hssh-0.1.0.0: test/Spec/Message.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE StandaloneDeriving #-}
module Spec.Message ( tests ) where
import Crypto.Error
import qualified Crypto.PubKey.Curve25519 as Curve25519
import qualified Crypto.PubKey.Ed25519 as Ed25519
import qualified Crypto.PubKey.RSA as RSA
import qualified Data.ByteString as BS
import qualified Data.ByteString.Short as SBS
import System.Exit
import Test.Tasty
import Test.Tasty.QuickCheck as QC
import Network.SSH.Internal
tests :: TestTree
tests = testGroup "Network.SSH.Message"
[ testParserIdentity
]
testParserIdentity :: TestTree
testParserIdentity = testGroup "put . get == id"
[ QC.testProperty ":: Disconnected" (parserIdentity :: Disconnected -> Property)
, QC.testProperty ":: DisconnectReason" (parserIdentity :: DisconnectReason -> Property)
, QC.testProperty ":: Ignore" (parserIdentity :: Ignore -> Property)
, QC.testProperty ":: Unimplemented" (parserIdentity :: Unimplemented -> Property)
, QC.testProperty ":: Debug" (parserIdentity :: Debug -> Property)
, QC.testProperty ":: ServiceRequest" (parserIdentity :: ServiceRequest -> Property)
, QC.testProperty ":: ServiceAccept" (parserIdentity :: ServiceAccept -> Property)
, QC.testProperty ":: KexInit" (parserIdentity :: KexInit -> Property)
, QC.testProperty ":: KexNewKeys" (parserIdentity :: KexNewKeys -> Property)
, QC.testProperty ":: KexEcdhInit" (parserIdentity :: KexEcdhInit -> Property)
, QC.testProperty ":: KexEcdhReply" (parserIdentity :: KexEcdhReply -> Property)
, QC.testProperty ":: UserAuthRequest" (parserIdentity :: UserAuthRequest -> Property)
, QC.testProperty ":: UserAuthFailure" (parserIdentity :: UserAuthFailure -> Property)
, QC.testProperty ":: UserAuthSuccess" (parserIdentity :: UserAuthSuccess -> Property)
, QC.testProperty ":: UserAuthBanner" (parserIdentity :: UserAuthBanner -> Property)
, QC.testProperty ":: UserAuthPublicKeyOk" (parserIdentity :: UserAuthPublicKeyOk -> Property)
, QC.testProperty ":: ChannelOpen" (parserIdentity :: ChannelOpen -> Property)
, QC.testProperty ":: ChannelOpenConfirmation" (parserIdentity :: ChannelOpenConfirmation -> Property)
, QC.testProperty ":: ChannelOpenFailure" (parserIdentity :: ChannelOpenFailure -> Property)
, QC.testProperty ":: ChannelOpenFailureReason" (parserIdentity :: ChannelOpenFailureReason -> Property)
, QC.testProperty ":: ChannelWindowAdjust" (parserIdentity :: ChannelWindowAdjust -> Property)
, QC.testProperty ":: ChannelData" (parserIdentity :: ChannelData -> Property)
, QC.testProperty ":: ChannelExtendedData" (parserIdentity :: ChannelExtendedData -> Property)
, QC.testProperty ":: ChannelEof" (parserIdentity :: ChannelEof -> Property)
, QC.testProperty ":: ChannelClose" (parserIdentity :: ChannelClose -> Property)
, QC.testProperty ":: ChannelRequest" (parserIdentity :: ChannelRequest -> Property)
, QC.testProperty ":: ChannelRequestEnv" (parserIdentity :: ChannelRequestEnv -> Property)
, QC.testProperty ":: ChannelRequestPty" (parserIdentity :: ChannelRequestPty -> Property)
, QC.testProperty ":: ChannelRequestWindowChange" (parserIdentity :: ChannelRequestWindowChange -> Property)
, QC.testProperty ":: ChannelRequestShell" (parserIdentity :: ChannelRequestShell -> Property)
, QC.testProperty ":: ChannelRequestExec" (parserIdentity :: ChannelRequestExec -> Property)
, QC.testProperty ":: ChannelRequestSignal" (parserIdentity :: ChannelRequestSignal -> Property)
, QC.testProperty ":: ChannelRequestExitSignal" (parserIdentity :: ChannelRequestExitSignal -> Property)
, QC.testProperty ":: ChannelRequestExitStatus" (parserIdentity :: ChannelRequestExitStatus -> Property)
, QC.testProperty ":: ChannelSuccess" (parserIdentity :: ChannelSuccess -> Property)
, QC.testProperty ":: ChannelFailure" (parserIdentity :: ChannelFailure -> Property)
, QC.testProperty ":: Version" (parserIdentity :: Version -> Property)
, QC.testProperty ":: PublicKey" (parserIdentity :: PublicKey -> Property)
, QC.testProperty ":: Signature" (parserIdentity :: Signature -> Property)
, QC.testProperty ":: Message" (parserIdentity :: Message -> Property)
]
where
parserIdentity :: (Encoding a, Eq a, Show a) => a -> Property
parserIdentity x = Just x === runGet (runPut $ put x)
instance Arbitrary BS.ByteString where
arbitrary = elements
[ ""
, "1"
, "1234567890"
]
instance Arbitrary SBS.ShortByteString where
arbitrary = elements
[ ""
, "1"
, "1234567890"
]
instance Arbitrary Command where
arbitrary = elements
[ Command ""
, Command "foobar --xyz fasel"
, Command "ls"
]
instance Arbitrary Message where
arbitrary = oneof
[ MsgDisconnect <$> arbitrary
, MsgIgnore <$> arbitrary
, MsgUnimplemented <$> arbitrary
, MsgDebug <$> arbitrary
, MsgServiceRequest <$> arbitrary
, MsgServiceAccept <$> arbitrary
, MsgKexInit <$> arbitrary
, MsgKexNewKeys <$> arbitrary
, MsgKexEcdhInit <$> arbitrary
, MsgKexEcdhReply <$> arbitrary
, MsgUserAuthRequest <$> arbitrary
, MsgUserAuthFailure <$> arbitrary
, MsgUserAuthSuccess <$> arbitrary
, MsgUserAuthBanner <$> arbitrary
, MsgUserAuthPublicKeyOk <$> arbitrary
, MsgChannelOpen <$> arbitrary
, MsgChannelOpenConfirmation <$> arbitrary
, MsgChannelOpenFailure <$> arbitrary
, MsgChannelData <$> arbitrary
, MsgChannelExtendedData <$> arbitrary
, MsgChannelEof <$> arbitrary
, MsgChannelClose <$> arbitrary
, MsgChannelRequest <$> arbitrary
, MsgChannelSuccess <$> arbitrary
, MsgChannelFailure <$> arbitrary
, MsgUnknown <$> elements [ 128, 255 ]
]
instance Arbitrary Disconnected where
arbitrary = Disconnected <$> arbitrary <*> arbitrary <*> arbitrary
instance Arbitrary DisconnectReason where
arbitrary = elements
[ DisconnectHostNotAllowedToConnect
, DisconnectProtocolError
, DisconnectKeyExchangeFailed
, DisconnectReserved
, DisconnectMacError
, DisconnectCompressionError
, DisconnectServiceNotAvailable
, DisconnectProtocolVersionNotSupported
, DisconnectHostKeyNotVerifiable
, DisconnectConnectionLost
, DisconnectByApplication
, DisconnectTooManyConnection
, DisconnectAuthCancelledByUser
, DisconnectNoMoreAuthMethodsAvailable
, DisconnectIllegalUsername
]
instance Arbitrary Ignore where
arbitrary = pure Ignore
instance Arbitrary Unimplemented where
arbitrary = Unimplemented <$> arbitrary
instance Arbitrary Debug where
arbitrary = Debug
<$> arbitrary
<*> elements [ "", "debug message", "debug message containing\n linefeeds\n\r" ]
<*> elements [ "", "de_DE", "en_US" ]
instance Arbitrary ServiceRequest where
arbitrary = ServiceRequest <$> arbitrary
instance Arbitrary ServiceAccept where
arbitrary = ServiceAccept <$> arbitrary
instance Arbitrary KexInit where
arbitrary = KexInit <$> arbitrary <*> nameList <*> nameList <*> nameList
<*> nameList <*> nameList <*> nameList <*> nameList
<*> nameList <*> nameList <*> nameList <*> arbitrary
where
nameList = elements [ [], ["abc"], ["abc","def"] ]
instance Arbitrary KexNewKeys where
arbitrary = pure KexNewKeys
instance Arbitrary KexEcdhInit where
arbitrary = KexEcdhInit <$> arbitrary
instance Arbitrary KexEcdhReply where
arbitrary = KexEcdhReply <$> arbitrary <*> arbitrary <*> arbitrary
instance Arbitrary UserAuthRequest where
arbitrary = UserAuthRequest <$> arbitrary <*> arbitrary <*> arbitrary
instance Arbitrary UserAuthFailure where
arbitrary = UserAuthFailure <$> arbitrary <*> arbitrary
instance Arbitrary UserAuthSuccess where
arbitrary = pure UserAuthSuccess
instance Arbitrary UserAuthBanner where
arbitrary = UserAuthBanner <$> arbitrary <*> arbitrary
instance Arbitrary UserAuthPublicKeyOk where
arbitrary = UserAuthPublicKeyOk <$> arbitrary
instance Arbitrary ChannelOpen where
arbitrary = ChannelOpen <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
instance Arbitrary ChannelOpenType where
arbitrary = elements
[ ChannelOpenSession
, ChannelOpenDirectTcpIp "localhost" 8080 "10.0.0.1" 73594
, ChannelOpenOther (ChannelType "other")
]
instance Arbitrary ChannelOpenConfirmation where
arbitrary = ChannelOpenConfirmation <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
instance Arbitrary ChannelOpenFailure where
arbitrary = ChannelOpenFailure <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
instance Arbitrary ChannelOpenFailureReason where
arbitrary = elements
[ ChannelOpenAdministrativelyProhibited
, ChannelOpenConnectFailed
, ChannelOpenUnknownChannelType
, ChannelOpenResourceShortage
]
instance Arbitrary ChannelWindowAdjust where
arbitrary = ChannelWindowAdjust <$> arbitrary <*> arbitrary
instance Arbitrary ChannelData where
arbitrary = ChannelData <$> arbitrary <*> elements
[ ""
, "abc"
, "asdhaskdjhaskhdkjahsdkjahsdkjhasdkjahdkj"
]
instance Arbitrary ChannelExtendedData where
arbitrary = ChannelExtendedData <$> arbitrary <*> arbitrary <*> arbitrary
instance Arbitrary ChannelEof where
arbitrary = ChannelEof <$> arbitrary
instance Arbitrary ChannelClose where
arbitrary = ChannelClose <$> arbitrary
instance Arbitrary ChannelRequest where
arbitrary = ChannelRequest <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
instance Arbitrary ChannelRequestEnv where
arbitrary = ChannelRequestEnv <$> arbitrary <*> arbitrary
instance Arbitrary ChannelRequestPty where
arbitrary = ChannelRequestPty <$> arbitrary
instance Arbitrary ChannelRequestWindowChange where
arbitrary = ChannelRequestWindowChange <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
instance Arbitrary ChannelRequestShell where
arbitrary = pure ChannelRequestShell
instance Arbitrary ChannelRequestExec where
arbitrary = ChannelRequestExec <$> arbitrary
instance Arbitrary ChannelRequestSignal where
arbitrary = ChannelRequestSignal <$> arbitrary
instance Arbitrary ChannelRequestExitStatus where
arbitrary = ChannelRequestExitStatus <$> (arbitrary >>= \i-> pure $ if i == 0 then ExitSuccess else ExitFailure (abs i))
instance Arbitrary ChannelRequestExitSignal where
arbitrary = ChannelRequestExitSignal <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
instance Arbitrary ChannelSuccess where
arbitrary = ChannelSuccess <$> arbitrary
instance Arbitrary ChannelFailure where
arbitrary = ChannelFailure <$> arbitrary
instance Arbitrary Version where
arbitrary = elements
[ Version "SSH-2.0-OpenSSH_4.3"
, Version "SSH-2.0-hssh_0.1"
]
instance Arbitrary PtySettings where
arbitrary = PtySettings
<$> elements [ "xterm", "urxvt-unicode", "urxvt-unicode-color256" ]
<*> elements [ 80 ]
<*> elements [ 24 ]
<*> elements [ 640 ]
<*> elements [ 480 ]
<*> elements [ "\129\NUL\NUL\150\NUL\128\NUL\NUL\150\NUL\SOH\NUL\NUL\NUL\ETX\STX\NUL\NUL\NUL\FS\ETX\NUL\NUL\NUL\DEL\EOT\NUL\NUL\NUL\NAK\ENQ\NUL\NUL\NUL\EOT\ACK\NUL\NUL\NUL\NUL\a\NUL\NUL\NUL\NUL\b\NUL\NUL\NUL\DC1\t\NUL\NUL\NUL\DC3\n\NUL\NUL\NUL\SUB\f\NUL\NUL\NUL\DC2\r\NUL\NUL\NUL\ETB\SO\NUL\NUL\NUL\SYN\DC2\NUL\NUL\NUL\SI\RS\NUL\NUL\NUL\SOH\US\NUL\NUL\NUL\NUL \NUL\NUL\NUL\NUL!\NUL\NUL\NUL\NUL\"\NUL\NUL\NUL\NUL#\NUL\NUL\NUL\NUL$\NUL\NUL\NUL\SOH%\NUL\NUL\NUL\NUL&\NUL\NUL\NUL\SOH'\NUL\NUL\NUL\NUL(\NUL\NUL\NUL\NUL)\NUL\NUL\NUL\SOH*\NUL\NUL\NUL\SOH2\NUL\NUL\NUL\SOH3\NUL\NUL\NUL\SOH4\NUL\NUL\NUL\NUL5\NUL\NUL\NUL\SOH6\NUL\NUL\NUL\SOH7\NUL\NUL\NUL\SOH8\NUL\NUL\NUL\NUL9\NUL\NUL\NUL\NUL:\NUL\NUL\NUL\NUL;\NUL\NUL\NUL\SOH<\NUL\NUL\NUL\SOH=\NUL\NUL\NUL\SOH>\NUL\NUL\NUL\NULF\NUL\NUL\NUL\SOHG\NUL\NUL\NUL\NULH\NUL\NUL\NUL\SOHI\NUL\NUL\NUL\NULJ\NUL\NUL\NUL\NULK\NUL\NUL\NUL\NULZ\NUL\NUL\NUL\SOH[\NUL\NUL\NUL\SOH\\\NUL\NUL\NUL\NUL]\NUL\NUL\NUL\NUL\NUL" ]
deriving instance Arbitrary ChannelId
deriving instance Arbitrary ChannelType
instance Arbitrary Cookie where
arbitrary = pure nilCookie
instance Arbitrary Password where
arbitrary = elements $ fmap Password
[ "1234567890"
]
instance Arbitrary AuthMethod where
arbitrary = oneof
[ pure AuthNone
, pure AuthHostBased
, AuthPassword <$> arbitrary
, AuthPublicKey <$> arbitrary <*> arbitrary
]
instance Arbitrary Name where
arbitrary = elements [ "abc" ]
instance Arbitrary PublicKey where
arbitrary = oneof
[ PublicKeyEd25519 <$> x1
, PublicKeyRSA <$> x2
, PublicKeyOther <$> x3
]
where
x1 = pure $ case Ed25519.publicKey ("$\149\229m\164\ETB\GSA\ESC\185ThTc8\212\219\158\249\CAN\202\245\133\140a\bZQ\v\234\247x" :: BS.ByteString) of
CryptoPassed pk -> pk
CryptoFailed _ -> undefined
x2 = pure $ RSA.PublicKey 24 65537 2834792
x3 = pure "PUBLIC_KEY_OTHER"
instance Arbitrary Signature where
arbitrary = oneof
[ SignatureEd25519 <$> x1
, SignatureRSA <$> x2
, pure (SignatureOther "ssh-other")
]
where
x1 = pure $ case Ed25519.signature ("\169\150V0\235\151\ENQ\149w\DC1\172wKV]W|\b\ETB\f@\158\178\254\158\168\v>\180&\164D\DELF\204\133p\186\195(\169\177\144\168\STX\DC2\153!B\252\154o\251\230\154\164T\223\243\148'i\a\EOT" :: BS.ByteString) of
CryptoPassed sig -> sig
CryptoFailed _ -> undefined
x2 = pure "SIGNATURE_RSA"
instance Arbitrary Curve25519.PublicKey where
arbitrary = pure $ case Curve25519.publicKey ("\179g~\181\170\169\154\205\211\ft\162\&0@0dO\FS\DLEA\166@[r\150t~W\221cOF" :: BS.ByteString) of
CryptoPassed pk -> pk
CryptoFailed _ -> undefined