From f25dcda007547f7dfb75c4aded7fd94ed2236e21 Mon Sep 17 00:00:00 2001 From: jwijenbergh Date: Tue, 31 Jan 2023 12:00:44 +0100 Subject: Client: Check if client ID is valid --- client/client.go | 30 +++++++++++++++++++++++++++++- client/client_test.go | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) (limited to 'client') diff --git a/client/client.go b/client/client.go index c443528..1a1e881 100644 --- a/client/client.go +++ b/client/client.go @@ -32,10 +32,34 @@ func (c *Client) logError(err error) { } func (c *Client) isLetsConnect() bool { - // see https://git.sr.ht/~fkooman/vpn-user-portal/tree/v3/item/src/OAuth/ClientDb.php + // see https://git.sr.ht/~fkooman/vpn-user-portal/tree/v3/item/src/OAuth/VpnClientDb.php return strings.HasPrefix(c.Name, "org.letsconnect-vpn.app") } +// isAllowedClientID checks if the 'clientID' is in the list of allowed client IDs +func isAllowedClientID(clientID string) bool { + allowList := []string{ + // eduVPN + "org.eduvpn.app.windows", + "org.eduvpn.app.android", + "org.eduvpn.app.ios", + "org.eduvpn.app.macos", + "org.eduvpn.app.linux", + // Let's Connect! + "org.letsconnect-vpn.app.windows", + "org.letsconnect-vpn.app.android", + "org.letsconnect-vpn.app.ios", + "org.letsconnect-vpn.app.macos", + "org.letsconnect-vpn.app.linux", + } + for _, x := range allowList { + if x == clientID { + return true + } + } + return false +} + // Client is the main struct for the VPN client. type Client struct { // The name of the client @@ -93,6 +117,10 @@ func (c *Client) Register( return errors.Errorf("fsm attempt to register while in '%v'", c.FSM.Current) } + if !isAllowedClientID(name) { + return errors.Errorf("client ID is not allowed: '%v', see https://git.sr.ht/~fkooman/vpn-user-portal/tree/v3/item/src/OAuth/VpnClientDb.php for a list of allowed IDs", name) + } + c.Name = name // TODO: Verify language setting? diff --git a/client/client_test.go b/client/client_test.go index ec5086f..b4b944b 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -406,3 +406,41 @@ func TestPreferTCP(t *testing.T) { t.Fatalf("Suffix for disable prefer TCP is not in the right order for config: %s", config.Config) } } + +func TestInvalidClientID(t *testing.T) { + tests := map[string]bool { + "test": false, + "org.letsconnect-vpn.app.linux": true, + "org.letsconnect-vpn": false, + "org.letsconnect-vpn.app": false, + "org.letsconnect-vpn.linuxsd": false, + "org.letsconnect-vpn.app.macos": true, + } + + for k, v := range tests { + state := &Client{} + registerErr := state.Register( + k, + "configsclientid", + "en", + func(old FSMStateID, new FSMStateID, data interface{}) bool { + stateCallback(t, old, new, data, state) + return true + }, + false, + ) + if v { + if registerErr != nil { + t.Fatalf("expected valid register with clientID: %v, got error: %v", k, registerErr) + } + continue + } + if registerErr == nil { + t.Fatalf("expected invalid register with clientID: %v, but got no error", k) + } + if !strings.HasPrefix(registerErr.Error(), "client ID is not allowed") { + t.Fatalf("register error has invalid prefix: %v", registerErr.Error()) + } + } + +} -- cgit v1.2.3