mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-18 02:26:11 +00:00
fix(mtproto): stop persisting a vestigial inbound-level secret
MTProto is multi-client: mtg's [secrets] config and every share link read only the per-client secrets. The old HealMtprotoSecret regenerated an inbound-level secret on every save, and seedMtprotoSecretsToClients only dropped it for legacy single-secret inbounds, so multi-client inbounds kept a dead secret. That value once leaked into stale links imported into Telegram, which mtg then rejected as "incorrect client random". Replace HealMtprotoSecret with StripMtprotoInboundSecret (removes the key), strip on save in normalizeMtprotoSecret, and add a one-time stripMtprotoInboundSecrets migration that runs after the seeder so a legacy secret is first preserved onto a client before the inbound-level copy is dropped.
This commit is contained in:
@@ -531,14 +531,16 @@ func (s *InboundService) normalizeStreamSettings(inbound *model.Inbound) {
|
||||
}
|
||||
|
||||
// normalizeMtprotoSecret rebuilds every mtproto client's FakeTLS secret so it is
|
||||
// always valid before the row is persisted. It also heals a legacy inbound-level
|
||||
// secret for any inbound that predates the multi-client migration.
|
||||
// always valid before the row is persisted, and drops the vestigial inbound-level
|
||||
// secret: MTProto is multi-client, so mtg and every share link read only the
|
||||
// per-client secrets. Leaving an inbound-level secret behind is what produced
|
||||
// stale links that failed with "incorrect client random".
|
||||
func (s *InboundService) normalizeMtprotoSecret(inbound *model.Inbound) {
|
||||
if inbound.Protocol != model.MTProto {
|
||||
return
|
||||
}
|
||||
if healed, ok := model.HealMtprotoSecret(inbound.Settings); ok {
|
||||
inbound.Settings = healed
|
||||
if stripped, ok := model.StripMtprotoInboundSecret(inbound.Settings); ok {
|
||||
inbound.Settings = stripped
|
||||
}
|
||||
if healed, ok := model.HealMtprotoClientSecrets(inbound.Settings); ok {
|
||||
inbound.Settings = healed
|
||||
|
||||
@@ -128,13 +128,16 @@ func TestFillProtocolDefaultsMtproto(t *testing.T) {
|
||||
|
||||
func TestNormalizeMtprotoSecretHealsClients(t *testing.T) {
|
||||
s := &InboundService{}
|
||||
ib := &model.Inbound{Protocol: model.MTProto, Settings: `{"fakeTlsDomain":"a.com","clients":[{"email":"x","secret":""}]}`}
|
||||
ib := &model.Inbound{Protocol: model.MTProto, Settings: `{"fakeTlsDomain":"a.com","secret":"eedeadbeef","clients":[{"email":"x","secret":""}]}`}
|
||||
s.normalizeMtprotoSecret(ib)
|
||||
|
||||
var parsed map[string]any
|
||||
if err := json.Unmarshal([]byte(ib.Settings), &parsed); err != nil {
|
||||
t.Fatalf("healed settings not valid json: %v", err)
|
||||
}
|
||||
if _, ok := parsed["secret"]; ok {
|
||||
t.Fatalf("the vestigial inbound-level secret must be stripped, got %q", ib.Settings)
|
||||
}
|
||||
clients := parsed["clients"].([]any)
|
||||
got := clients[0].(map[string]any)["secret"].(string)
|
||||
if !strings.HasPrefix(got, "ee") || !strings.HasSuffix(got, hex.EncodeToString([]byte("a.com"))) {
|
||||
|
||||
Reference in New Issue
Block a user