diff options
Diffstat (limited to 'wrappers/python')
| -rw-r--r-- | wrappers/python/eduvpn_common/loader.py | 3 | ||||
| -rw-r--r-- | wrappers/python/eduvpn_common/main.py | 56 | ||||
| -rw-r--r-- | wrappers/python/eduvpn_common/types.py | 7 |
3 files changed, 54 insertions, 12 deletions
diff --git a/wrappers/python/eduvpn_common/loader.py b/wrappers/python/eduvpn_common/loader.py index 961b569..1a172af 100644 --- a/wrappers/python/eduvpn_common/loader.py +++ b/wrappers/python/eduvpn_common/loader.py @@ -4,7 +4,7 @@ from collections import defaultdict from ctypes import CDLL, c_char_p, c_int, c_void_p, cdll from eduvpn_common import __version__ -from eduvpn_common.types import BoolError, DataError, ReadRxBytes, VPNStateChange +from eduvpn_common.types import BoolError, DataError, ReadRxBytes, TokenGetter, TokenSetter, VPNStateChange def load_lib() -> CDLL: @@ -88,6 +88,7 @@ def initialize_functions(lib: CDLL) -> None: c_int, ], c_void_p lib.RenewSession.argtypes, lib.RenewSession.restype = [c_int], c_void_p + lib.SetTokenHandler.argtypes, lib.SetTokenHandler.restype = [TokenGetter, TokenSetter], c_void_p lib.Cleanup.argtypes, lib.Cleanup.restype = [c_int], c_void_p lib.SetProfileID.argtypes, lib.SetProfileID.restype = [c_char_p], c_void_p lib.CookieNew.argtypes, lib.CookieNew.restype = [], c_int diff --git a/wrappers/python/eduvpn_common/main.py b/wrappers/python/eduvpn_common/main.py index b10e641..5d08ba9 100644 --- a/wrappers/python/eduvpn_common/main.py +++ b/wrappers/python/eduvpn_common/main.py @@ -1,8 +1,9 @@ +import ctypes from enum import IntEnum from typing import Any, Callable, Iterator, Optional from eduvpn_common.loader import initialize_functions, load_lib -from eduvpn_common.types import ReadRxBytes, VPNStateChange, decode_res, encode_args +from eduvpn_common.types import ReadRxBytes, TokenGetter, TokenSetter, VPNStateChange, decode_res, encode_args class WrappedError(Exception): @@ -56,6 +57,9 @@ class EduVPN(object): self.version = version self.config_directory = config_directory self.jar = Jar(lambda x: self.go_function(self.lib.CookieCancel, x)) + self.callback = None + self.token_setter = None + self.token_getter = None # Load the library self.lib = load_lib() @@ -88,8 +92,8 @@ class EduVPN(object): This removes the object from internal bookkeeping and saves the configuration """ self.go_function(self.lib.Deregister) - global callback_object - callback_object = None + global global_object + global_object = None def register(self, handler: Optional[Callable] = None, debug: bool = False) -> None: """Register the Go shared library. @@ -99,10 +103,11 @@ class EduVPN(object): :param debug: bool: (Default value = False): Whether or not we want to enable debug logging """ - global callback_object - if callback_object is not None: + global global_object + if global_object is not None: raise Exception("Already registered") - callback_object = handler + self.callback = handler + global_object = self register_err = self.go_function( self.lib.Register, self.name, @@ -244,6 +249,14 @@ class EduVPN(object): if location_err: forwardError(location_err) + def set_token_handler(self, getter: Callable, setter: Callable) -> None: + self.token_setter = setter + self.token_getter = getter + handler_err = self.go_function(self.lib.SetTokenHandler, token_getter, token_setter) + + if handler_err: + forwardError(handler_err) + def cookie_reply(self, cookie: int, data: str) -> None: """Reply with the given cookie and data""" cookie_err = self.go_function(self.lib.CookieReply, cookie, data) @@ -289,8 +302,30 @@ class EduVPN(object): self.jar.cancel() -callback_object: Optional[Callable] = None +global_object: Optional[EduVPN] = None +@TokenSetter +def token_setter(server: ctypes.c_char_p, tokens: ctypes.c_char_p): + global global_object + if global_object is None: + return + if global_object.token_setter is None: + return 0 + global_object.token_setter(server.decode(), tokens.decode()) + +@TokenGetter +def token_getter(server: ctypes.c_char_p, buf: ctypes.c_char_p, size: ctypes.c_size_t): + global global_object + if global_object is None: + return + if global_object.token_getter is None: + return + got = global_object.token_getter(server.decode()) + if got is None: + return + + outbuf = ctypes.cast(buf, ctypes.POINTER(ctypes.c_char * size)) + outbuf.contents.value = got.encode("utf-8") @VPNStateChange def state_callback(old_state: int, new_state: int, data: str) -> int: @@ -302,9 +337,12 @@ def state_callback(old_state: int, new_state: int, data: str) -> int: :meta private: """ - if callback_object is None: + global global_object + if global_object is None: + return 0 + if global_object.callback is None: return 0 - handled = callback_object(old_state, new_state, data.decode("utf-8")) + handled = global_object.callback(old_state, new_state, data.decode("utf-8")) if handled: return 1 return 0 diff --git a/wrappers/python/eduvpn_common/types.py b/wrappers/python/eduvpn_common/types.py index 1eba468..f83e710 100644 --- a/wrappers/python/eduvpn_common/types.py +++ b/wrappers/python/eduvpn_common/types.py @@ -1,10 +1,13 @@ from ctypes import ( CDLL, CFUNCTYPE, + POINTER, Structure, + c_char, c_char_p, c_int, c_ulonglong, + c_size_t, c_void_p, cast, ) @@ -32,8 +35,8 @@ class BoolError(Structure): # The type for a Go state change callback VPNStateChange = CFUNCTYPE(c_int, c_int, c_int, c_char_p) ReadRxBytes = CFUNCTYPE(c_ulonglong) -UpdateToken = CFUNCTYPE(None, c_char_p, c_void_p, c_void_p) - +TokenGetter = CFUNCTYPE(c_void_p, c_char_p, POINTER(c_char), c_size_t) +TokenSetter = CFUNCTYPE(c_void_p, c_char_p, c_char_p) def encode_args(args: List[Any], types: List[Any]) -> Iterator[Any]: """Encode the arguments ready to be used by the Go library |
