summaryrefslogtreecommitdiff
path: root/wrappers/python/eduvpn_common
diff options
context:
space:
mode:
authorjwijenbergh <jeroenwijenbergh@protonmail.com>2023-04-12 22:57:59 +0200
committerJeroen Wijenbergh <46386452+jwijenbergh@users.noreply.github.com>2023-09-25 09:43:37 +0200
commit696befcc0e29dade5879dab2f33ea2d705be244b (patch)
tree0934fc739ba002eac7542993e36f1d05fd143078 /wrappers/python/eduvpn_common
parenta38e3e79f74e95051db7e14ae14ab817b68b725a (diff)
Wrappers Python: Update to newest API by implementing cookies
Diffstat (limited to 'wrappers/python/eduvpn_common')
-rw-r--r--wrappers/python/eduvpn_common/loader.py23
-rw-r--r--wrappers/python/eduvpn_common/main.py85
2 files changed, 63 insertions, 45 deletions
diff --git a/wrappers/python/eduvpn_common/loader.py b/wrappers/python/eduvpn_common/loader.py
index 36381b4..961b569 100644
--- a/wrappers/python/eduvpn_common/loader.py
+++ b/wrappers/python/eduvpn_common/loader.py
@@ -57,21 +57,22 @@ def initialize_functions(lib: CDLL) -> None:
# Exposed functions
# We have to use c_void_p instead of c_char_p to free it properly
# See https://stackoverflow.com/questions/13445568/python-ctypes-how-to-free-memory-getting-invalid-pointer-error
- lib.CancelOAuth.argtypes, lib.CancelOAuth.restype = [], c_void_p
lib.Deregister.argtypes, lib.Deregister.restype = [], None
lib.ExpiryTimes.argtypes, lib.ExpiryTimes.restype = [], DataError
lib.FreeString.argtypes, lib.FreeString.restype = [c_void_p], None
- lib.DiscoOrganizations.argtypes, lib.DiscoOrganizations.restype = [], DataError
- lib.DiscoServers.argtypes, lib.DiscoServers.restype = [], DataError
+ lib.DiscoOrganizations.argtypes, lib.DiscoOrganizations.restype = [c_int], DataError
+ lib.DiscoServers.argtypes, lib.DiscoServers.restype = [c_int], DataError
lib.GetConfig.argtypes, lib.GetConfig.restype = [
c_int,
- c_char_p,
c_int,
c_char_p,
+ c_int,
], DataError
lib.AddServer.argtypes, lib.AddServer.restype = [
c_int,
+ c_int,
c_char_p,
+ c_int,
], c_char_p
lib.CurrentServer.argtypes, lib.CurrentServer.restype = [], DataError
lib.RemoveServer.argtypes, lib.RemoveServer.restype = [
@@ -86,21 +87,23 @@ def initialize_functions(lib: CDLL) -> None:
VPNStateChange,
c_int,
], c_void_p
- lib.RenewSession.argtypes, lib.RenewSession.restype = [], c_void_p
- lib.Cleanup.argtypes, lib.Cleanup.restype = [
- c_char_p,
- ], c_void_p
+ lib.RenewSession.argtypes, lib.RenewSession.restype = [c_int], 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
+ lib.CookieReply.argtypes, lib.CookieReply.restype = [c_int, c_char_p], c_void_p
+ lib.CookieCancel.argtypes, lib.CookieCancel.restype = [c_int], c_void_p
+ lib.CookieDelete.argtypes, lib.CookieDelete.restype = [c_int], c_void_p
lib.SetSecureLocation.argtypes, lib.SetSecureLocation.restype = [
+ c_int,
c_char_p,
], c_void_p
- lib.SecureLocationList.argtypes, lib.SecureLocationList.restype = [], DataError
lib.SetSupportWireguard.argtypes, lib.SetSupportWireguard.restype = [
c_int,
], c_void_p
lib.StartFailover.argtypes, lib.StartFailover.restype = [
+ c_int,
c_char_p,
c_int,
ReadRxBytes,
], BoolError
- lib.CancelFailover.argtypes, lib.CancelFailover.restype = [], c_void_p
diff --git a/wrappers/python/eduvpn_common/main.py b/wrappers/python/eduvpn_common/main.py
index d8e35f9..6616192 100644
--- a/wrappers/python/eduvpn_common/main.py
+++ b/wrappers/python/eduvpn_common/main.py
@@ -2,8 +2,7 @@ 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, get_bool, get_data_error)
+from eduvpn_common.types import ReadRxBytes, VPNStateChange, decode_res, encode_args
class WrappedError(Exception):
@@ -24,6 +23,24 @@ class ServerType(IntEnum):
CUSTOM = 3
+class Jar(object):
+ """A cookie jar"""
+
+ def __init__(self, canceller):
+ self.cookies = []
+ self.canceller = canceller
+
+ def add(self, cookie):
+ self.cookies.append(cookie)
+
+ def delete(self, cookie):
+ self.cookies.remove(cookie)
+
+ def cancel(self):
+ for cookie in self.cookies:
+ self.canceller(cookie)
+
+
class EduVPN(object):
"""The main class used to communicate with the Go library.
It registers the client with the library and then calls the needed appropriate functions
@@ -38,14 +55,21 @@ class EduVPN(object):
self.name = name
self.version = version
self.config_directory = config_directory
+ self.jar = Jar(lambda x: self.go_function(self.lib.CookieCancel, x))
# Load the library
self.lib = load_lib()
initialize_functions(self.lib)
- def go_function(
- self, func: Any, *args: Iterator
- ) -> Any:
+ def go_cookie_function(self, func: Any, *args: Iterator) -> Any:
+ cookie = self.lib.CookieNew()
+ self.jar.add(cookie)
+ res = self.go_function(func, cookie, *args)
+ self.jar.delete(cookie)
+ self.lib.CookieDelete(cookie)
+ return res
+
+ def go_function(self, func: Any, *args: Iterator) -> Any:
"""Call an internal go function and properly forward the arguments.
Also handles decoding the result
@@ -59,13 +83,6 @@ class EduVPN(object):
res = func(*(args_gen))
return decode_res(func.restype)(self.lib, res)
- def cancel_oauth(self) -> None:
- """Cancel the OAuth process"""
- cancel_oauth_err = self.go_function(self.lib.CancelOAuth)
-
- if cancel_oauth_err:
- forwardError(cancel_oauth_err)
-
def deregister(self) -> None:
"""Deregister the Go shared library.
This removes the object from internal bookkeeping and saves the configuration
@@ -98,15 +115,16 @@ class EduVPN(object):
if register_err:
forwardError(register_err)
- def add_server(self, _type: ServerType, _id: str) -> None:
+ def add_server(self, _type: ServerType, _id: str, ni: bool = False) -> None:
"""Add a server
:param _type: ServerType: The type of server e.g. SERVER.INSTITUTE_ACCESS
:param _id: str: The identifier of the server, e.g. "https://vpn.example.com/"
+ :param ni: bool: Whether the server should be added non interactively, meaning no callbacks
:raises WrappedError: An error by the Go library
"""
- add_err = self.go_function(self.lib.AddServer, int(_type), _id)
+ add_err = self.go_cookie_function(self.lib.AddServer, int(_type), _id, ni)
if add_err:
forwardError(add_err)
@@ -123,19 +141,13 @@ class EduVPN(object):
forwardError(server_err)
return server
- def get_secure_locations(self) -> Optional[str]:
- locs, locs_err = self.go_function(self.lib.SecureLocationList)
- if locs_err:
- forwardError(locs_err)
- return locs
-
def get_disco_organizations(self) -> Optional[str]:
- orgs, _ = self.go_function(self.lib.DiscoOrganizations)
+ orgs, _ = self.go_cookie_function(self.lib.DiscoOrganizations)
# TODO: Log error
return orgs
def get_disco_servers(self) -> Optional[str]:
- servers, _ = self.go_function(self.lib.DiscoServers)
+ servers, _ = self.go_cookie_function(self.lib.DiscoServers)
# TODO: Log error
return servers
@@ -159,7 +171,7 @@ class EduVPN(object):
forwardError(remove_err)
def get_config(
- self, _type: ServerType, identifier: str, prefer_tcp: bool = False, tokens: str = "{}"
+ self, _type: ServerType, identifier: str, prefer_tcp: bool = False
) -> Optional[str]:
"""Get an OpenVPN/WireGuard configuration from the server
@@ -178,12 +190,11 @@ class EduVPN(object):
# Because it could be the case that a profile callback is started, store a threading event
# In the constructor, we have defined a wait event for Ask_Profile, this waits for this event to be set
# The event is set in self.set_profile
- config, config_err = self.go_function(
+ config, config_err = self.go_cookie_function(
self.lib.GetConfig,
- _type,
+ int(_type),
identifier,
prefer_tcp,
- tokens,
)
if config_err:
@@ -191,14 +202,14 @@ class EduVPN(object):
return config
- def cleanup(self, tokens: str = "") -> None:
+ def cleanup(self) -> None:
"""Cleanup the vpn connection
:param tokens: str (Default value = ""): The OAuth tokens if available
:raises WrappedError: An error by the Go library
"""
- cleanup_err = self.go_function(self.lib.Cleanup, tokens)
+ cleanup_err = self.go_cookie_function(self.lib.Cleanup)
if cleanup_err:
forwardError(cleanup_err)
@@ -231,19 +242,25 @@ class EduVPN(object):
:raises WrappedError: An error by the Go library
"""
# Set the location by country code
- location_err = self.go_function(self.lib.SetSecureLocation, country_code)
+ location_err = self.go_cookie_function(self.lib.SetSecureLocation, country_code)
# If there is a location event, set it so that the wait callback finishes
# And so that the Go code can move to the next state
if location_err:
forwardError(location_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)
+ if cookie_err:
+ forwardError(cookie_err)
+
def renew_session(self) -> None:
"""Renew the session. This invalidates the tokens and runs the necessary callbacks to log back in
:raises WrappedError: An error by the Go library
"""
- renew_err = self.go_function(self.lib.RenewSession)
+ renew_err = self.go_cookie_function(self.lib.RenewSession)
if renew_err:
forwardError(renew_err)
@@ -263,7 +280,7 @@ class EduVPN(object):
def start_failover(
self, gateway: str, wg_mtu: int, readrxbytes: ReadRxBytes
) -> bool:
- dropped, dropped_err = self.go_function(
+ dropped, dropped_err = self.go_cookie_function(
self.lib.StartFailover,
gateway,
wg_mtu,
@@ -273,10 +290,8 @@ class EduVPN(object):
forwardError(dropped_err)
return dropped
- def cancel_failover(self):
- cancel_err = self.go_function(self.lib.CancelFailover)
- if cancel_err:
- forwardError(cancel_err)
+ def cancel(self):
+ self.jar.cancel()
callback_object: Optional[Callable] = None