Popularity
6.0
Stable
Activity
0.0
Stable
16
2
3
Monthly Downloads: 0
Programming language: Haskell
License: MIT License
Latest version: v0.1.0.0
hssh alternatives and similar packages
Based on the "network" category.
Alternatively, view hssh alternatives based on common mentions on social networks and blogs.
-
compendium-client
DISCONTINUED. Mu (μ) is a purely functional framework for building micro services.
InfluxDB – Built for High-Performance Time Series Workloads
InfluxDB 3 OSS is now GA. Transform, enrich, and act on time series data directly in the database. Automate critical tasks and eliminate the need to move data externally. Download now.
Promo
www.influxdata.com

Do you think we are missing an alternative of hssh or a related project?
Popular Comparisons
README
hssh - Haskell SSH

Introduction
This library is a pure-Haskell implementation of the SSH2 protocol.
Features
By now, only the server part has been implemented. It can be used to embed SSH servers into Haskell applications.
Transport layer:
ssh-ed25519
host keys.- Key exchange using the
[email protected]
algorithm. - Encryption using the
[email protected]
algorithm. - Rekeying fully supported and compatible with OpenSSH.
Authentication layer:
- User authentication with
ssh-ed25519
public keys.
Connection layer:
- Connection multiplexing.
- Serving session requests (shell and exec) with user-supplied handlers.
- Serving direct-tcpip requests with user-supplied handlers.
Misc:
- SSH private key file import (not encrypted yet).
Dependencies
- async
- base
- bytestring
- cereal
- containers
- cryptonite
- memory
- stm
- data-default
Example server application
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Concurrent ( forkFinally
)
import Control.Exception ( bracket
, bracketOnError
, handle
, throwIO
)
import Control.Monad ( forever
, void
)
import qualified Data.ByteArray as BA
import qualified Data.ByteString as BS
import Data.Default
import System.Exit
import qualified System.Socket as S
import qualified System.Socket.Family.Inet6 as S
import qualified System.Socket.Protocol.Default as S
import qualified System.Socket.Type.Stream as S
import qualified System.Socket.Unsafe as S
import Network.SSH
import qualified Network.SSH.Server as Server
main :: IO ()
main = do
file <- BS.readFile "./resources/id_ed25519"
(privateKey, _) : _ <- decodePrivateKeyFile BS.empty file :: IO [(KeyPair, BA.Bytes)]
bracket open close (accept config privateKey)
where
config = def
{ Server.transportConfig = def
, Server.userAuthConfig = def
{ Server.onAuthRequest = \username _ _ -> pure (Just username)
}
, Server.connectionConfig = def
{ Server.onSessionRequest = handleSessionRequest
, Server.onDirectTcpIpRequest = handleDirectTcpIpRequest
}
}
open = S.socket :: IO (S.Socket S.Inet6 S.Stream S.Default)
close = S.close
accept config agent s = do
S.setSocketOption s (S.ReuseAddress True)
S.setSocketOption s (S.V6Only False)
S.bind s (S.SocketAddressInet6 S.inet6Any 22 0 0)
S.listen s 5
forever $ bracketOnError (S.accept s) (S.close . fst) $ \(stream, peer) -> do
putStrLn $ "Connection from " ++ show peer
void $ forkFinally
(Server.serve config agent stream >>= print)
(const $ S.close stream)
handleDirectTcpIpRequest :: identity -> Server.DirectTcpIpRequest -> IO (Maybe Server.DirectTcpIpHandler)
handleDirectTcpIpRequest idnt req = pure $ Just $ Server.DirectTcpIpHandler $ \stream-> do
bs <- receive stream 4096
sendAll stream "HTTP/1.1 200 OK\n"
sendAll stream "Content-Type: text/plain\n\n"
sendAll stream $! BS.pack $ fmap (fromIntegral . fromEnum) $ show req
sendAll stream "\n\n"
sendAll stream bs
print bs
handleSessionRequest :: identity -> Server.SessionRequest -> IO (Maybe Server.SessionHandler)
handleSessionRequest idnt req = pure $ Just $ Server.SessionHandler $ \_ _ _ _ stdout _ -> do
sendAll stdout "Hello world!\n"
pure ExitSuccess
-------------------------------------------------------------------------------
-- Instances for use with the socket library
-------------------------------------------------------------------------------
instance DuplexStream (S.Socket f S.Stream p) where
instance OutputStream (S.Socket f S.Stream p) where
send stream bytes =
handle f $ S.send stream bytes S.msgNoSignal
where
f e
| e == S.ePipe = pure 0
| otherwise = throwIO e
sendUnsafe stream (BA.MemView ptr n) = fromIntegral <$>
handle f (S.unsafeSend stream ptr (fromIntegral n) S.msgNoSignal)
where
f e
| e == S.ePipe = pure 0
| otherwise = throwIO e
instance InputStream (S.Socket f S.Stream p) where
peek stream len = S.receive stream len (S.msgNoSignal <> S.msgPeek)
receive stream len = S.receive stream len S.msgNoSignal
receiveUnsafe stream (BA.MemView ptr n) = fromIntegral <$>
S.unsafeReceive stream ptr (fromIntegral n) S.msgNoSignal