package awg import ( "encoding/base64" "testing" ) func TestParseINI_AWG20(t *testing.T) { raw := `[Interface] PrivateKey = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= Address = 10.8.0.2/32 DNS = 1.1.1.1 Jc = 4 Jmin = 40 Jmax = 70 H1 = 1 H2 = 2 H3 = 3 H4 = 4 I1 = [Peer] PublicKey = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE= Endpoint = 203.0.113.10:51820 AllowedIPs = 0.0.0.0/0 PersistentKeepalive = 25 ` c, err := Parse(raw) if err != nil { t.Fatal(err) } if c.Jc != 4 || c.I1 != "" || c.Endpoint != "203.0.113.10:51820" { t.Fatalf("unexpected conf: %+v", c) } if !c.IsAWG20() { t.Fatal("expected AWG2 markers") } ipc, err := c.ToIPC() if err != nil { t.Fatal(err) } if !containsAll(ipc, "jc=4", "i1=", "endpoint=203.0.113.10:51820") { t.Fatalf("bad ipc: %s", ipc) } } func TestParseURI_UserInfoPrivateKey(t *testing.T) { priv := "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" pub := "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=" raw := "awg://" + priv + "@203.0.113.10:51820/?public_key=" + pub + "&address=10.8.0.2/32&jc=4" c, err := Parse(raw) if err != nil { t.Fatal(err) } if c.PrivateKey != priv { t.Fatalf("private key: %q", c.PrivateKey) } if c.PublicKey != pub { t.Fatalf("public key: %q", c.PublicKey) } if c.Endpoint != "203.0.113.10:51820" { t.Fatalf("endpoint: %q", c.Endpoint) } } func TestParseINI_SpacedKeysAndQuotes(t *testing.T) { raw := `Private Key = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" Address = 10.8.0.2/32 [Peer] Public Key = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=' Endpoint = 1.2.3.4:51820 ` c, err := Parse(raw) if err != nil { t.Fatal(err) } if c.PrivateKey == "" || c.PublicKey == "" { t.Fatalf("keys missing: %+v", c) } } func TestParseAmneziaJSON(t *testing.T) { raw := `{ "client_priv_key": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", "server_pub_key": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=", "client_ip": "10.8.0.2/32", "hostName": "203.0.113.10", "port": "51820", "Jc": 4, "Jmin": 10, "Jmax": 50, "H1": "1", "H2": "2", "H3": "3", "H4": "4" }` c, err := Parse(raw) if err != nil { t.Fatal(err) } if c.Endpoint != "203.0.113.10:51820" { t.Fatalf("endpoint %q", c.Endpoint) } if c.Jc != 4 { t.Fatalf("jc %d", c.Jc) } } func TestParseVPNScheme(t *testing.T) { inner := `{"client_priv_key":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=","server_pub_key":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=","client_ip":"10.8.0.2/32","hostName":"9.9.9.9","port":"51820"}` raw := "vpn://" + base64.StdEncoding.EncodeToString([]byte(inner)) c, err := Parse(raw) if err != nil { t.Fatal(err) } if c.Endpoint != "9.9.9.9:51820" { t.Fatalf("endpoint %q", c.Endpoint) } } func TestDetect(t *testing.T) { if !Detect("[Interface]\nPrivateKey = x") { t.Fatal("expected detect") } if !Detect("awg://1.2.3.4:51820/?private_key=a&public_key=b&address=10.0.0.2/32") { t.Fatal("expected awg uri detect") } if !Detect(`{"client_priv_key":"x","server_pub_key":"y"}`) { t.Fatal("expected json detect") } } func TestDecodeKeyURLSafe(t *testing.T) { // 32 zero bytes, URL-safe without padding raw := base64.RawURLEncoding.EncodeToString(make([]byte, 32)) b, err := decodeKey(raw) if err != nil || len(b) != 32 { t.Fatalf("url-safe: %v %d", err, len(b)) } } func containsAll(s string, parts ...string) bool { for _, p := range parts { if !stringsContains(s, p) { return false } } return true } func stringsContains(s, sub string) bool { return len(sub) == 0 || (len(s) >= len(sub) && indexOf(s, sub) >= 0) } func indexOf(s, sub string) int { for i := 0; i+len(sub) <= len(s); i++ { if s[i:i+len(sub)] == sub { return i } } return -1 }