Maj sock5 proxy
This commit is contained in:
parent
e6950ea526
commit
a2eac5a595
2 changed files with 80 additions and 19 deletions
|
@ -1,3 +1,4 @@
|
|||
{-# LANGUAGE DeriveAnyClass #-}
|
||||
{-# LANGUAGE DuplicateRecordFields #-}
|
||||
{-# LANGUAGE NoImplicitPrelude #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
|
@ -11,7 +12,14 @@ module Socks5 where
|
|||
import ClassyPrelude
|
||||
import Data.Binary
|
||||
import Data.Binary.Get
|
||||
import Network.Socket (HostName, PortNumber)
|
||||
import Data.Binary.Put
|
||||
import qualified Data.ByteString as BC
|
||||
import qualified Data.ByteString.Char8 as BC8
|
||||
import Data.Either
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.Encoding as E
|
||||
import Network.Socket (HostName, PortNumber)
|
||||
import Numeric (showHex)
|
||||
|
||||
data AuthMethod = NoAuth
|
||||
| GSSAPI
|
||||
|
@ -47,19 +55,19 @@ instance Binary RequestAuth where
|
|||
put RequestAuth{..} = do
|
||||
putWord8 (fromIntegral version)
|
||||
putWord8 (fromIntegral $ length methods)
|
||||
sequence_ ( put <$> methods)
|
||||
sequence_ (put <$> methods)
|
||||
-- Check length <= 255
|
||||
|
||||
get = do
|
||||
version <- fromIntegral <$> getWord8
|
||||
guard (version == 0x05)
|
||||
nbMethods <- fromIntegral <$> getWord8
|
||||
guard (version <= 0xFF)
|
||||
guard (nbMethods > 0 && nbMethods <= 0xFF)
|
||||
methods <- replicateM nbMethods get
|
||||
return $ RequestAuth version methods
|
||||
|
||||
|
||||
|
||||
|
||||
data Request = Request
|
||||
{ version :: Int
|
||||
, command :: Command
|
||||
|
@ -70,9 +78,59 @@ data Request = Request
|
|||
data Command = Connect
|
||||
| Bind
|
||||
| UdpAssociate
|
||||
deriving (Show, Eq)
|
||||
deriving (Show, Eq, Enum, Bounded)
|
||||
|
||||
|
||||
instance Binary Command where
|
||||
put = putWord8 . (+1) . fromIntegral . fromEnum
|
||||
|
||||
get = do
|
||||
cmd <- (\val -> fromIntegral val - 1) <$> getWord8
|
||||
guard $ cmd >= fromEnum (minBound :: Command) && cmd <= fromEnum (maxBound :: Command)
|
||||
|
||||
return .toEnum $ cmd
|
||||
|
||||
|
||||
instance Binary Request where
|
||||
put Request{..} = do
|
||||
putWord8 (fromIntegral version)
|
||||
put command
|
||||
putWord8 0x00 -- RESERVED
|
||||
putWord8 0x03 -- DOMAINNAME
|
||||
let host = BC8.pack addr
|
||||
putWord8 (fromIntegral . length $ host)
|
||||
traverse_ put host
|
||||
putWord16be (fromIntegral port)
|
||||
|
||||
|
||||
|
||||
get = do
|
||||
version <- fromIntegral <$> getWord8
|
||||
guard (version == 5)
|
||||
cmd <- get :: Get Command
|
||||
_ <- getWord8 -- RESERVED
|
||||
|
||||
opCode <- fromIntegral <$> getWord8 -- DOMAINNAME
|
||||
guard (opCode == 0x03)
|
||||
|
||||
length <- fromIntegral <$> getWord8
|
||||
host <- either (const T.empty) id . E.decodeUtf8' <$> replicateM length getWord8
|
||||
guard (not $ null host)
|
||||
|
||||
port <- fromIntegral <$> getWord16be
|
||||
|
||||
return Request
|
||||
{ version = version
|
||||
, command = cmd
|
||||
, addr = unpack host
|
||||
, port = port
|
||||
}
|
||||
|
||||
|
||||
|
||||
toHex :: LByteString -> String
|
||||
toHex = foldr showHex "" . unpack
|
||||
|
||||
data Response = Response
|
||||
{ version :: Int
|
||||
, returnCode :: RetCode
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue