moesocks 0.1.0.19 → 0.1.0.20
raw patch · 10 files changed
+268/−252 lines, 10 files
Files
- CHANGELOG.md +4/−0
- moesocks.cabal +4/−4
- src/Network/MoeSocks/App.hs +14/−15
- src/Network/MoeSocks/Common.hs +2/−9
- src/Network/MoeSocks/Encrypt.hs +140/−0
- src/Network/MoeSocks/Helper.hs +11/−8
- src/Network/MoeSocks/Internal/ShadowSocks/Encrypt.hs +0/−166
- src/Network/MoeSocks/TCP.hs +42/−27
- src/Network/MoeSocks/Type.hs +17/−3
- src/Network/MoeSocks/UDP.hs +34/−20
CHANGELOG.md view
@@ -1,3 +1,7 @@+0.1.0.20+--------+* Rewrite Encrypt module, cache password hash+ 0.1.0.19 -------- * Fix a memory leak
moesocks.cabal view
@@ -1,6 +1,6 @@ name: moesocks category: Network-version: 0.1.0.19+version: 0.1.0.20 license: Apache-2.0 synopsis: A functional firewall killer description: A socks5 proxy using the client / server architecture.@@ -54,13 +54,13 @@ other-modules: Network.MoeSocks.App Network.MoeSocks.BuilderAndParser+ Network.MoeSocks.Common Network.MoeSocks.Config Network.MoeSocks.Constant Network.MoeSocks.Helper- Network.MoeSocks.Internal.ShadowSocks.Encrypt Network.MoeSocks.Options- Network.MoeSocks.Type- Network.MoeSocks.Common Network.MoeSocks.TCP+ Network.MoeSocks.Type Network.MoeSocks.UDP+ Network.MoeSocks.Encrypt
src/Network/MoeSocks/App.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE LambdaCase #-} module Network.MoeSocks.App where @@ -20,10 +21,9 @@ import Network.MoeSocks.TCP import Network.MoeSocks.Type import Network.MoeSocks.UDP+import Network.MoeSocks.Encrypt (initBuilder) import Network.Socket hiding (send, recv, recvFrom, sendTo) import Network.Socket.ByteString-import OpenSSL (withOpenSSL)-import OpenSSL.EVP.Cipher (getCipherByName) import Prelude hiding ((-), take) import System.Log.Formatter import System.Log.Handler.Simple@@ -176,15 +176,12 @@ _config <- parseConfig - _options let _c = _config - let _method = _config ^. method . _Text-- when (_method /= "none") - do- _cipher <- io - withOpenSSL - getCipherByName _method+ let _method = _config ^. method - case _cipher of- Nothing -> throwError - "Invalid method '" - <> _method- Just _ -> pure ()+ _cipherBox <- (io - initBuilder _method (_config ^. password)) >>= \case+ Nothing -> throwError - "Invalid method '" + <> _method ^. _Text+ Just (a, b, c, d) -> pure - CipherBox a b c d let localAppBuilder :: AppType -> String -> (ByteString -> (Socket, SockAddr) -> IO ()) -> @@ -229,7 +226,7 @@ let localSocks5App :: (Socket, SockAddr) -> IO () localSocks5App = localAppBuilder TCP_App "socks5" - - local_Socks5_RequestHandler _config+ local_Socks5_RequestHandler _cipherBox _config showForwarding :: Forward -> String showForwarding (Forward _localPort _remoteHost _remotePort) =@@ -246,14 +243,16 @@ forward_TCP_App _f _s = do let _m = showForwarding _f localAppBuilder TCP_App ("TCP forwarding " <> _m)- (local_TCP_ForwardRequestHandler _config _f) + (local_TCP_ForwardRequestHandler _cipherBox + _config _f) _s forward_UDP_App :: Forward -> (Socket, SockAddr) -> IO () forward_UDP_App _f _s = do let _m = showForwarding _f localAppBuilder UDP_App ("UDP forwarding " <> _m)- (local_UDP_ForwardRequestHandler _config _f) + (local_UDP_ForwardRequestHandler _cipherBox+ _config _f) _s let remote_TCP_App :: (Socket, SockAddr) -> IO ()@@ -276,7 +275,7 @@ forkIO - catchExceptAsyncLog "R thread" - logSocket "R remote socket" (pure _newSocket) -- remote_TCP_RequestHandler _config + remote_TCP_RequestHandler _cipherBox _config forever - handleRemote _remoteSocket @@ -297,7 +296,7 @@ forkIO - catchExceptAsyncLog "R thread" - - remote_UDP_RequestHandler _config _msg _s+ remote_UDP_RequestHandler _cipherBox _config _msg _s
src/Network/MoeSocks/Common.hs view
@@ -4,24 +4,17 @@ import Control.Lens import Control.Monad.Writer hiding (listen)-import Data.ByteString (ByteString) import Data.Text (Text) import Data.Text.Lens-import Data.Text.Strict.Lens (utf8) import Network.MoeSocks.Helper-import Network.MoeSocks.Internal.ShadowSocks.Encrypt as E import Network.MoeSocks.Type import Network.Socket hiding (send, recv, recvFrom, sendTo) import Prelude hiding ((-), take) import qualified Data.List as L-import qualified Data.Strict as S+import qualified Network.MoeSocks.Encrypt as E -plainCipher :: (S.Maybe ByteString) -> IO ByteString+plainCipher :: Cipher plainCipher = E.plainCipher--getCipher :: Text -> Text -> IO (Cipher, Cipher)-getCipher aMethod aPassword =- getEncDec aMethod (review utf8 aPassword) showAddressType :: AddressType -> Text showAddressType (IPv4_address xs) = view (from _Text) -
+ src/Network/MoeSocks/Encrypt.hs view
@@ -0,0 +1,140 @@+-- Heavily inspired by+-- https://github.com/rnons/shadowsocks-haskell/blob/86bd47d474df6800e1f3706b33ae9e8f80696d8f/Shadowsocks/Encrypt.hs+++{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE LambdaCase #-}++module Network.MoeSocks.Encrypt where++import Control.Lens+import Control.Monad.Except+import Crypto.Hash.MD5 (hash)+import Data.ByteString (ByteString)+import Data.Map+import Data.Monoid ((<>))+import Data.Text (Text)+import Data.Text.Lens+import Data.Text.Strict.Lens (utf8)+import OpenSSL (withOpenSSL)+import OpenSSL.EVP.Cipher (getCipherByName, CryptoMode(..))+import OpenSSL.Random (randBytes)+import Prelude hiding ((-))+import qualified Data.ByteString as S+import qualified Data.Strict as S+import qualified OpenSSL.EVP.Internal as E++-- BEGIN backports++infixr 0 -+(-) :: (a -> b) -> a -> b+(-) = ($)++-- END backports++type KeyLength = Int+type IV_Length = Int++type Cipher = S.Maybe ByteString -> IO ByteString +type CipherBuilder = ByteString -> IO Cipher+type CipherBox = (Int, IO ByteString, CipherBuilder, CipherBuilder)++type MaybeExceptT = ExceptT () IO++methods :: Map Text (KeyLength, IV_Length)+methods = fromList+ [ ("aes-128-cfb", (16, 16))+ , ("aes-192-cfb", (24, 16))+ , ("aes-256-cfb", (32, 16))+ , ("bf-cfb", (16, 8))+ , ("camellia-128-cfb", (16, 16))+ , ("camellia-192-cfb", (24, 16))+ , ("camellia-256-cfb", (32, 16))+ , ("cast5-cfb", (16, 8))+ , ("des-cfb", (8, 8))+ , ("idea-cfb", (16, 8))+ , ("rc2-cfb", (16, 8))+ , ("rc4", (16, 0))+ , ("seed-cfb", (16, 16))+ ]+++hashKey :: ByteString -> Int -> Int -> ByteString+hashKey aPassword aKeyLen a_IV_len = loop mempty mempty + where+ _stopLength = aKeyLen + a_IV_len++ loop :: ByteString -> ByteString -> ByteString+ loop _lastHashedBytes _accumHashedBytes+ | S.length _accumHashedBytes >= _stopLength + = S.take aKeyLen _accumHashedBytes+ | otherwise = let _new = hash - _lastHashedBytes <> aPassword+ in+ loop _new - _accumHashedBytes <> _new+++ssl :: IO a -> IO a+ssl = withOpenSSL++eitherToMaybe :: Either a b -> Maybe b+eitherToMaybe (Left _) = Nothing+eitherToMaybe (Right x) = Just x++getMaybe :: Maybe a -> MaybeExceptT a+getMaybe Nothing = throwError ()+getMaybe (Just x) = pure x++mio :: IO (Maybe a) -> MaybeExceptT a+mio = (>>= getMaybe) . io++io :: (MonadIO m) => IO a -> m a+io = liftIO++plainCipher :: Cipher+plainCipher = pure . S.fromMaybe mempty++initBuilder :: Text -> Text -> IO (Maybe CipherBox)+initBuilder aMethod aPassword + | aMethod == "none" = let constCipher = const - pure plainCipher+ in+ pure - Just (0, pure mempty, constCipher, constCipher)++ | otherwise =+ fmap eitherToMaybe - runExceptT - initBuilder' aMethod aPassword++initBuilder' :: Text -> Text -> MaybeExceptT CipherBox+initBuilder' aMethod aPassword = do+ _method <- mio - ssl - getCipherByName - aMethod ^. _Text++ (_keyLength, _IV_Length) <- getMaybe - methods ^? ix aMethod++ let _hashed = hashKey (review utf8 aPassword) _keyLength _IV_Length+ _IV_Maker = io - ssl - randBytes _IV_Length++ _encryptBuilder :: ByteString -> IO Cipher+ _encryptBuilder _iv = do+ _ctx <- io - ssl - E.cipherInitBS _method _hashed _iv Encrypt++ let _encrypt :: Cipher+ _encrypt = \case+ S.Nothing -> E.cipherFinalBS _ctx+ S.Just _bytes -> do+ ssl - E.cipherUpdateBS _ctx _bytes++ pure _encrypt++ _decryptBuilder :: ByteString -> IO Cipher+ _decryptBuilder _iv = do+ _ctx <- io - ssl - E.cipherInitBS _method _hashed _iv Decrypt++ let _decrypt :: Cipher+ _decrypt = \case+ S.Nothing -> E.cipherFinalBS _ctx+ S.Just _bytes -> do+ ssl - E.cipherUpdateBS _ctx _bytes + + pure _decrypt+ ++ pure - (_IV_Length, _IV_Maker, _encryptBuilder, _decryptBuilder)+
src/Network/MoeSocks/Helper.hs view
@@ -254,16 +254,19 @@ send_ :: Socket -> ByteString -> IO () send_ = sendAll ++sendBytes :: HQueue -> ByteString -> IO ()+sendBytes _queue = atomically . writeTBQueue _queue . S.Just++sendBytesEncrypt :: HQueue -> HCipher -> ByteString -> IO ()+sendBytesEncrypt _queue _cipher x = sendBytes _queue =<< _cipher (S.Just x)+ sendBuilder :: HQueue -> B.Builder -> IO ()-sendBuilder _queue = - atomically . writeTBQueue _queue . S.Just . builder_To_ByteString+sendBuilder _queue = sendBytes _queue . builder_To_ByteString -sendBuilderEncrypted :: HQueue -> - HCipher -> - B.Builder -> IO ()-sendBuilderEncrypted _queue _encrypt x = - atomically . writeTBQueue _queue . S.Just =<< - _encrypt (S.Just - builder_To_ByteString x)+sendBuilderEncrypt :: HQueue -> HCipher -> B.Builder -> IO ()+sendBuilderEncrypt _queue _encrypt = + sendBytesEncrypt _queue _encrypt . builder_To_ByteString -- | An exception raised when parsing fails. data ParseException = ParseException String
− src/Network/MoeSocks/Internal/ShadowSocks/Encrypt.hs
@@ -1,166 +0,0 @@-{- Original file from the shadowsocks package hosted on Hackage:- - https://hackage.haskell.org/package/shadowsocks- - Copyright: rnons- - Licence: MIT- - Heavily modified here- -}---{- -The MIT License (MIT)--Copyright (c) 2014 rnons--Permission is hereby granted, free of charge, to any person obtaining a copy-of this software and associated documentation files (the "Software"), to deal-in the Software without restriction, including without limitation the rights-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell-copies of the Software, and to permit persons to whom the Software is-furnished to do so, subject to the following conditions:--The above copyright notice and this permission notice shall be included in all-copies or substantial portions of the Software.--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE-SOFTWARE.--}----{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE LambdaCase #-}--module Network.MoeSocks.Internal.ShadowSocks.Encrypt- ( getEncDec- , iv_len- , plainCipher- ) where--import Control.Concurrent.MVar ( newEmptyMVar, isEmptyMVar- , putMVar, readMVar)-import Crypto.Hash.MD5 (hash)-import Data.ByteString (ByteString)-import qualified Data.ByteString as S-import qualified Data.HashMap.Strict as HM-import Data.Maybe (fromJust)-import Data.Monoid ((<>))-import OpenSSL (withOpenSSL)-import OpenSSL.EVP.Cipher (getCipherByName, CryptoMode(..))-import OpenSSL.EVP.Internal (cipherInitBS, cipherUpdateBS,- cipherFinalBS)-import OpenSSL.Random (randBytes)-import Data.Text (Text)-import Control.Lens-import Data.Text.Lens-import qualified Data.Strict as S---method_supported :: HM.HashMap Text (Int, Int)-method_supported = HM.fromList- [ ("aes-128-cfb", (16, 16))- , ("aes-192-cfb", (24, 16))- , ("aes-256-cfb", (32, 16))- , ("bf-cfb", (16, 8))- , ("camellia-128-cfb", (16, 16))- , ("camellia-192-cfb", (24, 16))- , ("camellia-256-cfb", (32, 16))- , ("cast5-cfb", (16, 8))- , ("des-cfb", (8, 8))- , ("idea-cfb", (16, 8))- , ("rc2-cfb", (16, 8))- , ("rc4", (16, 0))- , ("seed-cfb", (16, 16))- ]--iv_len :: Text -> Int-iv_len method = m1- where- (_, m1) = method_supported HM.! method--evpBytesToKey :: ByteString -> Int -> Int -> (ByteString, ByteString)-evpBytesToKey password keyLen ivLen =- let ms' = S.concat $ ms 0 []- key = S.take keyLen ms'- iv = S.take ivLen $ S.drop keyLen ms'- in (key, iv)- where- ms :: Int -> [ByteString] -> [ByteString]- ms 0 _ = ms 1 [hash password]- ms i m- | S.length (S.concat m) < keyLen + ivLen =- ms (i+1) (m ++ [hash (last m <> password)])- | otherwise = m--getSSLEncDec :: Text -> ByteString- -> IO (S.Maybe ByteString -> IO ByteString- , S.Maybe ByteString -> IO ByteString)-getSSLEncDec method password = do- let (m0, m1) = fromJust $ HM.lookup method method_supported- random_iv <- withOpenSSL $ randBytes 32- let cipher_iv = S.take m1 random_iv- let (key, _) = evpBytesToKey password m0 m1- cipherCtx <- newEmptyMVar- decipherCtx <- newEmptyMVar-- cipherMethod <- fmap fromJust $ withOpenSSL $ getCipherByName $ - method ^. _Text- ctx <- withOpenSSL $ cipherInitBS cipherMethod key cipher_iv Encrypt- let- encrypt :: (S.Maybe ByteString) -> IO ByteString- encrypt = \case- S.Nothing -> cipherFinalBS ctx- S.Just buf -> do- if S.null buf- then return $! mempty- else do- empty <- isEmptyMVar cipherCtx- if empty- then do- putMVar cipherCtx $! ()- ciphered <- withOpenSSL $ cipherUpdateBS ctx buf- return $! cipher_iv <> ciphered- else do- r <- withOpenSSL $ cipherUpdateBS ctx buf- return $! r-- decrypt :: (S.Maybe ByteString) -> IO ByteString- decrypt = \case- S.Nothing -> cipherFinalBS ctx- S.Just buf -> do - if S.null buf- then return $! S.empty- else do- empty <- isEmptyMVar decipherCtx- if empty- then do- let decipher_iv = S.take m1 buf- dctx <- withOpenSSL $ - cipherInitBS cipherMethod key decipher_iv Decrypt- putMVar decipherCtx $! dctx- if S.null (S.drop m1 buf)- then return ""- else do- r <- withOpenSSL $- cipherUpdateBS dctx (S.drop m1 buf)- return $! r- else do- dctx <- readMVar decipherCtx- r <- withOpenSSL $ cipherUpdateBS dctx buf- return $! r-- return (encrypt, decrypt)--plainCipher :: (S.Maybe ByteString -> IO ByteString)-plainCipher = pure . S.fromMaybe mempty--getEncDec :: Text -> ByteString - -> IO (S.Maybe ByteString -> IO ByteString- , S.Maybe ByteString -> IO ByteString)-getEncDec t- | t == "none" = const $ pure (plainCipher, plainCipher)- | otherwise = getSSLEncDec t
src/Network/MoeSocks/TCP.hs view
@@ -14,12 +14,16 @@ import Network.MoeSocks.Helper import Network.MoeSocks.Type import Network.Socket hiding (send, recv, recvFrom, sendTo)+import Network.Socket.ByteString (recv) import Prelude hiding ((-), take) import qualified Data.Strict as S -local_Socks5_RequestHandler :: MoeConfig -> ByteString -> (Socket, SockAddr) - -> IO ()-local_Socks5_RequestHandler aConfig _ (aSocket,_) = do+local_Socks5_RequestHandler :: CipherBox + -> MoeConfig + -> ByteString + -> (Socket, SockAddr) + -> IO ()+local_Socks5_RequestHandler aCipherBox aConfig _ (aSocket,_) = do (_partialBytesAfterGreeting, _r) <- parseSocket "clientGreeting" mempty plainCipher greetingParser aSocket@@ -37,26 +41,34 @@ connectionParser aSocket - local_TCP_RequestHandler aConfig _parsedRequest True aSocket+ local_TCP_RequestHandler aCipherBox aConfig _parsedRequest True aSocket -local_TCP_ForwardRequestHandler :: MoeConfig -> Forward -> - ByteString -> (Socket, SockAddr) -> IO ()-local_TCP_ForwardRequestHandler aConfig aForwarding _ (aSocket,_) = do+local_TCP_ForwardRequestHandler :: CipherBox + -> MoeConfig + -> Forward + -> ByteString + -> (Socket, SockAddr) + -> IO ()+local_TCP_ForwardRequestHandler aCipherBox aConfig aForwarding _ (aSocket,_) = do let _clientRequest = ClientRequest TCP_IP_stream_connection (Domain_name - aForwarding ^. forwardRemoteHost) (aForwarding ^. forwardRemotePort) - local_TCP_RequestHandler aConfig (mempty, _clientRequest) False aSocket+ local_TCP_RequestHandler aCipherBox aConfig (mempty, _clientRequest) False aSocket -local_TCP_RequestHandler :: MoeConfig -> (ByteString, ClientRequest) -> - Bool -> Socket -> IO ()-local_TCP_RequestHandler aConfig +local_TCP_RequestHandler :: CipherBox + -> MoeConfig + -> (ByteString, ClientRequest) + -> Bool + -> Socket + -> IO ()+local_TCP_RequestHandler aCipherBox aConfig (_partialBytesAfterClientRequest, _clientRequest) shouldReplyClient aSocket = do let @@ -84,11 +96,9 @@ _log - "L T: " <> _msg let handleLocal __remoteSocket = do- (_encrypt, _decrypt) <- getCipher- (aConfig ^. method)- (aConfig ^. password)--+ _encodeIV <- aCipherBox ^. generateIV + _encrypt <- aCipherBox ^. encryptBuilder - _encodeIV+ let _header = shadowSocksRequestBuilder _clientRequest @@ -103,13 +113,12 @@ else Nothing let sendThread = do- sendBuilderEncrypted - sendChannel _encrypt _header+ sendBytes sendChannel _encodeIV+ sendBuilderEncrypt sendChannel _encrypt _header when (_partialBytesAfterClientRequest & isn't _Empty) -- atomically . writeTBQueue sendChannel . S.Just =<< - _encrypt (S.Just _partialBytesAfterClientRequest)-+ sendBytesEncrypt sendChannel _encrypt + _partialBytesAfterClientRequest let _produce = do produceLoop (_logId "L --> + Loop")@@ -133,6 +142,9 @@ pure () let receiveThread = do+ _decodeIV <- recv __remoteSocket (aCipherBox ^. ivLength)+ _decrypt <- aCipherBox ^. decryptBuilder - _decodeIV+ let _produce = produceLoop (_logId "L <-- + Loop") _timeout _NoThrottle@@ -161,12 +173,11 @@ handleLocal _remoteSocket -remote_TCP_RequestHandler:: MoeConfig -> Socket -> IO ()-remote_TCP_RequestHandler aConfig aSocket = do- (_encrypt, _decrypt) <- getCipher- (aConfig ^. method)- (aConfig ^. password)- +remote_TCP_RequestHandler :: CipherBox -> MoeConfig -> Socket -> IO ()+remote_TCP_RequestHandler aCipherBox aConfig aSocket = do+ _decodeIV <- recv aSocket (aCipherBox ^. ivLength)+ _decrypt <- aCipherBox ^. decryptBuilder - _decodeIV+ (_leftOverBytes, _clientRequest) <- parseSocket "clientRequest" mempty@@ -229,6 +240,10 @@ pure () let receiveThread = do+ _encodeIV <- aCipherBox ^. generateIV + _encrypt <- aCipherBox ^. encryptBuilder - _encodeIV+ sendBytes receiveChannel _encodeIV+ let _produce = do produceLoop (_logId "R <-- + Loop") _timeout
src/Network/MoeSocks/Type.hs view
@@ -99,16 +99,30 @@ makeLenses ''MoeOptions +type Cipher = S.Maybe ByteString -> IO ByteString +type CipherBuilder = ByteString -> IO Cipher++data CipherBox = CipherBox+ {+ _ivLength :: Int+ , _generateIV :: IO ByteString+ , _encryptBuilder :: CipherBuilder+ , _decryptBuilder :: CipherBuilder+ }++makeLenses '' CipherBox+ data Env = Env { _options :: MoeOptions , _config :: MoeConfig+ , _cipherBox :: CipherBox }- deriving (Show, Eq) makeLenses ''Env -type Cipher = S.Maybe ByteString -> IO ByteString -type Queue = TBQueue (Maybe ByteString) ++type Queue = TBQueue (Maybe ByteString) type MoeMonadT = ReaderT MoeOptions (ExceptT String IO)+
src/Network/MoeSocks/UDP.hs view
@@ -8,6 +8,7 @@ import Control.Monad.Writer hiding (listen) import Data.Attoparsec.ByteString import Data.ByteString (ByteString)+import qualified Data.ByteString as S import Network.MoeSocks.BuilderAndParser import Network.MoeSocks.Common import Network.MoeSocks.Helper@@ -36,9 +37,13 @@ processAll f x = (<>) <$> f (S.Just x) <*> f S.Nothing -local_UDP_ForwardRequestHandler :: MoeConfig -> Forward -> - ByteString -> (Socket,SockAddr) -> IO ()-local_UDP_ForwardRequestHandler aConfig aForwarding aMessage +local_UDP_ForwardRequestHandler :: CipherBox + -> MoeConfig + -> Forward + -> ByteString + -> (Socket,SockAddr) + -> IO ()+local_UDP_ForwardRequestHandler aCipherBox aConfig aForwarding aMessage (aSocket, aSockAddr) = do let _c = aConfig@@ -57,9 +62,8 @@ \(_remoteSocket, _remoteAddr) -> do connect _remoteSocket _remoteAddr - (_encrypt, _decrypt) <- getCipher- (aConfig ^. method)- (aConfig ^. password)+ _encodeIV <- aCipherBox ^. generateIV + _encrypt <- aCipherBox ^. encryptBuilder - _encodeIV {-let (_encrypt, _decrypt) = (pure, pure)-} @@ -70,27 +74,34 @@ let _msg = show aSockAddr <> " -> " <> showRequest _clientRequest _log - "L U: " <> _msg - send_ _remoteSocket =<< _encrypt (S.Just _bytes)+ _eMsg <- _encrypt (S.Just _bytes) - (_r, _) <- recv_ _remoteSocket >>= processAll _decrypt + send_ _remoteSocket - _encodeIV <> _eMsg++ _response <- recv_ _remoteSocket ++ let (_decodeIV, _responseMsg) = S.splitAt (aCipherBox ^. ivLength) + _response+ _decrypt <- aCipherBox ^. decryptBuilder - _decodeIV+ + (_r, _) <- processAll _decrypt _responseMsg >>= parseShadowSocksRequest - {-puts - "L UDP <--: " <> show _r-} when (_r & isn't _Empty) - do sendAllTo aSocket _r aSockAddr -remote_UDP_RequestHandler:: MoeConfig -> ByteString -> (Socket, SockAddr) - -> IO ()-remote_UDP_RequestHandler aConfig aMessage (aSocket, aSockAddr) = do- (_encrypt, _decrypt) <- getCipher- (aConfig ^. method)- (aConfig ^. password)- +remote_UDP_RequestHandler :: CipherBox + -> MoeConfig + -> ByteString + -> (Socket, SockAddr) + -> IO ()+remote_UDP_RequestHandler aCipherBox _ aMessage (aSocket, aSockAddr) = do+ let (_decodeIV, _eMsg) = S.splitAt (aCipherBox ^. ivLength) + aMessage - {-let (_encrypt, _decrypt) = (pure, pure)-}- - _msg <- processAll _decrypt aMessage+ _decrypt <- aCipherBox ^. decryptBuilder - _decodeIV+ _msg <- processAll _decrypt _eMsg (_decryptedMessage, _clientRequest) <- parseShadowSocksRequest _msg @@ -114,5 +125,8 @@ {-puts - "R UDP <--: " <> show _r-} when (_r & isn't _Empty) - do+ _encodeIV <- aCipherBox ^. generateIV + _encrypt <- aCipherBox ^. encryptBuilder - _encodeIV+ _encryptedMessage <- processAll _encrypt _r- sendAllTo aSocket _encryptedMessage aSockAddr+ sendAllTo aSocket (_encodeIV <> _encryptedMessage) aSockAddr