connector: hex-decode mtproxy secret
Go / Lint (old) (push) Failing after 5m14s
Go / Lint (latest) (push) Failing after 5m19s
Go / Lint (old) (pull_request) Failing after 5m14s
Go / Lint (latest) (pull_request) Failing after 4m40s

dcs.MTProxy expects raw secret bytes. Carrying them verbatim through a
YAML string field is impossible: real secrets contain bytes >= 0x80
(faketls starts with 0xee, secured with 0xdd) which cannot survive a
unicode string round-trip, so the value reached the bridge corrupted or
empty (gotd then logged "invalid secret").

Accept the standard hex form printed by mtg/MTProxy tooling
(e.g. "ee" + 16-byte secret + cloak domain hex) and decode it before
handing the bytes to gotd.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Igor Artamonov
2026-05-01 10:14:58 +03:00
parent e3bb26aee1
commit b00e2d8955
3 changed files with 62 additions and 1 deletions
+23 -1
View File
@@ -17,13 +17,31 @@
package connector
import (
"encoding/hex"
"fmt"
"strings"
"golang.org/x/net/proxy"
"go.mau.fi/mautrix-telegram/pkg/gotd/telegram/dcs"
)
// decodeMTProxySecret parses an MTProxy secret string into raw bytes.
// MTProxy secrets are binary (faketls secrets begin with 0xEE, secured with 0xDD)
// and cannot be carried verbatim in a YAML string field, so we accept the standard
// hex encoding (optionally prefixed with "ee"/"dd") used by mtg/MTProxy tooling.
func decodeMTProxySecret(s string) ([]byte, error) {
s = strings.TrimSpace(s)
if s == "" {
return nil, fmt.Errorf("mtproxy secret is empty")
}
b, err := hex.DecodeString(s)
if err != nil {
return nil, fmt.Errorf("mtproxy secret must be hex-encoded: %w", err)
}
return b, nil
}
func GetProxyDialFunc(cfg ProxyConfig) (dcs.DialFunc, error) {
switch cfg.Type {
// we can't proxy HTTP through mtproxy
@@ -54,7 +72,11 @@ func GetProxyResolver(cfg ProxyConfig) (dcs.Resolver, error) {
resolver := dcs.Plain(dcs.PlainOptions{Dial: dialer})
return resolver, nil
case "mtproxy":
return dcs.MTProxy(cfg.Address, []byte(cfg.Password), dcs.MTProxyOptions{})
secret, err := decodeMTProxySecret(cfg.Password)
if err != nil {
return nil, err
}
return dcs.MTProxy(cfg.Address, secret, dcs.MTProxyOptions{})
default:
return nil, fmt.Errorf("unsupported proxy type %s", cfg.Type)
}