summaryrefslogtreecommitdiff
path: root/exports/exports.go
diff options
context:
space:
mode:
authorjwijenbergh <jeroenwijenbergh@protonmail.com>2023-04-13 15:25:42 +0200
committerJeroen Wijenbergh <46386452+jwijenbergh@users.noreply.github.com>2023-09-25 09:43:37 +0200
commitf6f4396a81ce662eb5fb50c4f9fef92ffaadb333 (patch)
tree3e6b1c3ecc049c1aa377c8ca813f00b96437d2f3 /exports/exports.go
parent5610dca6c5e391ee62874c4d6cb25072d9c3c1d9 (diff)
All: Implement a token handler
This implements a token handler for OAuth tokens. Clients can use the SetTokenHandler function in exports to set a token handler. It needs two arguments, a getter and a setter. The getter is a callback with three arguments: - The server to get the tokens for, in types.server.current as JSON - The output buffer - The output buffer maximum length The tokens should be written to the output buffer with maximum length. The type should be types.server.Tokens and be marshalled as JSON. If no tokens are available, leave the output buffer intact The token setter is a callback with two arguments: - The server for which to set the tokens for, in types.server.Current as JSON - The tokens, defined in types.server.Tokens as JSON Breaking changes: - No more tokens as arguments, was already deprecated in previous commits - Tokens are no longer returned in types.server.Configuration
Diffstat (limited to 'exports/exports.go')
-rw-r--r--exports/exports.go71
1 files changed, 71 insertions, 0 deletions
diff --git a/exports/exports.go b/exports/exports.go
index f33fedd..6fc7f33 100644
--- a/exports/exports.go
+++ b/exports/exports.go
@@ -9,6 +9,9 @@ typedef long long int (*ReadRxBytes)();
typedef int (*StateCB)(int oldstate, int newstate, void* data);
+typedef const char* (*TokenGetter)(const char* server, char* out, size_t len);
+typedef void (*TokenSetter)(const char* server, const char* tokens);
+
static long long int get_read_rx_bytes(ReadRxBytes read)
{
return read();
@@ -17,10 +20,19 @@ static int call_callback(StateCB callback, int oldstate, int newstate, void* dat
{
return callback(oldstate, newstate, data);
}
+static void call_token_getter(TokenGetter getter, const char* server, char* out, size_t len)
+{
+ getter(server, out, len);
+}
+static void call_token_setter(TokenSetter setter, const char* server, const char* tokens)
+{
+ setter(server, tokens);
+}
*/
import "C"
import (
+ "bytes"
"context"
"encoding/json"
"runtime/cgo"
@@ -29,6 +41,7 @@ import (
"github.com/go-errors/errors"
"github.com/eduvpn/eduvpn-common/client"
+ "github.com/eduvpn/eduvpn-common/internal/log"
"github.com/eduvpn/eduvpn-common/types/cookie"
srvtypes "github.com/eduvpn/eduvpn-common/types/server"
)
@@ -382,6 +395,64 @@ func getCookie(c C.uintptr_t) (*cookie.Cookie, error) {
return v, nil
}
+//export SetTokenHandler
+func SetTokenHandler(getter C.TokenGetter, setter C.TokenSetter) *C.char {
+ state, stateErr := getVPNState()
+ if stateErr != nil {
+ return getCError(stateErr)
+ }
+ state.TokenSetter = func(c srvtypes.Current, t srvtypes.Tokens) {
+ cJSON, err := getReturnData(c)
+ if err != nil {
+ log.Logger.Warningf("failed to get current server for setting tokens in exports: %v", err)
+ return
+ }
+ tJSON, err := getReturnData(t)
+ if err != nil {
+ log.Logger.Warningf("failed to get tokens for setting tokens in exports: %v", err)
+ return
+ }
+ c1 := C.CString(cJSON)
+ c2 := C.CString(tJSON)
+ C.call_token_setter(setter, c1, c2)
+ FreeString(c1)
+ FreeString(c2)
+ }
+
+ state.TokenGetter = func(c srvtypes.Current) *srvtypes.Tokens {
+ cJSON, err := getReturnData(c)
+ if err != nil {
+ log.Logger.Warningf("failed to get current server for getting tokens in exports: %v", err)
+ return nil
+ }
+ c1 := C.CString(cJSON)
+ // create an output buffer with size 2048
+ // In my testing tokens seem to be ~1033 bytes marshalled as JSON
+ d := make([]byte, 2048)
+
+ C.call_token_getter(getter, c1, (*C.char)(unsafe.Pointer(&d[0])), C.size_t(len(d)))
+ FreeString(c1)
+
+ // get null pointer index as unmarshalling wants it without
+ null := bytes.IndexByte(d, 0)
+ if null < 0 {
+ log.Logger.Warningf("output buffer is not NULL terminated")
+ return nil
+ }
+
+ var gotT srvtypes.Tokens
+ err = json.Unmarshal(d[:null], &gotT)
+ if err != nil {
+ log.Logger.Warningf("failed to get json data for getting tokens in exports: %v", err)
+ return nil
+ }
+ return &gotT
+ }
+
+
+ return nil
+}
+
//export CookieNew
func CookieNew() C.uintptr_t {
c := cookie.NewWithContext(context.Background())