Add support for socks5 ipv4
Former-commit-id: 93f444c7554b05a247beb3cef3f9e9e67dbdf04e Former-commit-id: 9f48bc09d61b4b0723553ad7635382570dd8568a [formerly 726f62c02f451aa3d3bce2d43f82fb89ac57df6f] [formerly ecc452136b37f5387b8328f0a067ef14d3ae20ea [formerly a198098e9a56b46b7e699f43287c479bc80c7dc1 [formerly a198098e9a56b46b7e699f43287c479bc80c7dc1 [formerly a198098e9a56b46b7e699f43287c479bc80c7dc1 [formerly c42827e3842267f52c65419a91c91672294d8e60]]]]] Former-commit-id: 7302ac40185825650c63dbbbb7746fa628ec7aea [formerly 2f2dbaf7687a712ecf7efe02c937c667bccce360] Former-commit-id: dca93f1ee79fbf5a7243fc664c3e71b9ffeedfdd Former-commit-id: 01939d01a83faea0e336403371fdcfbcf668694c Former-commit-id: d3f7507bdee393f93c79fba6aac49fa68d6788cc Former-commit-id: 7715e5d09783415843b188584ff4f339171bb266 [formerly c2fe751fae043fca4df6a3bbe0fcf790feaa3115] Former-commit-id: 57ea26c8efe39e0f025b806af4607edd1bc928f4
This commit is contained in:
parent
395411a4b7
commit
23051c7982
3 changed files with 43 additions and 15 deletions
|
@ -133,7 +133,7 @@ runSocks5Server socksSettings@Socks5.ServerSettings{..} cfg inner = do
|
||||||
-- Get the request and update dynamically the tunnel config
|
-- Get the request and update dynamically the tunnel config
|
||||||
request <- decode . fromStrict <$> N.appRead cnx :: IO Socks5.Request
|
request <- decode . fromStrict <$> N.appRead cnx :: IO Socks5.Request
|
||||||
debug $ "Socks5 forward request " <> show request
|
debug $ "Socks5 forward request " <> show request
|
||||||
let responseRequest = encode $ Socks5.Response (fromIntegral Socks5.socksVersion) Socks5.SUCCEEDED (Socks5.addr request) (Socks5.port request)
|
let responseRequest = encode $ Socks5.Response (fromIntegral Socks5.socksVersion) Socks5.SUCCEEDED (Socks5.addr request) (Socks5.port request) (Socks5.addrType request)
|
||||||
let cfg' = cfg { destHost = Socks5.addr request, destPort = Socks5.port request }
|
let cfg' = cfg { destHost = Socks5.addr request, destPort = Socks5.port request }
|
||||||
N.appWrite cnx (toStrict responseRequest)
|
N.appWrite cnx (toStrict responseRequest)
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,9 @@ import qualified Data.ByteString as BC
|
||||||
import qualified Data.ByteString.Char8 as BC8
|
import qualified Data.ByteString.Char8 as BC8
|
||||||
import Data.Either
|
import Data.Either
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
|
import qualified Data.Text.Read as T
|
||||||
import qualified Data.Text.Encoding as E
|
import qualified Data.Text.Encoding as E
|
||||||
import Network.Socket (HostAddress, HostName, PortNumber)
|
import Network.Socket (HostName, PortNumber)
|
||||||
import Numeric (showHex)
|
import Numeric (showHex)
|
||||||
|
|
||||||
import Control.Monad.Except (MonadError)
|
import Control.Monad.Except (MonadError)
|
||||||
|
@ -34,6 +35,10 @@ data AuthMethod = NoAuth
|
||||||
| NotAllowed
|
| NotAllowed
|
||||||
deriving (Show, Read)
|
deriving (Show, Read)
|
||||||
|
|
||||||
|
data AddressType = DOMAIN_NAME
|
||||||
|
| IPv4
|
||||||
|
deriving (Show, Read, Eq)
|
||||||
|
|
||||||
data RequestAuth = RequestAuth
|
data RequestAuth = RequestAuth
|
||||||
{ version :: Int
|
{ version :: Int
|
||||||
, methods :: Vector AuthMethod
|
, methods :: Vector AuthMethod
|
||||||
|
@ -90,6 +95,7 @@ data Request = Request
|
||||||
, command :: Command
|
, command :: Command
|
||||||
, addr :: HostName
|
, addr :: HostName
|
||||||
, port :: PortNumber
|
, port :: PortNumber
|
||||||
|
, addrType :: AddressType
|
||||||
} deriving (Show)
|
} deriving (Show)
|
||||||
|
|
||||||
data Command = Connect
|
data Command = Connect
|
||||||
|
@ -113,10 +119,17 @@ instance Binary Request where
|
||||||
putWord8 (fromIntegral version)
|
putWord8 (fromIntegral version)
|
||||||
put command
|
put command
|
||||||
putWord8 0x00 -- RESERVED
|
putWord8 0x00 -- RESERVED
|
||||||
putWord8 0x03 -- DOMAINNAME
|
_ <- if addrType == DOMAIN_NAME
|
||||||
|
then do
|
||||||
|
putWord8 0x03
|
||||||
let host = BC8.pack addr
|
let host = BC8.pack addr
|
||||||
putWord8 (fromIntegral . length $ host)
|
putWord8 (fromIntegral . length $ host)
|
||||||
traverse_ put host
|
traverse_ put host
|
||||||
|
else do
|
||||||
|
putWord8 0x01
|
||||||
|
let ipv4 = fst . Data.Either.fromRight (0, mempty) . T.decimal . T.pack <$> splitElem '.' addr
|
||||||
|
traverse_ putWord8 ipv4
|
||||||
|
|
||||||
putWord16be (fromIntegral port)
|
putWord16be (fromIntegral port)
|
||||||
|
|
||||||
|
|
||||||
|
@ -147,6 +160,7 @@ instance Binary Request where
|
||||||
, command = cmd
|
, command = cmd
|
||||||
, addr = unpack host
|
, addr = unpack host
|
||||||
, port = port
|
, port = port
|
||||||
|
, addrType = if opCode == 0x03 then DOMAIN_NAME else IPv4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -159,6 +173,7 @@ data Response = Response
|
||||||
, returnCode :: RetCode
|
, returnCode :: RetCode
|
||||||
, serverAddr :: HostName
|
, serverAddr :: HostName
|
||||||
, serverPort :: PortNumber
|
, serverPort :: PortNumber
|
||||||
|
, serverAddrType :: AddressType
|
||||||
} deriving (Show)
|
} deriving (Show)
|
||||||
|
|
||||||
data RetCode = SUCCEEDED
|
data RetCode = SUCCEEDED
|
||||||
|
@ -183,10 +198,17 @@ instance Binary Response where
|
||||||
putWord8 socksVersion
|
putWord8 socksVersion
|
||||||
put returnCode
|
put returnCode
|
||||||
putWord8 0x00 -- Reserved
|
putWord8 0x00 -- Reserved
|
||||||
putWord8 0x03 -- DOMAINNAME
|
_ <- if serverAddrType == DOMAIN_NAME
|
||||||
|
then do
|
||||||
|
putWord8 0x03
|
||||||
let host = BC8.pack serverAddr
|
let host = BC8.pack serverAddr
|
||||||
putWord8 (fromIntegral . length $ host)
|
putWord8 (fromIntegral . length $ host)
|
||||||
traverse_ put host
|
traverse_ put host
|
||||||
|
else do
|
||||||
|
putWord8 0x01
|
||||||
|
let ipv4 = fst . Data.Either.fromRight (0, mempty) . T.decimal . T.pack <$> splitElem '.' serverAddr
|
||||||
|
traverse_ putWord8 ipv4
|
||||||
|
|
||||||
putWord16be (fromIntegral serverPort)
|
putWord16be (fromIntegral serverPort)
|
||||||
|
|
||||||
|
|
||||||
|
@ -196,11 +218,16 @@ instance Binary Response where
|
||||||
ret <- toEnum . min maxBound . fromIntegral <$> getWord8
|
ret <- toEnum . min maxBound . fromIntegral <$> getWord8
|
||||||
getWord8 -- RESERVED
|
getWord8 -- RESERVED
|
||||||
opCode <- fromIntegral <$> getWord8 -- Type
|
opCode <- fromIntegral <$> getWord8 -- Type
|
||||||
guard(opCode == 0x03)
|
guard(opCode == 0x03 || opCode == 0x01)
|
||||||
|
host <- if opCode == 0x03
|
||||||
|
then do
|
||||||
length <- fromIntegral <$> getWord8
|
length <- fromIntegral <$> getWord8
|
||||||
host <- fromRight T.empty . E.decodeUtf8' <$> replicateM length getWord8
|
fromRight T.empty . E.decodeUtf8' <$> replicateM length getWord8
|
||||||
|
else do
|
||||||
|
ipv4 <- replicateM 4 getWord8 :: Get [Word8]
|
||||||
|
let ipv4Str = T.intercalate "." $ fmap (tshow . fromEnum) ipv4
|
||||||
|
return ipv4Str
|
||||||
guard (not $ null host)
|
guard (not $ null host)
|
||||||
|
|
||||||
port <- getWord16be
|
port <- getWord16be
|
||||||
|
|
||||||
return Response
|
return Response
|
||||||
|
@ -208,6 +235,7 @@ instance Binary Response where
|
||||||
, returnCode = ret
|
, returnCode = ret
|
||||||
, serverAddr = unpack host
|
, serverAddr = unpack host
|
||||||
, serverPort = fromIntegral port
|
, serverPort = fromIntegral port
|
||||||
|
, serverAddrType = if opCode == 0x03 then DOMAIN_NAME else IPv4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -208,7 +208,7 @@ testSocks5Tunneling useTLS = do
|
||||||
rrunTCPClient (N.clientSettingsTCP (fromIntegral 8081) "localhost") $ \cnx -> do
|
rrunTCPClient (N.clientSettingsTCP (fromIntegral 8081) "localhost") $ \cnx -> do
|
||||||
write cnx (toStrict . encode $ Socks5.RequestAuth (fromIntegral Socks5.socksVersion) (fromList [Socks5.NoAuth]))
|
write cnx (toStrict . encode $ Socks5.RequestAuth (fromIntegral Socks5.socksVersion) (fromList [Socks5.NoAuth]))
|
||||||
_ <- read cnx
|
_ <- read cnx
|
||||||
write cnx (toStrict . encode $ Socks5.Request (fromIntegral Socks5.socksVersion) Socks5.Connect "localhost" 8082)
|
write cnx (toStrict . encode $ Socks5.Request (fromIntegral Socks5.socksVersion) Socks5.Connect "localhost" 8082 Socks5.DOMAIN_NAME)
|
||||||
_ <- read cnx
|
_ <- read cnx
|
||||||
write cnx needle
|
write cnx needle
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue