fix(ss): propagate cipher errors and decode SIP002 base64 auth
- Return err instead of nil in SS TCP/UDP connector Init when NewClientConfig fails, preventing nil pointer dereference in WrapConn - Initialize tcpClient in UDP connector for UDP-over-TCP path - Add decodeSIP002Auth to handle ss://BASE64(method:password)@host:port URL format with RawURLEncoding and StdEncoding fallback - Update buildServiceConfig and buildNodeConfig to decode SIP002 auth for ss* schemes before falling back to standard userinfo parsing - Support RawURLEncoding in parseAuthFromCmd with StdEncoding fallback - Add tests for decodeSIP002Auth, parseAuthFromCmd, and integration tests for buildNodeConfig/buildServiceConfig
This commit is contained in:
+55
-9
@@ -469,10 +469,15 @@ func buildServiceConfig(url *url.URL) ([]*config.ServiceConfig, error) {
|
||||
|
||||
var auth *config.AuthConfig
|
||||
if url.User != nil {
|
||||
auth = &config.AuthConfig{
|
||||
Username: url.User.Username(),
|
||||
if strings.HasPrefix(url.Scheme, "ss") {
|
||||
auth = decodeSIP002Auth(url)
|
||||
}
|
||||
if auth == nil {
|
||||
auth = &config.AuthConfig{
|
||||
Username: url.User.Username(),
|
||||
}
|
||||
auth.Password, _ = url.User.Password()
|
||||
}
|
||||
auth.Password, _ = url.User.Password()
|
||||
}
|
||||
|
||||
m := map[string]any{}
|
||||
@@ -614,10 +619,15 @@ func buildNodeConfig(url *url.URL, m map[string]any) (*config.NodeConfig, error)
|
||||
|
||||
var auth *config.AuthConfig
|
||||
if url.User != nil {
|
||||
auth = &config.AuthConfig{
|
||||
Username: url.User.Username(),
|
||||
if strings.HasPrefix(url.Scheme, "ss") {
|
||||
auth = decodeSIP002Auth(url)
|
||||
}
|
||||
if auth == nil {
|
||||
auth = &config.AuthConfig{
|
||||
Username: url.User.Username(),
|
||||
}
|
||||
auth.Password, _ = url.User.Password()
|
||||
}
|
||||
auth.Password, _ = url.User.Password()
|
||||
}
|
||||
|
||||
if sauth := mdutil.GetString(md, "auth"); sauth != "" && auth == nil {
|
||||
@@ -742,10 +752,46 @@ func Norm(s string) (*url.URL, error) {
|
||||
return url, nil
|
||||
}
|
||||
|
||||
func parseAuthFromCmd(sa string) (*config.AuthConfig, error) {
|
||||
v, err := base64.StdEncoding.DecodeString(sa)
|
||||
func decodeSIP002Auth(u *url.URL) *config.AuthConfig {
|
||||
if u.User == nil {
|
||||
return nil
|
||||
}
|
||||
_, hasPassword := u.User.Password()
|
||||
if hasPassword {
|
||||
return nil
|
||||
}
|
||||
username := u.User.Username()
|
||||
if username == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
decoded, err := base64.RawURLEncoding.DecodeString(username)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
decoded, err = base64.StdEncoding.DecodeString(username)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
cs := string(decoded)
|
||||
n := strings.IndexByte(cs, ':')
|
||||
if n < 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &config.AuthConfig{
|
||||
Username: cs[:n],
|
||||
Password: cs[n+1:],
|
||||
}
|
||||
}
|
||||
|
||||
func parseAuthFromCmd(sa string) (*config.AuthConfig, error) {
|
||||
v, err := base64.RawURLEncoding.DecodeString(sa)
|
||||
if err != nil {
|
||||
v, err = base64.StdEncoding.DecodeString(sa)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
cs := string(v)
|
||||
n := strings.IndexByte(cs, ':')
|
||||
|
||||
Reference in New Issue
Block a user