summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--exports/exports.go10
-rw-r--r--src/server.go5
-rw-r--r--src/state.go41
-rw-r--r--src/wireguard.go23
-rw-r--r--wrappers/python/eduvpncommon/__init__.py1
-rw-r--r--wrappers/python/eduvpncommon/main.py49
-rw-r--r--wrappers/python/main.py21
7 files changed, 127 insertions, 23 deletions
diff --git a/exports/exports.go b/exports/exports.go
index 8236977..4e998bf 100644
--- a/exports/exports.go
+++ b/exports/exports.go
@@ -34,7 +34,8 @@ func StateCallback(old_state string, new_state string, data string) {
//export Register
func Register(name *C.char, config_directory *C.char, stateCallback C.PythonCB) *C.char {
P_StateCallback = stateCallback
- registerErr := eduvpn.Register(eduvpn.GetVPNState(), C.GoString(name), C.GoString(config_directory), StateCallback)
+ state := eduvpn.GetVPNState()
+ registerErr := state.Register(C.GoString(name), C.GoString(config_directory), StateCallback)
return C.CString(ErrorToString(registerErr))
}
@@ -46,6 +47,13 @@ func ErrorToString(error error) string {
return error.Error()
}
+//export Connect
+func Connect(url *C.char) (*C.char, *C.char) {
+ state := eduvpn.GetVPNState()
+ config, configErr := state.Connect(C.GoString(url))
+ return C.CString(config), C.CString(ErrorToString(configErr))
+}
+
//export GetOrganizationsList
func GetOrganizationsList() (*C.char, *C.char) {
state := eduvpn.GetVPNState()
diff --git a/src/server.go b/src/server.go
index 627843f..0ef3965 100644
--- a/src/server.go
+++ b/src/server.go
@@ -34,6 +34,11 @@ func (server *Server) Initialize(url string) error {
return nil
}
+// FIXME: Check validity of tokens
+func (server *Server) IsAuthenticated() bool {
+ return server.OAuth != nil
+}
+
func (server *Server) GetEndpoints() error {
url := server.BaseURL + "/.well-known/vpn-user-portal"
body, bodyErr := HTTPGet(url)
diff --git a/src/state.go b/src/state.go
index ea268ec..cd8fa19 100644
--- a/src/state.go
+++ b/src/state.go
@@ -2,8 +2,9 @@ package eduvpn
type VPNState struct {
// Info passed by the client
- ConfigDirectory string `json:"-"`
- Name string `json:"-"`
+ ConfigDirectory string `json:"-"`
+ Name string `json:"-"`
+ StateCallback func(string, string, string) `json:"-"`
// The chosen server
Server *Server `json:"server"`
@@ -12,11 +13,12 @@ type VPNState struct {
DiscoList *DiscoList `json:"disco"`
}
-func Register(state *VPNState, name string, directory string, stateCallback func(string, string, string)) error {
+func (state *VPNState) Register(name string, directory string, stateCallback func(string, string, string)) error {
state.Name = name
state.ConfigDirectory = directory
+ state.StateCallback = stateCallback
- stateCallback("START", "REGISTERED", "app registered")
+ state.StateCallback("Start", "Registered", "app registered")
// Try to load the previous configuration
if state.LoadConfig() != nil {
@@ -26,6 +28,37 @@ func Register(state *VPNState, name string, directory string, stateCallback func
return nil
}
+func (state *VPNState) Connect(url string) (string, error) {
+ if state.Server == nil {
+ state.Server = &Server{}
+ }
+ initializeErr := state.Server.Initialize(url)
+
+ if initializeErr != nil {
+ return "", initializeErr
+ }
+
+ if !state.Server.IsAuthenticated() {
+ authURL, authInitializeErr := state.InitializeOAuth()
+
+ if authInitializeErr != nil {
+ return "", authInitializeErr
+ }
+
+ state.StateCallback("Registered", "OAuthInitialized", authURL)
+ oauthErr := state.FinishOAuth()
+
+ if oauthErr != nil {
+ return "", oauthErr
+ }
+
+ state.StateCallback("OAuthInitialized", "OAuthFinished", "finished oauth")
+ state.WriteConfig()
+ }
+
+ return state.WireguardGetConfig()
+}
+
var VPNStateInstance *VPNState
func GetVPNState() *VPNState {
diff --git a/src/wireguard.go b/src/wireguard.go
index 9441c51..0d5967c 100644
--- a/src/wireguard.go
+++ b/src/wireguard.go
@@ -6,13 +6,13 @@ import (
"regexp"
)
-func WireguardGenerateKey() (wgtypes.Key, error) {
+func wireguardGenerateKey() (wgtypes.Key, error) {
key, error := wgtypes.GeneratePrivateKey()
return key, error
}
// FIXME: Instead of doing a regex replace, decide if we should use a parser
-func WireguardConfigAddKey(config string, key wgtypes.Key) string {
+func wireguardConfigAddKey(config string, key wgtypes.Key) string {
interface_section := "[Interface]"
interface_section_escaped := regexp.QuoteMeta(interface_section)
@@ -24,3 +24,22 @@ func WireguardConfigAddKey(config string, key wgtypes.Key) string {
to_replace := fmt.Sprintf("%s\nPrivateKey = %s", interface_section, key.String())
return interface_re.ReplaceAllString(config, to_replace)
}
+
+func (eduvpn *VPNState) WireguardGetConfig() (string, error) {
+ wireguardKey, wireguardErr := wireguardGenerateKey()
+
+ if wireguardErr != nil {
+ return "", wireguardErr
+ }
+
+ wireguardPublicKey := wireguardKey.PublicKey().String()
+ configWireguard, configErr := eduvpn.APIConnectWireguard(wireguardPublicKey)
+
+ if configErr != nil {
+ return "", configErr
+ }
+
+ configWireguardKey := wireguardConfigAddKey(configWireguard, wireguardKey)
+
+ return configWireguardKey, nil
+}
diff --git a/wrappers/python/eduvpncommon/__init__.py b/wrappers/python/eduvpncommon/__init__.py
index 073af39..faa311d 100644
--- a/wrappers/python/eduvpncommon/__init__.py
+++ b/wrappers/python/eduvpncommon/__init__.py
@@ -33,6 +33,7 @@ class DataError(Structure):
VPNStateChange = CFUNCTYPE(None, c_char_p, c_char_p, c_char_p)
# Exposed functions
+lib.Connect.argtypes, lib.Connect.restype = [c_char_p], DataError
lib.Register.argtypes, lib.Register.restype = [c_char_p, c_char_p, VPNStateChange], None
lib.GetOrganizationsList.argtypes, lib.GetOrganizationsList.restype = [], DataError
lib.GetServersList.argtypes, lib.GetServersList.restype = [], DataError
diff --git a/wrappers/python/eduvpncommon/main.py b/wrappers/python/eduvpncommon/main.py
index 9a4931f..9e1f25e 100644
--- a/wrappers/python/eduvpncommon/main.py
+++ b/wrappers/python/eduvpncommon/main.py
@@ -1,12 +1,13 @@
from . import lib, VPNStateChange, GetDataError, GetPtrString
from ctypes import *
from enum import Enum
-import functools
+
class StateType(Enum):
Enter = 1
Leave = 2
+
# Registers the python app with the Go code
# name: The name of the app to be registered
# url: The url of the server to connect to, FIXME: To be removed
@@ -19,19 +20,46 @@ def Register(name, config_directory, state_callback):
return err_string
+def GetDiscoServers():
+ servers, serversErr = GetDataError(lib.GetServersList())
+ organizations, organizationsErr = GetDataError(lib.GetOrganizationsList())
+ return servers, serversErr, organizations, organizationsErr
+
+
+def Connect(url):
+ url_bytes = url.encode("utf-8")
+ data_error = lib.Connect(url_bytes)
+ return GetDataError(data_error)
+
+
+# This has to be global as otherwise the callback is not alive
+callback_function = None
+
+
+def register_callback(eduvpn):
+ global callback_function
+ callback_function = VPNStateChange(
+ lambda old_state, new_state, data: eduvpn.callback(
+ old_state.decode(), new_state.decode(), data.decode()
+ )
+ )
+
+
class EduVPN(object):
def __init__(self, name, config_directory):
self.event_handler = EventHandler()
self.name = name
self.config_directory = config_directory
+ register_callback(self)
def register(self) -> bool:
- closure = VPNStateChange(
- lambda old_state, new_state, data: self.callback(
- old_state.decode(), new_state.decode(), data.decode()
- )
- )
- return Register(self.name, self.config_directory, closure) == ""
+ return Register(self.name, self.config_directory, callback_function) == ""
+
+ def get_disco(self):
+ return GetDiscoServers()
+
+ def connect(self, url):
+ return Connect(url)
@property
def event(self):
@@ -51,6 +79,7 @@ class EventHandler(object):
self.handlers[(state, state_type)] = []
self.handlers[(state, state_type)].append(func)
return func
+
return wrapped_f
def run_state(self, state, state_type, data):
@@ -64,9 +93,3 @@ class EventHandler(object):
return
self.run_state(old_state, StateType.Leave, data)
self.run_state(new_state, StateType.Enter, data)
-
-
-def GetDiscoServers():
- servers, serversErr = GetDataError(lib.GetServersList())
- organizations, organizationsErr = GetDataError(lib.GetOrganizationsList())
- return servers, serversErr, organizations, organizationsErr
diff --git a/wrappers/python/main.py b/wrappers/python/main.py
index a248b71..6bd7d86 100644
--- a/wrappers/python/main.py
+++ b/wrappers/python/main.py
@@ -1,12 +1,27 @@
import eduvpncommon.main as eduvpn
+import webbrowser
_eduvpn = eduvpn.EduVPN("org.eduvpn.app.linux", "configs")
-@_eduvpn.event.on("REGISTERED", eduvpn.StateType.Enter)
-def registered(data):
- print(f"REGISTERED PYTHON WITH DATA {data}")
+@_eduvpn.event.on("OAuthInitialized", eduvpn.StateType.Enter)
+def oauth_initialized(url):
+ print(f"Got OAUTH url {url}")
+ webbrowser.open(url)
+
+
+@_eduvpn.event.on("OAuthFinished", eduvpn.StateType.Enter)
+def oauth_finished(data):
+ print(f"Oauth finished {data}")
_eduvpn.register()
+print(_eduvpn.get_disco())
+
+config, error = _eduvpn.connect("https://eduvpn.jwijenbergh.com")
+#
+if error != "":
+ print("Got connect error", error)
+
+print(config)