diff options
| author | Jeroen Wijenbergh <jeroen.wijenbergh@geant.org> | 2025-05-06 10:31:57 +0200 |
|---|---|---|
| committer | Jeroen Wijenbergh <jeroen.wijenbergh@geant.org> | 2025-05-06 13:25:48 +0200 |
| commit | 6b939462fb1064abd42e8cb8316700ec844172ea (patch) | |
| tree | b572daecdf0f25e3beec9883a8b7bb2522628212 | |
| parent | 347b20fc91505584bc9efbeca89590a411b95e79 (diff) | |
All: Remove ProxyGuard integration
This should be done in WireGuard-go or in case of a linux a small daemon
| -rw-r--r-- | docs/md/apidocs.md | 73 | ||||
| -rw-r--r-- | exports/exports.go | 120 | ||||
| -rw-r--r-- | exports/exports.h | 5 | ||||
| -rw-r--r-- | internal/api/api.go | 5 | ||||
| -rw-r--r-- | internal/api/api_test.go | 20 | ||||
| -rw-r--r-- | internal/server/server.go | 9 | ||||
| -rw-r--r-- | internal/wireguard/ini/ini.go | 42 | ||||
| -rw-r--r-- | internal/wireguard/ini/ini_test.go | 67 | ||||
| -rw-r--r-- | internal/wireguard/wireguard.go | 97 | ||||
| -rw-r--r-- | internal/wireguard/wireguard_test.go | 25 | ||||
| -rw-r--r-- | proxy/proxy.go | 84 | ||||
| -rw-r--r-- | types/server/server.go | 15 | ||||
| -rw-r--r-- | wrappers/python/eduvpn_common/loader.py | 31 | ||||
| -rw-r--r-- | wrappers/python/eduvpn_common/main.py | 44 | ||||
| -rw-r--r-- | wrappers/python/eduvpn_common/types.py | 1 |
15 files changed, 23 insertions, 615 deletions
diff --git a/docs/md/apidocs.md b/docs/md/apidocs.md index 9fb7808..71713e6 100644 --- a/docs/md/apidocs.md +++ b/docs/md/apidocs.md @@ -110,8 +110,7 @@ Signature: func Cleanup(c C.uintptr_t) *C.char ``` -Cleanup sends a `/disconnect` to cleanup the connection. Additionally, -if ProxyGuard is active it cancels the running process +Cleanup sends a `/disconnect` to cleanup the connection. This MUST be called when disconnecting, see [the eduVPN docs](https://docs.eduvpn.org/server/v3/api.html#application-flow). `c` is @@ -483,8 +482,7 @@ Signature: func GetConfig(c C.uintptr_t, _type C.int, id *C.char, pTCP C.int, startup C.int) (*C.char, *C.char) ``` -GetConfig gets a configuration for the server. It returns additional -information in case WireGuard over Proxyguard is used (see the last example) +GetConfig gets a configuration for the server. `c` is the cookie that is used for cancellation. Create a cookie first with CookieNew, this same cookie is also used for replying to state transitions @@ -594,16 +592,6 @@ Example Output (2=WireGuard): "should_failover": true, <- whether or not the failover procedure should happen } -Example Output (3=WireGuard + Proxyguard): - - { - "config":"[Interface]\nMTU = ...\nAddress = ...\nDNS = ...\nPrivateKey = ...\n[Peer]\nPublicKey = ...\nAllowedIPs = ...\nEndpoint = 127.0.0.1:x\n", - "protocol":3, - "default_gateway":true, - "should_failover":true, - "proxy":{"source_port":38683,"listen":"127.0.0.1:59812","peer":"https://..."} - } - ## InState Signature: @@ -617,63 +605,6 @@ Example Input: ```InState(5)``` Example Output: ```1, null``` -## NewProxyguard -Signature: - -```go -func NewProxyguard(c C.uintptr_t, lp C.int, tcpsp C.int, peer *C.char, proxySetup C.ProxySetup) (C.uintptr_t, *C.char) -``` - -NewProxyguard creates the 'proxyguard' procedure in eduvpn-common. If the -proxy cannot be created it returns an error. - -This function proxies WireGuard UDP connections over HTTP: [ProxyGuard on -Codeberg](https://codeberg.org/eduvpn/proxyguard). - -These input variables can be gotten from the configuration that is retrieved -using the `proxy` JSON key - - - `c` is the cookie. Note that if you cancel/delete the cookie, - ProxyGuard gets cleaned up. Common automatically cleans up ProxyGuard - when `Cleanup` is called, but it is good to cleanup yourself too. - - `lp` is the `port` of the local udp ProxyGuard connection, this is what - is set to the WireGuard endpoint - - `tcpsp` is the TCP source port. Pass 0 if you do not route based on - source port, so far only the Linux client has to pass non-zero. - - `peer` is the `ip:port` of the remote server - - `proxySetup` is a callback which is called when the socket is setting - up, this can be used for configuring routing in the client. It takes - two arguments: the file descriptor (integer) and a JSON list of IPs the - client connects to - -Example Input: ```NewProxyguard(myCookie, 1337, 0, "5.5.5.5:51820", -proxySetupCB)``` - -Example Output: ```null``` - -## ProxyguardPeerIPs -Signature: - -```go -func ProxyguardPeerIPs(proxyH C.uintptr_t) (*C.char, *C.char) -``` - -ProxyguardPeerIPs gets the Peer IPs configured by ProxyGuard Example Input: -```ProxyguardPeerIPs(handle)``` - -Example Output: ```["1.1.1.1"], null``` - -## ProxyguardTunnel -Signature: - -```go -func ProxyguardTunnel(c C.uintptr_t, proxyH C.uintptr_t, wglisten C.int) *C.char -``` - -ProxyguardTunnel starts the tunneling for ProxyGuard `c` is the cookie -`proxyH` is the proxy handle `wglisten` is the port WireGuard is listening -on - ## Register Signature: diff --git a/exports/exports.go b/exports/exports.go index 3c9c59a..448883b 100644 --- a/exports/exports.go +++ b/exports/exports.go @@ -29,7 +29,6 @@ import ( "codeberg.org/eduVPN/eduvpn-common/client" "codeberg.org/eduVPN/eduvpn-common/i18nerr" "codeberg.org/eduVPN/eduvpn-common/internal/log" - "codeberg.org/eduVPN/eduvpn-common/proxy" "codeberg.org/eduVPN/eduvpn-common/types/cookie" errtypes "codeberg.org/eduVPN/eduvpn-common/types/error" srvtypes "codeberg.org/eduVPN/eduvpn-common/types/server" @@ -452,7 +451,7 @@ func ServerList() (*C.char, *C.char) { return C.CString(ret), nil } -// GetConfig gets a configuration for the server. It returns additional information in case WireGuard over Proxyguard is used (see the last example) +// GetConfig gets a configuration for the server. // // `c` is the cookie that is used for cancellation. Create a cookie first with CookieNew, this same cookie is also used for replying to state transitions // @@ -538,16 +537,6 @@ func ServerList() (*C.char, *C.char) { // "should_failover": true, <- whether or not the failover procedure should happen // } // -// Example Output (3=WireGuard + Proxyguard): -// -// { -// "config":"[Interface]\nMTU = ...\nAddress = ...\nDNS = ...\nPrivateKey = ...\n[Peer]\nPublicKey = ...\nAllowedIPs = ...\nEndpoint = 127.0.0.1:x\n", -// "protocol":3, -// "default_gateway":true, -// "should_failover":true, -// "proxy":{"source_port":38683,"listen":"127.0.0.1:59812","peer":"https://..."} -// } -// //export GetConfig func GetConfig(c C.uintptr_t, _type C.int, id *C.char, pTCP C.int, startup C.int) (*C.char, *C.char) { state, stateErr := getVPNState() @@ -769,7 +758,6 @@ func DiscoOrganizations(c C.uintptr_t, search *C.char) (*C.char, *C.char) { } // Cleanup sends a `/disconnect` to cleanup the connection. -// Additionally, if ProxyGuard is active it cancels the running process // // This MUST be called when disconnecting, see [the eduVPN docs](https://docs.eduvpn.org/server/v3/api.html#application-flow). // `c` is the Cookie that needs to be passed. Create a new Cookie using `CookieNew`. @@ -877,112 +865,6 @@ func StartFailover(c C.uintptr_t, gateway *C.char, mtu C.int, readRxBytes C.Read return droppedC, nil } -// NewProxyguard creates the 'proxyguard' procedure in eduvpn-common. -// If the proxy cannot be created it returns an error. -// -// This function proxies WireGuard UDP connections over HTTP: [ProxyGuard on Codeberg](https://codeberg.org/eduvpn/proxyguard). -// -// These input variables can be gotten from the configuration that is retrieved using the `proxy` JSON key -// -// - `c` is the cookie. Note that if you cancel/delete the cookie, ProxyGuard gets cleaned up. Common automatically cleans up ProxyGuard when `Cleanup` is called, but it is good to cleanup yourself too. -// - `lp` is the `port` of the local udp ProxyGuard connection, this is what is set to the WireGuard endpoint -// - `tcpsp` is the TCP source port. Pass 0 if you do not route based on source port, so far only the Linux client has to pass non-zero. -// - `peer` is the `ip:port` of the remote server -// - `proxySetup` is a callback which is called when the socket is setting up, this can be used for configuring routing in the client. It takes two arguments: the file descriptor (integer) and a JSON list of IPs the client connects to -// -// Example Input: ```NewProxyguard(myCookie, 1337, 0, "5.5.5.5:51820", proxySetupCB)``` -// -// Example Output: ```null``` -// -//export NewProxyguard -func NewProxyguard(c C.uintptr_t, lp C.int, tcpsp C.int, peer *C.char, proxySetup C.ProxySetup) (C.uintptr_t, *C.char) { - ck, err := getCookie(c) - if err != nil { - return 0, getCError(err) - } - proxy, proxyErr := proxy.NewProxyguard(ck.Context(), int(lp), int(tcpsp), C.GoString(peer), func(fd int) { - if proxySetup == nil { - return - } - C.call_proxy_setup(proxySetup, C.int(fd)) - }) - if proxyErr != nil { - return 0, getCError(proxyErr) - } - return C.uintptr_t(cgo.NewHandle(proxy)), nil -} - -// ProxyguardRestart restarts ProxyGuard, call this when a network change happens -// -// Example Input: ```ProxyguardRestart(proxyHandle)``` -// -// Example Output: ```"failed restarting ProxyGuard"``` -// -//export ProxyguardRestart -func ProxyguardRestart(proxyH C.uintptr_t) *C.char { - pr, err := getProxy(proxyH) - if err != nil { - return getCError(err) - } - pr.Restart() - return nil -} - -func getProxy(proxyH C.uintptr_t) (*proxy.Proxy, error) { - h := cgo.Handle(proxyH) - v, ok := h.Value().(*proxy.Proxy) - if !ok { - return nil, i18nerr.NewInternal("value is not a proxyguard wrapper") - } - return v, nil -} - -// ProxyguardTunnel starts the tunneling for ProxyGuard -// `c` is the cookie -// `proxyH` is the proxy handle -// `wglisten` is the port WireGuard is listening on -// -//export ProxyguardTunnel -func ProxyguardTunnel(c C.uintptr_t, proxyH C.uintptr_t, wglisten C.int) *C.char { - ck, err := getCookie(c) - if err != nil { - return getCError(err) - } - pr, err := getProxy(proxyH) - if err != nil { - return getCError(err) - } - tunnelErr := pr.Tunnel(ck.Context(), int(wglisten)) - - // after tunneling is done, the handle should be deleted - cgo.Handle(proxyH).Delete() - return getCError(tunnelErr) -} - -// ProxyguardPeerIPs gets the Peer IPs configured by ProxyGuard -// Example Input: ```ProxyguardPeerIPs(handle)``` -// -// Example Output: ```["1.1.1.1"], null``` -// -//export ProxyguardPeerIPs -func ProxyguardPeerIPs(proxyH C.uintptr_t) (*C.char, *C.char) { - pr, err := getProxy(proxyH) - if err != nil { - return nil, getCError(err) - } - pips := pr.PeerIPS - - b, err := json.Marshal(pips) - if err != nil { - return nil, getCError(i18nerr.WrapInternal(err, "failed converting Peer IPs to JSON")) - } - ret, err := getReturnData(string(b)) - if err != nil { - return nil, getCError(err) - } - return C.CString(ret), nil -} - // SetState sets the state of the state machine. // // Note: this transitions the FSM into the new state without passing any data to it. diff --git a/exports/exports.h b/exports/exports.h index 9ec39e4..13630a6 100644 --- a/exports/exports.h +++ b/exports/exports.h @@ -11,7 +11,6 @@ typedef int (*StateCB)(int oldstate, int newstate, void* data); typedef void (*RefreshList)(); typedef void (*TokenGetter)(const char* server_id, int server_type, char* out, size_t len); typedef void (*TokenSetter)(const char* server_id, int server_type, const char* tokens); -typedef void (*ProxySetup)(int fd); static long long int get_read_rx_bytes(ReadRxBytes read) { @@ -33,9 +32,5 @@ static void call_token_setter(TokenSetter setter, const char* server_id, int ser { setter(server_id, server_type, tokens); } -static void call_proxy_setup(ProxySetup proxysetup, int fd) -{ - proxysetup(fd); -} #endif /* EXPORTS_H */ diff --git a/internal/api/api.go b/internal/api/api.go index 7111c45..4ee82b0 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -233,8 +233,6 @@ type ConnectData struct { Protocol protocol.Protocol // Expires tells us when this configuration expires Expires time.Time - // Proxy is filled when WireGuard is proxied - Proxy *wireguard.Proxy } // see https://github.com/eduvpn/documentation/blob/v3/API.md#request-1 @@ -338,7 +336,7 @@ func (a *API) Connect(ctx context.Context, prof profiles.Profile, protos []proto }, nil } - vpnCfg, proxy, err := wireguard.Config(vpnCfg, wgKey, proto == protocol.WireGuardProxy) + vpnCfg, err = wireguard.Config(vpnCfg, wgKey) if err != nil { return nil, err } @@ -346,7 +344,6 @@ func (a *API) Connect(ctx context.Context, prof profiles.Profile, protos []proto Configuration: vpnCfg, Protocol: proto, Expires: expT, - Proxy: proxy, }, nil } diff --git a/internal/api/api_test.go b/internal/api/api_test.go index f611f07..6ad70f6 100644 --- a/internal/api/api_test.go +++ b/internal/api/api_test.go @@ -10,6 +10,7 @@ import ( "net/url" "reflect" "regexp" + "slices" "strings" "testing" "time" @@ -17,11 +18,9 @@ import ( "codeberg.org/eduVPN/eduvpn-common/internal/api/profiles" httpw "codeberg.org/eduVPN/eduvpn-common/internal/http" "codeberg.org/eduVPN/eduvpn-common/internal/test" - "codeberg.org/eduVPN/eduvpn-common/internal/wireguard" "codeberg.org/eduVPN/eduvpn-common/types/protocol" "codeberg.org/eduVPN/eduvpn-common/types/server" "github.com/jwijenbergh/eduoauth-go" - "slices" ) func tokenHandler(t *testing.T, gt []string) func(http.ResponseWriter, *http.Request) { @@ -421,7 +420,6 @@ func TestAPIConnect(t *testing.T) { Configuration: "openvpnconfig\nscript-security 0", Protocol: protocol.OpenVPN, Expires: time.Date(2000, time.January, 0, 0, 0, 0, 0, time.UTC), - Proxy: nil, }, protos: []protocol.Protocol{protocol.OpenVPN, protocol.WireGuard}, err: nil, @@ -437,7 +435,6 @@ func TestAPIConnect(t *testing.T) { PrivateKey = .*`, Protocol: protocol.WireGuard, Expires: time.Date(2000, time.January, 0, 0, 0, 0, 0, time.UTC), - Proxy: nil, }, protos: []protocol.Protocol{protocol.OpenVPN, protocol.WireGuard}, err: nil, @@ -453,8 +450,6 @@ PrivateKey = .*`, PrivateKey = .*`, Protocol: protocol.WireGuardProxy, Expires: time.Date(2000, time.January, 0, 0, 0, 0, 0, time.UTC), - // proxy will be manually checked - Proxy: &wireguard.Proxy{}, }, ptcp: true, protos: []protocol.Protocol{protocol.OpenVPN, protocol.WireGuard}, @@ -490,19 +485,6 @@ PrivateKey = .*`, // we have already checked the config using a regex c.cd.Configuration = gcd.Configuration - // check proxy manually - if c.cd.Proxy != nil && gcd.Proxy != nil { - if gcd.Proxy.Peer != "https://proxyendpoint" { - t.Fatalf("config data proxy peer is no proxyendpoint with HTTPS scheme: %s", gcd.Proxy.Peer) - } - if gcd.Proxy.SourcePort <= 0 { - t.Fatalf("got proxy source port is smaller or equal to 0: %v", gcd.Proxy.SourcePort) - } - if gcd.Proxy.ListenPort <= 0 { - t.Fatalf("proxy listen port is smaller or equal to 0: %v", gcd.Proxy.ListenPort) - } - c.cd.Proxy = gcd.Proxy - } } if !reflect.DeepEqual(gcd, c.cd) { t.Fatalf("got connect data: %v, not equal to want: %v", gcd, c.cd) diff --git a/internal/server/server.go b/internal/server/server.go index e27b38e..2372494 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -138,21 +138,12 @@ func (s *Server) connect(ctx context.Context, pTCP bool) (*srvtypes.Configuratio if err != nil { return nil, err } - var proxy *srvtypes.Proxy - if apicfg.Proxy != nil { - proxy = &srvtypes.Proxy{ - SourcePort: apicfg.Proxy.SourcePort, - ListenPort: apicfg.Proxy.ListenPort, - Peer: apicfg.Proxy.Peer, - } - } return &srvtypes.Configuration{ VPNConfig: apicfg.Configuration, Protocol: apicfg.Protocol, DefaultGateway: chosenP.DefaultGateway, DNSSearchDomains: chosenP.DNSSearchDomains, ShouldFailover: chosenP.ShouldFailover() && !pTCP, - Proxy: proxy, }, nil } diff --git a/internal/wireguard/ini/ini.go b/internal/wireguard/ini/ini.go index 842928a..46c6f8b 100644 --- a/internal/wireguard/ini/ini.go +++ b/internal/wireguard/ini/ini.go @@ -7,7 +7,6 @@ package ini import ( "errors" "fmt" - "slices" "strings" ) @@ -47,28 +46,6 @@ func keyValue(f string) (string, string, error) { // OrderedKeys is a slice of strings that is used for an ordered map type OrderedKeys []string -func (ok *OrderedKeys) find(name string) int { - if ok == nil { - return -1 - } - for i, v := range *ok { - if v == name { - return i - } - } - return -1 -} - -// Remove removes a `name` from the OrderedKeys slice by finding the name -// It is a no-op if the key does not exist -func (ok *OrderedKeys) Remove(name string) { - idx := ok.find(name) - if idx == -1 { - return - } - *ok = slices.Delete((*ok), idx, idx+1) -} - // Section represents a single section within an ini file // It consists of multiple key and values type Section struct { @@ -78,7 +55,7 @@ type Section struct { // KeyValue gets a value for key `key` // It returns an error if the key does not exist -func (sec *Section) KeyValue(key string) (string, error) { +func (sec *Section) keyValue(key string) (string, error) { if v, ok := sec.keyValues[key]; ok { return v, nil } @@ -96,7 +73,7 @@ func (sec *Section) newKeyValue(key string, value string) { // AddOrReplaceKeyValue adds a key `key` with value `value` // If the key already exists it modifies the value func (sec *Section) AddOrReplaceKeyValue(key string, value string) { - _, err := sec.KeyValue(key) + _, err := sec.keyValue(key) if err == nil { sec.keyValues[key] = value return @@ -108,7 +85,7 @@ func (sec *Section) AddOrReplaceKeyValue(key string, value string) { // It returns an error if the key already exists func (sec *Section) AddKeyValue(key string, value string) error { // get an existing key - _, err := sec.KeyValue(key) + _, err := sec.keyValue(key) if err == nil { return fmt.Errorf("key: '%s' already exists", key) } @@ -116,17 +93,6 @@ func (sec *Section) AddKeyValue(key string, value string) error { return nil } -// RemoveKey removes a key `key` from the section -// It returns an error if the key cannot be found -func (sec *Section) RemoveKey(key string) (string, error) { - if v, ok := sec.keyValues[key]; ok { - sec.keys.Remove(key) - delete(sec.keyValues, key) - return v, nil - } - return "", fmt.Errorf("no key to remove with name: '%s'", key) -} - // INI is the struct for a ini file type INI struct { sections map[string]*Section @@ -172,7 +138,7 @@ func (i *INI) String() string { out.WriteString(fmt.Sprintf("[%s]\n", s)) for _, k := range sec.keys { - v, err := sec.KeyValue(k) + v, err := sec.keyValue(k) if err != nil { continue } diff --git a/internal/wireguard/ini/ini_test.go b/internal/wireguard/ini/ini_test.go index faa45f2..d28ad4d 100644 --- a/internal/wireguard/ini/ini_test.go +++ b/internal/wireguard/ini/ini_test.go @@ -160,73 +160,6 @@ func TestKeyValue(t *testing.T) { } } -func TestOrderedKeysFind(t *testing.T) { - cases := []struct { - v OrderedKeys - in string - w int - }{ - { - v: []string{""}, - in: "test", - w: -1, - }, - { - v: []string{"bla"}, - in: "bla", - w: 0, - }, - { - v: []string{"ha"}, - in: "bla", - w: -1, - }, - { - v: []string{"ha", "ga"}, - in: "ga", - w: 1, - }, - } - - for _, c := range cases { - g := c.v.find(c.in) - if g != c.w { - t.Fatalf("got: %v, want: %v", g, c.w) - } - } -} - -func TestOrderedKeysRemove(t *testing.T) { - cases := []struct { - v OrderedKeys - rem string - out OrderedKeys - }{ - { - v: []string{"bla"}, - rem: "test", - out: []string{"bla"}, - }, - { - v: []string{"bla"}, - rem: "bla", - out: []string{}, - }, - { - v: []string{"ha", "ga"}, - rem: "ga", - out: []string{"ha"}, - }, - } - - for _, c := range cases { - c.v.Remove(c.rem) - if !reflect.DeepEqual(c.v, c.out) { - t.Fatalf("got: %v, want: %v", c.v, c.out) - } - } -} - func TestParse(t *testing.T) { // parse correct file diff --git a/internal/wireguard/wireguard.go b/internal/wireguard/wireguard.go index b156430..d2a0ae0 100644 --- a/internal/wireguard/wireguard.go +++ b/internal/wireguard/wireguard.go @@ -3,115 +3,30 @@ package wireguard import ( "errors" - "fmt" - "net" "codeberg.org/eduVPN/eduvpn-common/internal/wireguard/ini" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" ) -func availableTCPPort() (int, error) { - tcpaddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:0") - if err != nil { - return -1, err - } - ltcp, err := net.ListenTCP("tcp", tcpaddr) - if err != nil { - return -1, err - } - defer ltcp.Close() //nolint:errcheck - return ltcp.Addr().(*net.TCPAddr).Port, nil -} - -func availableUDPPort() (int, error) { - udpaddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0") - if err != nil { - return -1, err - } - ludp, err := net.ListenUDP("udp", udpaddr) - if err != nil { - return -1, err - } - defer ludp.Close() //nolint:errcheck - return ludp.LocalAddr().(*net.UDPAddr).Port, nil -} - -// Proxy is the proxyguard information -type Proxy struct { - // SourcePort is the source port of the TCP socket - SourcePort int - // ListenPort is the PORT of the udp listener - ListenPort int - // Peer is the hostname/ip:port of the WireGuard peer - Peer string -} - -// Config gets a wireguard config with API config `cfg`, wg key `key` and whether to use proxyguard `proxy` -func Config(cfg string, key *wgtypes.Key, proxy bool) (string, *Proxy, error) { +// Config places a WireGuard key `key` inside of the WireGuard config `cfg` +func Config(cfg string, key *wgtypes.Key) (string, error) { // the key is nil if the client does not accept WireGuard if key == nil { - return "", nil, errors.New("the server sent us a WireGuard profile but the client does not accept WireGuard") - } - - var tcpp int - var udpp int - var err error - var udpl string - - if proxy { - tcpp, err = availableTCPPort() - if err != nil { - return "", nil, err - } - udpp, err = availableUDPPort() - if err != nil { - return "", nil, err - } - udpl = fmt.Sprintf("127.0.0.1:%d", udpp) - } - - rcfg, peer, err := configReplace(cfg, *key, udpl) - if err != nil { - return "", nil, err - } - var retP *Proxy - if proxy { - retP = &Proxy{ - SourcePort: tcpp, - ListenPort: udpp, - Peer: peer, - } + return "", errors.New("the server sent us a WireGuard profile but the client does not accept WireGuard") } - return rcfg, retP, nil -} -// ConfigReplace replaces the wireguard config with our private key and proxy in case of TCP -func configReplace(cfg string, key wgtypes.Key, proxy string) (string, string, error) { // first parse the config secs := ini.Parse(cfg) if secs.Empty() { - return "", "", errors.New("parsed ini is empty") + return "", errors.New("parsed ini is empty") } // find the interface section // and set the private key is, err := secs.Section("Interface") if err != nil { - return "", "", err + return "", err } is.AddOrReplaceKeyValue("PrivateKey", key.String()) - peer := "" - if proxy != "" { - ps, err := secs.Section("Peer") - if err != nil { - return "", "", err - } - peer, err = ps.RemoveKey("ProxyEndpoint") - if err != nil { - return "", "", err - } - ps.AddOrReplaceKeyValue("Endpoint", proxy) - } - - return secs.String(), peer, nil + return secs.String(), nil } diff --git a/internal/wireguard/wireguard_test.go b/internal/wireguard/wireguard_test.go index bd68afb..5092320 100644 --- a/internal/wireguard/wireguard_test.go +++ b/internal/wireguard/wireguard_test.go @@ -8,7 +8,7 @@ import ( "golang.zx2c4.com/wireguard/wgctrl/wgtypes" ) -func TestConfigReplace(t *testing.T) { +func TestConfig(t *testing.T) { k, err := wgtypes.GeneratePrivateKey() if err != nil { t.Fatalf("Failed to generate key for wg config replace: %v", err) @@ -16,7 +16,6 @@ func TestConfigReplace(t *testing.T) { cases := []struct { config string - proxy string want string wantep string werr string @@ -24,10 +23,8 @@ func TestConfigReplace(t *testing.T) { { config: ` `, - want: "", - wantep: "", - proxy: "", - werr: "parsed ini is empty", + want: "", + werr: "parsed ini is empty", }, { config: ` @@ -48,9 +45,7 @@ PrivateKey = %s [interface] [interface2] `, k.String()), - wantep: "", - proxy: "", - werr: "", + werr: "", }, { config: ` @@ -73,23 +68,17 @@ DNS = 9.9.9.9,2620:fe::fe [Peer] PublicKey = AllowedIPs = 0.0.0.0/0,::/0 -Endpoint = 127.0.0.1:1337 +ProxyEndpoint = https://vpn.example.org/example `, k.String()), - wantep: "https://vpn.example.org/example", - proxy: "127.0.0.1:1337", - werr: "", + werr: "", }, } for _, c := range cases { - gcfg, gep, err := configReplace(c.config, k, c.proxy) + gcfg, err := Config(c.config, &k) test.AssertError(t, err, c.werr) if gcfg != c.want { t.Fatalf("Got config: %s, not equal to config: %s", gcfg, c.want) } - - if gep != c.wantep { - t.Fatalf("Got endpoint: %s, not equal to endpoint: %s", gep, c.wantep) - } } } diff --git a/proxy/proxy.go b/proxy/proxy.go deleted file mode 100644 index 4c51aed..0000000 --- a/proxy/proxy.go +++ /dev/null @@ -1,84 +0,0 @@ -// Package proxy is a wrapper around proxyguard that integrates it with eduvpn-common settings -// - leaves out some options not applicable to the common integration, e.g. fwmark -// - integrates with eduvpn-common's logger -// - integrates eduvpn-common's user agent -package proxy - -import ( - "context" - - "codeberg.org/eduVPN/proxyguard" - - "codeberg.org/eduVPN/eduvpn-common/i18nerr" - httpw "codeberg.org/eduVPN/eduvpn-common/internal/http" - "codeberg.org/eduVPN/eduvpn-common/internal/log" -) - -// Logger is defined here such that we can update the proxyguard logger -type Logger struct{} - -// Logf logs a message with parameters -func (l *Logger) Logf(msg string, params ...any) { - log.Logger.Infof("[Proxyguard] "+msg, params...) -} - -// Log logs a message -func (l *Logger) Log(msg string) { - log.Logger.Infof("[Proxyguard] %s", msg) -} - -// Proxy is the ProxyGuard client with a channel used for restarting -type Proxy struct { - proxyguard.Client - resChan chan struct{} -} - -// NewProxyguard sets up proxyguard for proxied WireGuard connections -func NewProxyguard(ctx context.Context, lp int, tcpsp int, peer string, setupSocket func(fd int)) (*Proxy, error) { - proxyguard.UpdateLogger(&Logger{}) - proxy := Proxy{ - Client: proxyguard.Client{ - Peer: peer, - ListenPort: lp, - TCPSourcePort: tcpsp, - SetupSocket: setupSocket, - UserAgent: httpw.UserAgent, - }, - resChan: make(chan struct{}), - } - _, err := proxy.Setup(ctx) - if err != nil { - return nil, i18nerr.WrapInternal(err, "The ProxyGuard DNS could not be resolved") - } - - return &proxy, nil -} - -// Tunnel tunnels the ProxyGuard connection. `wglisten` is the WireGuard listen port -func (p *Proxy) Tunnel(ctx context.Context, wglisten int) error { - log.Logger.Infof("callying tunnel") - errChan := make(chan error, 1) - gctx, cancel := context.WithCancel(ctx) - go func() { - err := p.Client.Tunnel(gctx, wglisten) - if err != nil { - err = i18nerr.WrapInternal(err, "The VPN proxy exited") - } - errChan <- err - }() - - select { - case err := <-errChan: - cancel() - return err - case <-p.resChan: - cancel() - <-errChan - return p.Tunnel(ctx, wglisten) - } -} - -// Restart restarts the existing ProxyGuard process, for e.g. roaming -func (p *Proxy) Restart() { - p.resChan <- struct{}{} -} diff --git a/types/server/server.go b/types/server/server.go index 3b0d374..cfadb25 100644 --- a/types/server/server.go +++ b/types/server/server.go @@ -164,18 +164,6 @@ type List struct { Custom []Server `json:"custom_servers,omitempty"` } -// Proxy defines the structure with the arguments that should be passed to start proxyguard -type Proxy struct { - // SourcePort is the source port for the client TCP connection - SourcePort int `json:"source_port"` - // ListenPort is the port for the client UDP connection, this is the value that is set as the WireGuard endpoint prepended with "127.0.0.1:" - // So if the listen port is set to 1337, the WireGuard endpoint would be 127.0.0.1:1337 - ListenPort int `json:"listen_port"` - // Peer is the URI of the upstream server - // Note that this exactly matches the "ProxyEndpoint" key in the WireGuard config - Peer string `json:"peer"` -} - // Configuration is the configuration that you get back when you call the get config function type Configuration struct { // VPNConfig is the VPN Configuration, a WireGuard or OpenVPN Configuration @@ -190,9 +178,6 @@ type Configuration struct { DNSSearchDomains []string `json:"dns_search_domains,omitempty"` // ShouldFailover returns whether or not the client should attempt to failover ShouldFailover bool `json:"should_failover"` - // Proxy returns information for proxied VPN connections - // If this is non-nil a proxy must be started using StartProxyguard - Proxy *Proxy `json:"proxy,omitempty"` } // Current is the struct that defines the current server diff --git a/wrappers/python/eduvpn_common/loader.py b/wrappers/python/eduvpn_common/loader.py index 11307ef..6957c15 100644 --- a/wrappers/python/eduvpn_common/loader.py +++ b/wrappers/python/eduvpn_common/loader.py @@ -6,7 +6,6 @@ from eduvpn_common.types import ( BoolError, DataError, HandlerError, - ProxySetup, ReadRxBytes, RefreshList, TokenGetter, @@ -134,33 +133,3 @@ def initialize_functions(lib: CDLL) -> None: ], BoolError, ) - lib.NewProxyguard.argtypes, lib.NewProxyguard.restype = ( - [ - c_int, - c_int, - c_int, - c_char_p, - ProxySetup, - ], - HandlerError, - ) - lib.ProxyguardRestart.argtypes, lib.ProxyguardRestart.restype = ( - [ - c_int, - ], - c_char_p, - ) - lib.ProxyguardTunnel.argtypes, lib.ProxyguardTunnel.restype = ( - [ - c_int, - c_int, - c_int, - ], - c_char_p, - ) - lib.ProxyguardPeerIPs.argtypes, lib.ProxyguardPeerIPs.restype = ( - [ - c_int, - ], - DataError, - ) diff --git a/wrappers/python/eduvpn_common/main.py b/wrappers/python/eduvpn_common/main.py index 8d78afd..613dce2 100644 --- a/wrappers/python/eduvpn_common/main.py +++ b/wrappers/python/eduvpn_common/main.py @@ -1,13 +1,12 @@ import ctypes import json from enum import IntEnum -from typing import Any, Callable, Iterator, List, Optional +from typing import Any, Callable, Iterator, Optional from eduvpn_common.event import EventHandler from eduvpn_common.loader import initialize_functions, load_lib from eduvpn_common.state import State from eduvpn_common.types import ( - ProxySetup, ReadRxBytes, RefreshList, TokenGetter, @@ -20,29 +19,6 @@ from eduvpn_common.types import ( global_object = None -class Proxyguard(object): - def __init__(self, parent, handler): - self.parent = parent - self.handler = handler - - def tunnel(self, wglisten: int): - tunnel_err = self.parent.go_cookie_function(self.parent.lib.ProxyguardTunnel, self.handler, wglisten) - if tunnel_err: - forwardError(tunnel_err) - - @property - def peer_ips(self) -> List[str]: - peer_ips, peer_ips_err = self.parent.go_function(self.parent.lib.ProxyguardPeerIPs, self.handler) - if peer_ips_err: - forwardError(peer_ips_err) - return json.loads(peer_ips) - - def restart(self): - restart_err = self.parent.go_function(self.parent.lib.ProxyguardRestart, self.handler) - if restart_err: - forwardError(restart_err) - - class WrappedError(Exception): def __init__(self, translations, language, misc): self.translations = translations @@ -381,24 +357,6 @@ class EduVPN(object): forwardError(dropped_err) return dropped - def new_proxyguard( - self, - listen_port: int, - tcp_source_port: int, - peer: str, - setup: ProxySetup, - ) -> Proxyguard: - proxy, proxy_err = self.go_cookie_function( - self.lib.NewProxyguard, - listen_port, - tcp_source_port, - peer, - setup, - ) - if proxy_err: - forwardError(proxy_err) - return Proxyguard(self, proxy) - def cancel(self): self.jar.cancel() diff --git a/wrappers/python/eduvpn_common/types.py b/wrappers/python/eduvpn_common/types.py index 5e23d61..999fbdd 100644 --- a/wrappers/python/eduvpn_common/types.py +++ b/wrappers/python/eduvpn_common/types.py @@ -45,7 +45,6 @@ class BoolError(Structure): # The type for a Go state change callback VPNStateChange = CFUNCTYPE(c_int, c_int, c_int, c_char_p) -ProxySetup = CFUNCTYPE(c_void_p, c_int) ReadRxBytes = CFUNCTYPE(c_ulonglong) RefreshList = CFUNCTYPE(c_void_p) TokenGetter = CFUNCTYPE(c_void_p, c_char_p, c_int, POINTER(c_char), c_size_t) |
