CI / go-test (push) Canceled after 0s
CI / postgres-durable-first (push) Canceled after 0s
CI / codegen (push) Canceled after 0s
CI / govulncheck (push) Canceled after 0s
CI / race (push) Canceled after 0s
CI / fuzz-smoke (push) Canceled after 0s
CI / golangci (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CodeQL Advanced / Analyze (go) (push) Canceled after 0s
CodeQL Advanced / Analyze (actions) (push) Canceled after 0s
CodeQL Advanced / Analyze (javascript-typescript) (push) Canceled after 0s
Docs CI / build (push) Canceled after 0s
Docs Deploy (GitHub Pages) / build (push) Canceled after 0s
Release 3X-UI / build (386) (push) Canceled after 0s
Release 3X-UI / build (amd64) (push) Canceled after 0s
Release 3X-UI / build (arm64) (push) Canceled after 0s
Release 3X-UI / build (armv5) (push) Canceled after 0s
Release 3X-UI / build (armv6) (push) Canceled after 0s
Release 3X-UI / build (armv7) (push) Canceled after 0s
Release 3X-UI / build (s390x) (push) Canceled after 0s
Release 3X-UI / Build for Windows (amd64) (push) Canceled after 0s
Deploy Smoke Tests / noninteractive-install (ubuntu-24.04-arm) (push) Canceled after 0s
Deploy Smoke Tests / noninteractive-install (ubuntu-latest) (push) Canceled after 0s
Deploy Smoke Tests / release-tag-install (ubuntu-24.04-arm) (push) Canceled after 0s
Deploy Smoke Tests / release-tag-install (ubuntu-latest) (push) Canceled after 0s
Docs Deploy (GitHub Pages) / deploy (push) Canceled after 0s
Release 3X-UI / Publish rolling dev release (push) Canceled after 0s
50 lines
1.9 KiB
Go
50 lines
1.9 KiB
Go
package service
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"testing"
|
|
)
|
|
|
|
// A method switch between SS-2022 ciphers of different key sizes must regenerate
|
|
// client PSKs whose length no longer matches; otherwise xray rejects the user.
|
|
func TestNormalizeShadowsocksClientKeys_RegeneratesOnMethodResize(t *testing.T) {
|
|
// 32-byte (aes-256-sized) client key under an aes-128 (16-byte) method.
|
|
oversized := base64.StdEncoding.EncodeToString(make([]byte, 32))
|
|
settings := `{"method":"2022-blake3-aes-128-gcm","password":"` +
|
|
base64.StdEncoding.EncodeToString(make([]byte, 16)) +
|
|
`","clients":[{"email":"a","password":"` + oversized + `"}]}`
|
|
|
|
out, changed := normalizeShadowsocksClientKeys(settings)
|
|
if !changed {
|
|
t.Fatalf("expected mismatched client key to be regenerated")
|
|
}
|
|
|
|
var m map[string]any
|
|
if err := json.Unmarshal([]byte(out), &m); err != nil {
|
|
t.Fatalf("unmarshal: %v", err)
|
|
}
|
|
clients := m["clients"].([]any)
|
|
pw := clients[0].(map[string]any)["password"].(string)
|
|
if pw == oversized {
|
|
t.Fatalf("client key was not regenerated")
|
|
}
|
|
if decoded, err := base64.StdEncoding.DecodeString(pw); err != nil || len(decoded) != 16 {
|
|
t.Fatalf("regenerated key must be 16 bytes for aes-128, got len=%d err=%v", len(decoded), err)
|
|
}
|
|
}
|
|
|
|
// A correctly-sized key (and non-2022 / legacy settings) must pass through untouched.
|
|
func TestNormalizeShadowsocksClientKeys_NoChangeWhenValid(t *testing.T) {
|
|
valid := base64.StdEncoding.EncodeToString(make([]byte, 32))
|
|
settings := `{"method":"2022-blake3-aes-256-gcm","clients":[{"email":"a","password":"` + valid + `"}]}`
|
|
if out, changed := normalizeShadowsocksClientKeys(settings); changed || out != settings {
|
|
t.Fatalf("valid aes-256 key must be left unchanged")
|
|
}
|
|
|
|
legacy := `{"method":"aes-256-gcm","clients":[{"email":"a","password":"anything"}]}`
|
|
if out, changed := normalizeShadowsocksClientKeys(legacy); changed || out != legacy {
|
|
t.Fatalf("legacy (non-2022) SS settings must be left unchanged")
|
|
}
|
|
}
|