lib: parse bracketed IPv6 server addresses (#1807)

* Parse bracketed IPv6 server hosts

* lib: parse service-scheme and invitation hosts via TransportHost

* correct encoding

* encoding

---------

Co-authored-by: Paul Bottinelli <paul.bottinelli@trailofbits.com>
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
This commit is contained in:
sh
2026-06-21 12:18:34 +01:00
committed by GitHub
co-authored by Paul Bottinelli Evgeny Poberezkin
parent 958de3bfca
commit 74a86043cc
7 changed files with 145 additions and 9 deletions
+11 -5
View File
@@ -11,8 +11,9 @@ import Control.Applicative ((<|>))
import qualified Data.Attoparsec.ByteString.Char8 as A
import qualified Data.ByteString.Char8 as B
import Data.Functor (($>))
import Network.Socket (HostName, ServiceName)
import Network.Socket (ServiceName)
import Simplex.Messaging.Encoding.String (StrEncoding (..))
import Simplex.Messaging.Transport.Client (TransportHost (..))
data ServiceScheme = SSSimplex | SSAppServer SrvLoc
deriving (Eq, Show)
@@ -25,14 +26,19 @@ instance StrEncoding ServiceScheme where
"simplex:" $> SSSimplex
<|> "https://" *> (SSAppServer <$> strP)
data SrvLoc = SrvLoc HostName ServiceName
data SrvLoc = SrvLoc TransportHost ServiceName
deriving (Eq, Ord, Show)
instance StrEncoding SrvLoc where
strEncode (SrvLoc host port) = B.pack $ host <> if null port then "" else ':' : port
strP = SrvLoc <$> host <*> (port <|> pure "")
strEncode (SrvLoc host port)
| null port = strEncode host
| otherwise = h <> B.pack (':' : port)
where
h = case host of
THIPv6 _ -> ('[' `B.cons` strEncode host) `B.snoc` ']'
_ -> strEncode host
strP = SrvLoc <$> strP <*> (port <|> pure "")
where
host = B.unpack <$> A.takeWhile1 (A.notInClass ":#,;/ ")
port = show <$> (A.char ':' *> (A.decimal :: A.Parser Int))
simplexChat :: ServiceScheme
+1 -1
View File
@@ -89,7 +89,7 @@ instance StrEncoding TransportHost where
[ THIPv4 <$> ((,,,) <$> ipNum <*> ipNum <*> ipNum <*> A.decimal),
maybe (Left "bad IPv6") (Right . THIPv6 . fromIPv6w) . readMaybe . B.unpack <$?> ipv6StrP,
THOnionHost <$> ((<>) <$> A.takeWhile (\c -> isAsciiLower c || isDigit c) <*> A.string ".onion"),
THDomainName . B.unpack <$> (notOnion <$?> A.takeWhile1 (A.notInClass ":#,;/ \n\r\t"))
THDomainName . B.unpack <$> (notOnion <$?> A.takeWhile1 (A.notInClass ":#,;/ \n\r\t[]"))
]
where
ipNum = validIP <$?> (A.decimal <* A.char '.')
+1 -1
View File
@@ -81,7 +81,7 @@ instance StrEncoding RCInvitation where
_ <- A.string "xrcp:/"
ca <- strP
_ <- A.char '@'
host <- A.takeWhile (/= ':') >>= either fail pure . strDecode . urlDecode True
host <- strP
_ <- A.char ':'
port <- strP
_ <- A.string "#/?"