socks 0.1.0 → 0.2.0
raw patch · 4 files changed
+56/−13 lines, 4 filesdep ~network
Dependency ranges changed: network
Files
- Example.hs +17/−2
- Network/Socks5.hs +33/−9
- Network/Socks5/Command.hs +1/−1
- socks.cabal +5/−1
Example.hs view
@@ -3,21 +3,29 @@ import Network.Socket hiding (recv) import Network.Socket.ByteString import Network.BSD+import Network import Data.ByteString.Char8 ()+import qualified Data.ByteString.Char8 as BC +import System.IO (hClose, hFlush) import System.Environment (getArgs) main = do args <- getArgs+ let serverName = "localhost"+ let serverPort = 1080 let destinationName = case args of [] -> "www.google.com" (x:_) -> x -- socks server is expected to be running on localhost port 1080- he <- getHostByName "localhost"- let socksServerAddr = SockAddrInet 1080 (head $ hostAddresses he)+ he <- getHostByName serverName+ let socksServerAddr = SockAddrInet serverPort (head $ hostAddresses he) example1 socksServerAddr destinationName example2 socksServerAddr destinationName++ example3 serverName serverPort destinationName 80+ where -- connect to @destName on port 80 through the socks server -- www.google.com get resolve on the client here and then the sockaddr is@@ -40,3 +48,10 @@ sendAll socket "GET / HTTP/1.0\r\n\r\n" recv socket 4096 >>= putStrLn . show sClose socket++ example3 sname sport dname dport = do + handle <- socksConnectTo sname (PortNumber sport) dname (PortNumber dport)+ BC.hPut handle "GET / HTTP/1.0\r\n\r\n"+ hFlush handle+ BC.hGet handle 1024 >>= putStrLn . show+ hClose handle
Network/Socks5.hs view
@@ -10,16 +10,21 @@ module Network.Socks5 ( socksConnectAddr , socksConnectName+ , socksConnectTo ) where import Control.Monad-import Network.Socket (Socket, SockAddr(..), PortNumber, connect)+import Control.Exception+import Network.Socket+import Network.BSD import Network.Socks5.Command import Network.Socks5.Types+import Network+import System.IO -withSocks socket sockaddr f = do- connect socket sockaddr- r <- socks5Establish socket [SocksMethodNone]+withSocks sock sockaddr f = do+ connect sock sockaddr+ r <- socks5Establish sock [SocksMethodNone] when (r == SocksMethodNotAcceptable) $ error "cannot connect with no socks method of authentication" f @@ -30,15 +35,34 @@ -- -- |socket|-----sockServer----->|server|----destAddr----->|destination| socksConnectAddr :: Socket -> SockAddr -> SockAddr -> IO ()-socksConnectAddr socket sockserver destaddr = withSocks socket sockserver $ do+socksConnectAddr sock sockserver destaddr = withSocks sock sockserver $ do case destaddr of- SockAddrInet p h -> socks5ConnectIPV4 socket h p >> return ()- SockAddrInet6 p _ h _ -> socks5ConnectIPV6 socket h p >> return ()+ SockAddrInet p h -> socks5ConnectIPV4 sock h p >> return ()+ SockAddrInet6 p _ h _ -> socks5ConnectIPV6 sock h p >> return () SockAddrUnix _ -> error "unsupported unix sockaddr type" -- | connect a new socket to the socks server, and connect the stream to a FQDN -- resolved on the server side. socksConnectName :: Socket -> SockAddr -> String -> PortNumber -> IO ()-socksConnectName socket sockserver destination port = withSocks socket sockserver $ do- _ <- socks5ConnectDomainName socket destination port+socksConnectName sock sockserver destination port = withSocks sock sockserver $ do+ _ <- socks5ConnectDomainName sock destination port return ()++-- | similar to Network connectTo but use a socks proxy.+socksConnectTo :: String -> PortID -> String -> PortID -> IO Handle+socksConnectTo sockshost socksport desthost destport = do+ sport <- resolvePortID socksport+ dport <- resolvePortID destport++ proto <- getProtocolNumber "tcp"+ bracketOnError (socket AF_INET Stream proto) sClose (go sport dport)+ where+ go sport dport sock = do+ he <- getHostByName sockshost+ let sockaddr = SockAddrInet sport (hostAddress he)+ socksConnectName sock sockaddr desthost dport+ socketToHandle sock ReadWriteMode++ resolvePortID (Service serv) = getServicePortNumber serv+ resolvePortID (PortNumber n) = return n+ resolvePortID _ = error "unsupported unix PortID"
Network/Socks5/Command.hs view
@@ -81,4 +81,4 @@ r (Partial cont) = ioget >>= r . cont r (Done a b) | not $ B.null b = error "got too many bytes while receiving data"- | otherwise = putStrLn (show a) >> return a+ | otherwise = return a
socks.cabal view
@@ -1,5 +1,5 @@ Name: socks-Version: 0.1.0+Version: 0.2.0 Description: Socks proxy (version 5) implementation. License: BSD3 License-file: LICENSE@@ -24,3 +24,7 @@ Network.Socks5.Types Network.Socks5.Command ghc-options: -Wall -fno-warn-missing-signatures++source-repository head+ type: git+ location: git://github.com/vincenthz/hs-socks