mirror of
https://github.com/simplex-chat/simplexmq.git
synced 2026-07-02 22:12:21 +00:00
smp-server: hardcode TldRegistries (drop registry_tld_* INI keys)
This commit is contained in:
@@ -1465,15 +1465,13 @@ rslv = %s"RSLV" SP json-bytes ; json-bytes consumes the remainder of the trans
|
||||
|
||||
**Server-side validation.** The names router parses `name` as a fully-qualified
|
||||
domain (TLD required — bare labels are rejected), extracts the TLD, and looks
|
||||
up the expected SNRC contract address in its INI whitelist
|
||||
(`registry_tld_simplex`, `registry_tld_testing`, `registry_tld_all`).
|
||||
`registry_tld_all` is the catch-all used when no TLD-specific entry matches
|
||||
the requested TLD (and the only entry that can resolve web domains). If no
|
||||
whitelist entry matches the TLD, or if the client-supplied `contract` differs
|
||||
from the configured address, the server replies with `ERR AUTH` without
|
||||
contacting the chain. This lets one names router safely host multiple TLDs
|
||||
(each backed by its own SNRC contract) and reject clients pointing at a
|
||||
contract the operator doesn't run.
|
||||
up the expected SNRC contract address in a whitelist hardcoded in the server
|
||||
binary (TLD-specific addresses with an optional catch-all for unspecified
|
||||
TLDs and web domains). If no whitelist entry matches the TLD, or if the
|
||||
client-supplied `contract` differs from the configured address, the server
|
||||
replies with `ERR AUTH` without contacting the chain. This lets one names
|
||||
router safely host multiple TLDs (each backed by its own SNRC contract) and
|
||||
reject clients pointing at a contract the operator doesn't run.
|
||||
|
||||
The names router responds with either a `NAME` response carrying the resolved
|
||||
record, or `ERR AUTH` collapsing every failure mode (name not found, malformed
|
||||
|
||||
@@ -754,7 +754,7 @@ instance J.ToJSON NameOwner where
|
||||
|
||||
instance J.FromJSON NameOwner where
|
||||
parseJSON = J.withText "NameOwner" $ \t -> do
|
||||
-- Accept "0x" and "0X" prefixes (matches Server/Main.hs:parseEthAddr via fromHex).
|
||||
-- Accept "0x" and "0X" prefixes (matches the Server-side hex decoder).
|
||||
let hex = fromMaybe t (T.stripPrefix "0x" t <|> T.stripPrefix "0X" t)
|
||||
case BAE.convertFromBase BAE.Base16 (encodeUtf8 hex) of
|
||||
Left e -> fail e
|
||||
|
||||
@@ -77,9 +77,8 @@ import Simplex.Messaging.Server.Web (EmbeddedWebParams (..), WebHttpsParams (..)
|
||||
import Simplex.Messaging.Server.MsgStore.Journal (JournalMsgStore (..), QStoreCfg (..), stmQueueStore)
|
||||
import Simplex.Messaging.Server.MsgStore.Types (MsgStoreClass (..), SQSType (..), SMSType (..), newMsgStore)
|
||||
import Network.URI (URI (..), URIAuth (..), parseAbsoluteURI)
|
||||
import Simplex.Messaging.Protocol (mkNameOwner, NameOwner)
|
||||
import Simplex.Messaging.Protocol (mkNameOwner)
|
||||
import Simplex.Messaging.Server.Names (NamesConfig (..), RpcAuth (..), TldRegistries (..))
|
||||
import Simplex.Messaging.Server.Names.Eth.RPC (fromHex)
|
||||
import Simplex.Messaging.Server.QueueStore.Postgres.Config
|
||||
import Simplex.Messaging.Server.StoreLog.ReadWrite (readQueueStore)
|
||||
import Simplex.Messaging.Transport (supportedProxyClientSMPRelayVRange, alpnSupportedSMPHandshakes, supportedServerSMPRelayVRange)
|
||||
@@ -807,11 +806,10 @@ readNamesConfig ini
|
||||
| otherwise =
|
||||
let rpcAuth_ = either (error . ("[NAMES] rpc_auth: " <>)) Just . parseRpcAuth =<< eitherToMaybe (lookupValue "NAMES" "rpc_auth" ini)
|
||||
endpoint = requiredText "ethereum_endpoint"
|
||||
registries = readTldRegistries
|
||||
in Just
|
||||
NamesConfig
|
||||
{ ethereumEndpoint = either (error . ("[NAMES] ethereum_endpoint: " <>)) id (validateUrl endpoint rpcAuth_),
|
||||
tldRegistries = registries,
|
||||
tldRegistries = hardcodedTldRegistries,
|
||||
rpcAuth = rpcAuth_,
|
||||
rpcTimeoutMs = boundedIniInt 3000 100 60000 "rpc_timeout_ms",
|
||||
rpcMaxResponseBytes = boundedIniInt 262144 1024 16777216 "rpc_max_response_bytes",
|
||||
@@ -833,18 +831,22 @@ readNamesConfig ini
|
||||
n | n >= floor_ && n <= ceiling_ -> n
|
||||
| otherwise ->
|
||||
error $ "[NAMES] " <> T.unpack key <> " must be in [" <> show floor_ <> ".." <> show ceiling_ <> "] (got " <> show n <> ")"
|
||||
readTldRegistries =
|
||||
let regs = TldRegistries
|
||||
{ tldSimplex = optionalAddr "registry_tld_simplex",
|
||||
tldTesting = optionalAddr "registry_tld_testing",
|
||||
tldAll = optionalAddr "registry_tld_all"
|
||||
}
|
||||
in case (tldSimplex regs, tldTesting regs, tldAll regs) of
|
||||
(Nothing, Nothing, Nothing) ->
|
||||
error "[NAMES] at least one of registry_tld_simplex, registry_tld_testing, registry_tld_all is required"
|
||||
_ -> regs
|
||||
optionalAddr key =
|
||||
either (error . (("[NAMES] " <> T.unpack key <> ": ") <>)) Just . parseEthAddr =<< eitherToMaybe (lookupValue "NAMES" key ini)
|
||||
|
||||
-- | Hardcoded SNRC contract whitelist. Placeholder addresses until the
|
||||
-- launch contracts are deployed; replaced in code rather than INI so
|
||||
-- operators can't accidentally point a names router at the wrong contract
|
||||
-- during the bootstrap phase. The TldRegistries shape + lookup precedence
|
||||
-- (TLD-specific then `tldAll` catch-all) is unchanged from the previous
|
||||
-- INI-driven form.
|
||||
hardcodedTldRegistries :: TldRegistries
|
||||
hardcodedTldRegistries =
|
||||
TldRegistries
|
||||
{ tldSimplex = Just (placeholderAddr '\x11'),
|
||||
tldTesting = Just (placeholderAddr '\x22'),
|
||||
tldAll = Nothing
|
||||
}
|
||||
where
|
||||
placeholderAddr c = either error id $ mkNameOwner (B.replicate 20 c)
|
||||
|
||||
-- | Validate the ethereum_endpoint URL:
|
||||
-- * scheme must be http: or https:
|
||||
@@ -913,15 +915,6 @@ validateUrl url auth_ = do
|
||||
'0' : 'x' : rest -> all isHexDigit rest
|
||||
lh -> not (null lh) && all isDigit lh
|
||||
|
||||
-- | Parse a 20-byte Ethereum address as text "0x[hex40]" or "[hex40]".
|
||||
-- EIP-55 mixed-case checksum verification is a follow-up.
|
||||
parseEthAddr :: Text -> Either String NameOwner
|
||||
parseEthAddr t = do
|
||||
bs <- fromHex (encodeUtf8 t)
|
||||
if B.length bs == 20
|
||||
then mkNameOwner bs
|
||||
else Left "expected a 20-byte address (40 hex characters, optionally 0x-prefixed)"
|
||||
|
||||
-- | Parse an rpc_auth INI value. Scheme keyword is case-insensitive so
|
||||
-- "Bearer <token>" / "BEARER <token>" (Caddy / RFC 7235 convention) work
|
||||
-- as well as the lowercase form.
|
||||
|
||||
@@ -168,14 +168,9 @@ iniFileContent cfgPath logPath opts host basicAuth controlPortPwds =
|
||||
\# Central Reth via Caddy:\n\
|
||||
\# ethereum_endpoint: https://eth.simplex.chat:443\n\
|
||||
\# rpc_auth: basic <username>:<password>\n\
|
||||
\# Per-TLD SNRC contract whitelist. At least one entry must be set.\n\
|
||||
\# Each RSLV carries the contract address the client wants queried;\n\
|
||||
\# the server only accepts it if it matches the address configured for\n\
|
||||
\# that TLD (or registry_tld_all as catch-all for any unspecified TLD,\n\
|
||||
\# including web domains).\n\
|
||||
\# registry_tld_simplex: 0x<paste-your-contract-address>\n\
|
||||
\# registry_tld_testing: 0x<paste-your-contract-address>\n\
|
||||
\# registry_tld_all: 0x<paste-your-contract-address>\n\
|
||||
\# The SNRC contract addresses are hardcoded in the server binary; each\n\
|
||||
\# RSLV's contract field is verified against the binary's whitelist for\n\
|
||||
\# the requested TLD. Operators do NOT configure registries here.\n\
|
||||
\# rpc_timeout_ms: 3000\n\
|
||||
\# rpc_max_response_bytes: 262144\n\
|
||||
\# rpc_max_concurrency: 8\n\n\
|
||||
|
||||
Reference in New Issue
Block a user