mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-11-02 11:15:03 +03:00
fix(mtproto): leave clients mtg cannot parse out of the generated config
One mtg-multi process serves every client of an MTProto inbound from a single TOML file and refuses the whole file over one value it cannot parse. InstanceFromInbound already guarded the ad tag for that reason but copied secret, quota and expiry as stored, so a malformed secret, a year-10000 expiry or a near-MaxInt64 quota on one client took the sidecar down for everyone on the inbound. A client whose secret mtg cannot parse is left out with a warning, and quota and expiry are capped at what mtg accepts.
This commit is contained in:
@@ -4,6 +4,7 @@ package model
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@@ -707,6 +708,16 @@ func ValidMtprotoAdTag(tag string) bool {
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// ValidMtprotoSecret mirrors mtg's secret parser: hex, else unpadded URL-safe
|
||||
// base64, of the 0xee FakeTLS marker, a 16-byte key and a non-empty host name.
|
||||
func ValidMtprotoSecret(secret string) bool {
|
||||
decoded, err := hex.DecodeString(secret)
|
||||
if err != nil {
|
||||
decoded, err = base64.RawURLEncoding.DecodeString(secret)
|
||||
}
|
||||
return err == nil && len(decoded) > 17 && decoded[0] == 0xee
|
||||
}
|
||||
|
||||
// StripMtprotoInboundSecret removes the vestigial inbound-level `secret` from an
|
||||
// mtproto inbound's settings JSON. MTProto is multi-client: every secret lives on
|
||||
// a client, and mtg's [secrets] config plus every share link read only the
|
||||
|
||||
@@ -25,6 +25,20 @@ func TestGenerateFakeTLSSecret(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidMtprotoSecret(t *testing.T) {
|
||||
const good = "ee0123456789abcdef0123456789abcdef6578616d706c652e636f6d"
|
||||
for _, s := range []string{good, strings.ToUpper(good), "ee0123456789abcdef0123456789abcdef61", "7gEjRWeJq83vASNFZ4mrze9leGFtcGxlLmNvbQ"} {
|
||||
if !ValidMtprotoSecret(s) {
|
||||
t.Fatalf("mtg parses %q, so it must be valid", s)
|
||||
}
|
||||
}
|
||||
for _, s := range []string{"", "zz", "ee00", "dd0123456789abcdef0123456789abcdef6578616d706c652e636f6d", "ee0123456789abcdef0123456789abcdef", "7gEjRWeJq83vASNFZ4mrze9leGFtcGxlLmNvbQ==", "not a secret"} {
|
||||
if ValidMtprotoSecret(s) {
|
||||
t.Fatalf("mtg refuses %q, so it must be invalid", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStripMtprotoInboundAdTag(t *testing.T) {
|
||||
in := `{"adTag":"0123456789abcdef0123456789abcdef","clients":[{"email":"a","adTag":"fedcba9876543210fedcba9876543210"}]}`
|
||||
out, changed := StripMtprotoInboundAdTag(in)
|
||||
|
||||
Reference in New Issue
Block a user