Skip to content
This repository has been archived by the owner on Nov 29, 2024. It is now read-only.

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
jwijenbergh committed Nov 13, 2023
1 parent 70fd0c5 commit 5f5e90c
Show file tree
Hide file tree
Showing 10 changed files with 272 additions and 631 deletions.
719 changes: 138 additions & 581 deletions client/client.go

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions cmd/cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ func printConfig(url string, srvType srvtypes.Type) {
fmt.Fprintf(os.Stderr, "failed getting a config: %v\n", err)
return
}
fmt.Println(cfg.Protocol)

fmt.Println("Obtained config:", cfg.VPNConfig)
}
Expand Down
25 changes: 14 additions & 11 deletions exports/exports.go
Original file line number Diff line number Diff line change
Expand Up @@ -457,19 +457,21 @@ func CurrentServer() (*C.char, *C.char) {
//
//export ServerList
func ServerList() (*C.char, *C.char) {
state, stateErr := getVPNState()
_, stateErr := getVPNState()
if stateErr != nil {
return nil, getCError(stateErr)
}
list, err := state.ServerList()
if err != nil {
return nil, getCError(err)
}
ret, err := getReturnData(list)
if err != nil {
return nil, getCError(err)
}
return C.CString(ret), nil
panic("TODO")
return nil, nil
//list, err := state.ServerList()
//if err != nil {
// return nil, getCError(err)
//}
//ret, err := getReturnData(list)
//if err != nil {
// return nil, getCError(err)
//}
//return C.CString(ret), nil
}

// GetConfig gets a configuration for the server
Expand Down Expand Up @@ -839,7 +841,8 @@ func SetSupportWireguard(support C.int) *C.char {
if stateErr != nil {
return getCError(stateErr)
}
state.SupportsWireguard = support != 0
// TODO: Do not do any nested struct member here
state.Servers.WGSupport = support != 0
return nil
}

Expand Down
32 changes: 24 additions & 8 deletions internal/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (

type API struct {
// autht is the function to retrigger authorization
autht func(string) (string, error)
autht func(context.Context, string, bool) (string, error)
// authd is the function that triggers when authorization is done
authd func()
// oauth is the oauth object
Expand All @@ -39,9 +39,25 @@ func (a *API) BaseURL() string {
return a.baseWKURL
}

func (a *API) UpdateTokens(tok eduoauth.Token) error {

Check failure on line 42 in internal/api/api.go

View workflow job for this annotation

GitHub Actions / Lint go

undefined: eduoauth (typecheck)
if a.oauth == nil {
return errors.New("no oauth object defined")
}
a.oauth.UpdateTokens(tok)
return nil
}

func (a *API) Tokens() (*eduoauth.Token, error) {

Check failure on line 50 in internal/api/api.go

View workflow job for this annotation

GitHub Actions / Lint go

undefined: eduoauth (typecheck)
if a.oauth == nil {
return nil, errors.New("no oauth object defined")
}
t := a.oauth.Token()
return &t, nil
}

// NewAPI creates a new API object by creating an OAuth object
// TODO: make this mess shorter
func NewAPI(ctx context.Context, clientID string, baseWKURL string, baseWKAuthURL string, autht func(string) (string, error), authd func(), tokens *eduoauth.Token) (*API, error) {
func NewAPI(ctx context.Context, clientID string, baseWKURL string, baseWKAuthURL string, autht func(context.Context, string, bool) (string, error), authd func(), tokens *eduoauth.Token) (*API, error) {
ep, epauth, err := refreshEndpoints(ctx, baseWKURL, baseWKAuthURL)
if err != nil {
return nil, err
Expand Down Expand Up @@ -93,7 +109,8 @@ func (a *API) authorize(ctx context.Context) (err error) {
if err != nil {
return err
}
uri, err := a.autht(url)
// We expect an uri if custom redirect is non empty
uri, err := a.autht(ctx, url, a.oauth.CustomRedirect != "")
if err != nil {
return err
}
Expand All @@ -106,10 +123,8 @@ func (a *API) authorize(ctx context.Context) (err error) {
}

func (a *API) authorized(ctx context.Context, method string, endpoint string, opts *httpw.OptionalParams) (http.Header, []byte, error) {
u, err := httpw.JoinURLPath(a.apiURL, endpoint)
if err != nil {
return nil, nil, err
}
u := a.apiURL + endpoint
fmt.Println("GOT API URL", u)

// TODO: Cache HTTP client?
httpC := httpw.NewClient(a.oauth.NewHTTPClient())
Expand Down Expand Up @@ -204,10 +219,11 @@ func (a *API) Connect(ctx context.Context, prof profiles.Profile, protos []proto
if pTCP && len(protos) > 1 {
continue
}
wgKey, err := wireguard.GenerateKey()
gk, err := wireguard.GenerateKey()
if err != nil {
return nil, err
}
wgKey = &gk
// Set the public key
pubkey := wgKey.PublicKey()
uv.Set("public_key", pubkey.String())
Expand Down
15 changes: 9 additions & 6 deletions internal/config/v2/v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package v2

import (
"encoding/json"
"fmt"
"errors"
"time"

Expand Down Expand Up @@ -54,18 +55,20 @@ func (v2 *V2) AddCustom(url string) *Server {
// Otherwise add to the list and return
v := Server{}
cst.List[url] = v
cst.LastChosenID = url
v2.Servers.Custom = cst
return &v
}

func (v2 *V2) GetCustom(url string) *Server {
func (v2 *V2) GetCustom(url string) (*Server, error) {
cst := v2.Servers.Custom
if len(cst.List) == 0 {
cst.List = make(map[string]Server)
return nil, fmt.Errorf("server list is empty, no custom server with url: '%s'", url)
}
// Otherwise add to the list and return
v := Server{}
cst.List[url] = v
return &v
if v, ok := cst.List[url]; ok {
return &v, nil
}
return nil, errors.New("custom server with url: '%s' does not exist")
}

type Joined struct {
Expand Down
48 changes: 35 additions & 13 deletions internal/server/base.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,40 @@
package server

import (
"os"
import (
"context"
"errors"
"os"

"github.com/eduvpn/eduvpn-common/internal/api"
"github.com/eduvpn/eduvpn-common/internal/api/profiles"
"github.com/eduvpn/eduvpn-common/types/protocol"
srvtypes "github.com/eduvpn/eduvpn-common/types/server"
"github.com/jwijenbergh/eduoauth-go"
)

type Base struct {
apiw *api.API
CachedInfo *profiles.Info
Profile *profiles.Profile
prID string
}

func (b *Base) ProfileID() string {
if b.Profile == nil {
return ""
func (b *Base) UpdateTokens(tok eduoauth.Token) error {
if b.apiw == nil {
return errors.New("no API object defined")
}
return b.Profile.ID
return b.apiw.UpdateTokens(tok)
}

func (b *Base) Tokens() (*srvtypes.Tokens, error) {
tok, err := b.apiw.Tokens()
if err != nil {
return nil, err
}
return &srvtypes.Tokens{
Access: tok.Access,
Refresh: tok.Refresh,
Expires: tok.ExpiredTimestamp.Unix(),
}, nil
}

var InvalidProfileErr = errors.New("invalid profile")
Expand Down Expand Up @@ -60,8 +75,6 @@ func (b *Base) findProfile(ctx context.Context, wgSupport bool) (*profiles.Profi
return nil, err
}

prID := b.ProfileID()

// No profiles available
if prfs.Len() == 0 {
return nil, errors.New("the server has no available profiles for your account")
Expand All @@ -85,7 +98,7 @@ func (b *Base) findProfile(ctx context.Context, wgSupport bool) (*profiles.Profi
chosenP = prfs.MustIndex(0)
default:
// Profile doesn't exist
v := prfs.Get(prID)
v := prfs.Get(b.prID)
if v == nil {
return nil, InvalidProfileErr
}
Expand All @@ -94,7 +107,7 @@ func (b *Base) findProfile(ctx context.Context, wgSupport bool) (*profiles.Profi
return &chosenP, nil
}

func (b *Base) Connect(ctx context.Context, wgSupport bool, pTCP bool) (*api.ConnectData, error) {
func (b *Base) Connect(ctx context.Context, wgSupport bool, pTCP bool) (*srvtypes.Configuration, error) {
a, err := b.API()
if err != nil {
return nil, err
Expand All @@ -105,7 +118,7 @@ func (b *Base) Connect(ctx context.Context, wgSupport bool, pTCP bool) (*api.Con
if err != nil {
return nil, err
}
b.Profile = chosenP
b.prID = chosenP.ID

protos := []protocol.Protocol{protocol.OpenVPN}
if wgSupport {
Expand All @@ -120,7 +133,16 @@ func (b *Base) Connect(ctx context.Context, wgSupport bool, pTCP bool) (*api.Con
}
}
// SAFETY: chosenP is guaranteed to be non-nil
return a.Connect(ctx, *chosenP, protos, pTCP)
apicfg, err := a.Connect(ctx, *chosenP, protos, pTCP)
if err != nil {
return nil, err
}
// TODO: Save connection
return &srvtypes.Configuration{
VPNConfig: apicfg.Configuration,
Protocol: apicfg.Protocol,
DefaultGateway: chosenP.DefaultGateway,
}, nil
}

func (b *Base) Disconnect(ctx context.Context) error {
Expand Down
36 changes: 33 additions & 3 deletions internal/server/custom.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package server

import (
"context"
"github.com/eduvpn/eduvpn-common/types/server"

"github.com/eduvpn/eduvpn-common/internal/api"
httpw "github.com/eduvpn/eduvpn-common/internal/http"
"github.com/eduvpn/eduvpn-common/types/server"
"github.com/jwijenbergh/eduoauth-go"
)

type CustomServer struct {
Expand Down Expand Up @@ -35,10 +37,38 @@ func (s *Servers) AddCustom(ctx context.Context, url string, na bool) (Server, e
}
}

cust := CustomServer{
Base: Base{
apiw: a,
},
}

s.config.AddCustom(id)

// Return the server with the API
return &CustomServer{
return &cust, nil
}

func (s *Servers) GetCustom(ctx context.Context, url string, tok eduoauth.Token) (Server, error) {
// Convert to an identifier
id, err := httpw.EnsureValidURL(url, true)
if err != nil {
return nil, err
}
// Get the server from the config
srv, err := s.config.GetCustom(id)
if err != nil {
return nil, err
}
a, err := api.NewAPI(ctx, s.clientID, id, id, s.authTrigger, s.authDone, &tok)
if err != nil {
return nil, err
}
cust := &CustomServer{
Base: Base{
apiw: a,
prID: srv.ProfileID,
},
}, nil
}
return cust, nil
}
4 changes: 4 additions & 0 deletions internal/server/secureinternet.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ func (si *SecureInternet) Type() server.Type {
func (s *Servers) AddSecure(ctx context.Context, disco *discovery.Discovery, orgID string, na bool) (*SecureInternet, error) {
dOrg, dsrv, err := disco.SecureHomeArgs(orgID)
if err != nil {
// We mark the organizations as expired because we got an error
// Note that in the docs it states that it only should happen when the Org ID doesn't exist
// However, this is nice as well because it also catches the error where the SecureInternetHome server is not found
disco.MarkOrganizationsExpired()
return nil, err
}

Expand Down
21 changes: 13 additions & 8 deletions internal/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,37 @@ package server
import (
"context"

"github.com/eduvpn/eduvpn-common/internal/api"
v2 "github.com/eduvpn/eduvpn-common/internal/config/v2"
"github.com/jwijenbergh/eduoauth-go"
srvtypes "github.com/eduvpn/eduvpn-common/types/server"
)

type Servers struct {
clientID string
authDone func()
authTrigger func(string) (string, error)
wgSupport bool
authTrigger func(context.Context, string, bool) (string, error)
WGSupport bool
config v2.V2
}

type Server interface {
GetBase() Base
UpdateTokens(tok eduoauth.Token) error
}

func NewServers(name string, autht func(string) (string, error), authd func(), wgSupport bool) *Servers {
return &Servers{
func NewServers(name string, autht func(context.Context, string, bool) (string, error), authd func(), wgSupport bool, cfg v2.V2) Servers {
return Servers{
clientID: name,
authDone: authd,
authTrigger: autht,
wgSupport: wgSupport,
WGSupport: wgSupport,
config: cfg,
}
}

func (s *Servers) Connect(ctx context.Context, srv Server, pTCP bool) (*api.ConnectData, error) {
func (s *Servers) Connect(ctx context.Context, srv Server, pTCP bool) (*srvtypes.Configuration, error) {
b := srv.GetBase()
return b.Connect(ctx, s.wgSupport, pTCP)
return b.Connect(ctx, s.WGSupport, pTCP)
}

func (s *Servers) Disconnect(ctx context.Context, srv Server) error {
Expand Down
2 changes: 1 addition & 1 deletion types/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ type Tokens struct {
// Refresh is the refresh token
Refresh string `json:"refresh_token"`
// Expires is the Unix timestamp when the token expires
Expires int64 `json:"expires_in"`
Expires int64 `json:"expires"`
}

// Server is the basic type for a server. This is the base for secure internet and institute access. Custom servers are equal to this type
Expand Down

0 comments on commit 5f5e90c

Please sign in to comment.