Refine WireGuard client routing and authentication UI
This commit is contained in:
1 parent
eabb3e4472
commit
41fb9d5631
33 files changed
+1709
-469
No files matched your search
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"net/netip"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -64,6 +65,93 @@ func TestRejectSymlinkedKeyFile(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRejectOversizedRecord(t *testing.T) {
|
||||
path := filepath.Join(t.TempDir(), "record.json")
|
||||
if err := os.WriteFile(path, []byte(strings.Repeat("x", 64*1024+1)), 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := readRecord(path); err == nil || !strings.Contains(err.Error(), "大小限制") {
|
||||
t.Fatalf("oversized record accepted: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStatusReturnsOnlyNonSecretCounters(t *testing.T) {
|
||||
raw := "private_key=secret\npublic_key=peer\npreshared_key=secret\nendpoint=192.0.2.1:51820\n" +
|
||||
"last_handshake_time_sec=123\nrx_bytes=456\ntx_bytes=789\nallowed_ip=0.0.0.0/0\n"
|
||||
status, err := sanitizedStatus(raw)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if status.Status != "device_status" || status.HandshakeUnix != 123 || status.RXBytes != 456 || status.TXBytes != 789 {
|
||||
t.Fatalf("unexpected status: %+v", status)
|
||||
}
|
||||
data, err := json.Marshal(status)
|
||||
if err != nil || strings.Contains(string(data), "secret") || strings.Contains(string(data), "192.0.2.1") {
|
||||
t.Fatalf("status leaked configuration: %s, %v", data, err)
|
||||
}
|
||||
for _, malformed := range []string{"private_key=secret", "public_key=peer\nrx_bytes=bad", "public_key=one\npublic_key=two"} {
|
||||
if _, err := sanitizedStatus(malformed); err == nil {
|
||||
t.Fatalf("malformed device status accepted: %q", malformed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNativeRoutePlanGuardsPhysicalEndpoint(t *testing.T) {
|
||||
r := testRecord()
|
||||
ip, port, err := resolveEndpoint(r.Config.Endpoint)
|
||||
if err != nil || ip.String() != "121.4.111.208" || port != "51820" {
|
||||
t.Fatalf("endpoint resolution failed: %s, %s, %v", ip, port, err)
|
||||
}
|
||||
r.Config.AllowedIPs = "0.0.0.0/0"
|
||||
plan, err := planNativeRoutes(r, "utun12", ip)
|
||||
if err != nil || !plan.EndpointBypass || len(plan.Routes) != 2 ||
|
||||
plan.Routes[0].String() != "0.0.0.0/1" || plan.Routes[1].String() != "128.0.0.0/1" {
|
||||
t.Fatalf("full route missing endpoint bypass: %+v, %v", plan, err)
|
||||
}
|
||||
r.Config.AllowedIPs = "10.88.0.0/24, 10.88.0.0/24"
|
||||
plan, err = planNativeRoutes(r, "utun2", netip.MustParseAddr("121.4.111.208"))
|
||||
if err != nil || plan.EndpointBypass || len(plan.Routes) != 1 || plan.Routes[0].String() != "10.88.0.0/24" {
|
||||
t.Fatalf("split route not normalized: %+v, %v", plan, err)
|
||||
}
|
||||
r.Config.AllowedIPs = "::/0, 0.0.0.0/0"
|
||||
if _, err := planNativeRoutes(r, "utun2", netip.MustParseAddr("121.4.111.208")); err == nil {
|
||||
t.Fatal("unsupported IPv6 route accepted")
|
||||
}
|
||||
for _, name := range []string{"utun", "utun1;route", "eth0", "utun-1"} {
|
||||
if _, err := planNativeRoutes(r, name, netip.MustParseAddr("121.4.111.208")); err == nil {
|
||||
t.Fatalf("unsafe interface accepted: %q", name)
|
||||
}
|
||||
}
|
||||
for _, endpoint := range []string{"127.0.0.1:51820", "[::1]:51820", "missing-port"} {
|
||||
if _, _, err := resolveEndpoint(endpoint); err == nil {
|
||||
t.Fatalf("invalid endpoint accepted: %q", endpoint)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPhysicalRouteParsingRejectsVPNAndInjection(t *testing.T) {
|
||||
output := " route to: 121.4.111.208\n gateway: 192.168.80.1\n interface: en0\n"
|
||||
exit, err := parsePhysicalRoute(output)
|
||||
if err != nil || exit.Interface != "en0" || exit.Gateway == nil || exit.Gateway.String() != "192.168.80.1" {
|
||||
t.Fatalf("physical gateway rejected: %+v, %v", exit, err)
|
||||
}
|
||||
direct, err := parsePhysicalRoute("interface: en4\n")
|
||||
if err != nil || direct.Gateway != nil {
|
||||
t.Fatalf("direct physical link rejected: %+v, %v", direct, err)
|
||||
}
|
||||
for _, raw := range []string{
|
||||
"interface: utun2\ngateway: 10.0.0.1\n",
|
||||
"interface: en0;touch /tmp/injected\n",
|
||||
"interface: lo0\n",
|
||||
"gateway: 192.168.80.1\n",
|
||||
"interface: en0\ngateway: invalid\n",
|
||||
} {
|
||||
if _, err := parsePhysicalRoute(raw); err == nil {
|
||||
t.Fatalf("unsafe route accepted: %q", raw)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestProxyCannotBindPublicInterface(t *testing.T) {
|
||||
for _, address := range []string{"0.0.0.0:19090", "192.0.2.1:19090", "127.0.0.1:0", "garbage"} {
|
||||
if err := serveSOCKS(testRecord(), address); err == nil {
|
||||
|
||||
Reference in new issue
Block a user