Ich versuche herauszufinden, wie die OpenSSL.Session- API in einem gleichzeitigen Kontext richtig verwendet wird
Angenommen, ich möchte eine implementieren stunnel-style ssl-wrapper
, würde ich die folgende grundlegende Skelettstruktur erwarten, die eine naive implementiertfull-duplex tcp-port-forwarder:
runProxy :: PortID -> AddrInfo -> IO ()
runProxy localPort@(PortNumber lpn) serverAddrInfo = do
listener <- listenOn localPort
forever $ do
(sClient, clientAddr) <- accept listener
let finalize sServer = do
sClose sServer
sClose sClient
forkIO $ do
tidToServer <- myThreadId
bracket (connectToServer serverAddrInfo) finalize $ \sServer -> do
-- execute one 'copySocket' thread for each data direction
-- and make sure that if one direction dies, the other gets
-- pulled down as well
bracket (forkIO (copySocket sServer sClient
`finally` killThread tidToServer))
(killThread) $ \_ -> do
copySocket sClient sServer -- "controlling" thread
where
-- |Copy data from source to dest until EOF occurs on source
-- Copying may also be aborted due to exceptions
copySocket :: Socket -> Socket -> IO ()
copySocket src dst = go
where
go = do
buf <- B.recv src 4096
unless (B.null buf) $ do
B.sendAll dst buf
go
-- |Create connection to given AddrInfo target and return socket
connectToServer saddr = do
sServer <- socket (addrFamily saddr) Stream defaultProtocol
connect sServer (addrAddress saddr)
return sServer
Wie verwandle ich das obige Skelett in ein full-duplex ssl-wrapping tcp-forwarding proxy
? Wo liegen die Gefahren von WRT für die gleichzeitige / parallele Ausführung (im Kontext des obigen Anwendungsfalls) der von der HsOpenSSL-API bereitgestellten Funktionsaufrufe?
PS: Ich habe immer noch Schwierigkeiten zu verstehen, wie der Code gegenüber Ausnahmen und Ressourcenlecks robust gemacht werden kann. Obwohl dies nicht der Hauptfokus dieser Frage ist, hinterlassen Sie bitte einen Kommentar, wenn Sie im obigen Code etwas Schlechtes bemerken.
full-duplex ssl-rewrapping tcp-forwarding
), aber es hat stattdessenNetwork.TLS
(Pakettls
) verwendet. Und es war hässlich. Sie finden es hier , wenn überhaupt interessiert.Antworten:
Dazu müssen Sie
copySocket
zwei verschiedene Funktionen ersetzen , eine zum Verarbeiten von Daten vom einfachen Socket zu SSL und die andere von SSL zum einfachen Socket:Dann müssen Sie Änderungen
connectToServer
vornehmen, damit eine SSL-Verbindung hergestellt wirdund ändern Sie
finalize
diese Option, um die SSL-Sitzung zu beendenVergessen Sie nicht, Ihre Hauptaufgaben
withOpenSSL
wie in auszuführenquelle
stunnels
Client-Modus entspricht. Können Sie auch ein Beispiel zum Abhören eines lokalen SSL-Sockets bereitstellen (z. B. zum Bereitstellen eines lokalen SSL-zu-Remote-Nicht-SSL)? SSL-Proxy)?