packages feed

ssh-known-hosts-0.1.0.0: test/test_ssh_known_hosts.hs

{-# LANGUAGE OverloadedStrings #-}

module Main where

import           Data.IP.Internal
import           Data.Monoid ((<>))
import qualified Data.Text as T
import           Network.SSH.KnownHosts
import           System.Environment
import           Test.Framework
import           Test.Framework.Providers.HUnit
import           Test.Framework.Providers.QuickCheck2
import           Test.HUnit
import           Test.QuickCheck

main = defaultMain
       [ testGroup "Parsing entries"
         [ testParse1
         , testParse2
         , testParse3
         , testParse4
         , testParse5
         , testParse6
         , testParse7
         , testParse8
         , testParse9
         , testParse12
         , testParse13
         , testParse14
         , testParse15
         , testParse16
         , testParse17
         , testParse18
         , testParse19
         , testParse20
         , testParse21
         , testParse22
         ]
       , testGroup "Read and parse existing $HOME/.ssh/known_hosts"
         [ testReadFile
         ]
       , testGroup "Target address recovery"
         [ testTgtAddr1
         , testTgtAddr2
         , testTgtAddr3
         , testTgtAddr4
         , testTgtAddr5
         , testTgtAddr6
         , testTgtAddr7
         , testTgtAddr8
         , testTgtAddr9
         , testTgtAddr12
         , testTgtAddr13
         , testTgtAddr14
         , testTgtAddr15
         , testTgtAddr16
         , testTgtAddr17
         , testTgtAddr18
         , testTgtAddr19
         , testTgtAddr20
         , testTgtAddr22
         ]
       , testGroup "Best address from group"
         [ testBestTgtAddr1
         , testBestTgtAddr2
         , testBestTgtAddr3
         , testBestTgtAddr4
         , testBestTgtAddr5
         , testBestTgtAddr6
         , testBestTgtAddr7
         , testBestTgtAddr8
         , testBestTgtAddr9
         , testBestTgtAddr10
         , testBestTgtAddr11
         , testBestTgtAddr12
         , testBestTgtAddr13
         , testBestTgtAddr14
         , testBestTgtAddr15
         , testBestTgtAddr16
         , testBestTgtAddr17
         , testBestTgtAddr18
         , testBestTgtAddr19
         ]
       ]

testReadFile = testCase "read file" $
               do h <- readKnownHosts
                  home <- getEnv "HOME"
                  l <- lines <$> readFile (home <> "/.ssh/known_hosts")
                  length h @?= length l

testParse1 = testCase "empty parse"
             $ parseRemotes (T.pack "") @?= []

testTgtAddr1 = testCase "target IPv4 address"
               $ (targetAddr $ SSHRemote (SSH1Addr $ RemoteV4 "1.2.3.4") "alg1" "key1")
               @?= ("1.2.3.4", 22)

addr2 = T.pack "1.2.3.4 alg hash"
testParse2 = testCase "single IPv4 parse"
             $ parseRemotes addr2
             @?= [SSHRemote (SSH1Addr $ RemoteV4 "1.2.3.4") "alg" "hash"]
testTgtAddr2 = testCase "target IPv4 address"
               $ (targetAddr $ head $ parseRemotes addr2)
               @?= ("1.2.3.4", 22)

addr3 = T.pack "1.2.3.4 alg hash\n11.22.33.44 alg2 hash2\n"
testParse3 = testCase "multiple IPv4 parse"
             $ parseRemotes addr3
             @?= [ SSHRemote (SSH1Addr $ RemoteV4 "1.2.3.4") "alg" "hash"
                 , SSHRemote (SSH1Addr $ RemoteV4 "11.22.33.44") "alg2" "hash2"
                 ]
testTgtAddr3 = testCase "target IPv4 address"
               $ (targetAddr $ head $ parseRemotes addr3)
               @?= ("1.2.3.4", 22)

addr4 = T.pack "::1 alg hash"
testParse4 = testCase "single IPv6 address"
             $ parseRemotes addr4
             @?= [SSHRemote (SSH1Addr $ RemoteV6 "::1") "alg" "hash"]
testTgtAddr4 = testCase "target IPv6 address"
               $ (targetAddr $ head $ parseRemotes addr4)
               @?= ("::1", 22)

addr5 = T.pack "::1 alg hash\n11::2bed alg2 hash2\n"
testParse5 = testCase "multiple IPv6 parse"
             $ parseRemotes addr5
             @?= [ SSHRemote (SSH1Addr $ RemoteV6 "::1") "alg" "hash"
                 , SSHRemote (SSH1Addr $ RemoteV6 "11::2bed") "alg2" "hash2"
                 ]
testTgtAddr5 = testCase "multiple IPv6 address"
               $ (map targetAddr $ parseRemotes addr5)
               @?= [ ("::1", 22)
                   , ("11::2bed", 22)
                   ]


addr6 = (T.pack "myhost alg hash")
testParse6 = testCase "single name address parse"
             $ parseRemotes addr6
             @?= [SSHRemote (SSH1Addr $ RemoteDNS ["myhost"]) "alg" "hash"]
testTgtAddr6 = testCase "single name address"
               $ (map targetAddr $ parseRemotes addr6)
               @?= [ ("myhost", 22) ]

addr7 = T.pack "localhost alg hash\nmyhost alg2 hash2\n"
testParse7 = testCase "multiple name parse"
             $ parseRemotes addr7
             @?= [ SSHRemote (SSH1Addr $ RemoteDNS ["localhost"]) "alg" "hash"
                 , SSHRemote (SSH1Addr $ RemoteDNS ["myhost"]) "alg2" "hash2"
                 ]
testTgtAddr7 = testCase "multiple name address"
               $ (map targetAddr $ parseRemotes addr7)
               @?= [ ("localhost", 22)
                   , ("myhost", 22)
                   ]

addr8 = T.pack "my.host.org alg hash"
testParse8 = testCase "single FQDN address parse"
             $ parseRemotes addr8
             @?= [SSHRemote (SSH1Addr $ RemoteDNS ["org", "host", "my"]) "alg" "hash"]
testTgtAddr8 = testCase "single FQDN address"
               $ (map targetAddr $ parseRemotes addr8)
               @?= [ ("my.host.org", 22)]

addr9 = T.pack "localhost.com alg hash\nmy.host.org alg2 hash2\na.b.c.d.f.g alg3 hash3\n"
testParse9 = testCase "multiple FQDN parse"
             $ parseRemotes addr9
             @?= [ SSHRemote (SSH1Addr $ RemoteDNS ["com", "localhost"]) "alg" "hash"
                 , SSHRemote (SSH1Addr $ RemoteDNS ["org", "host", "my"]) "alg2" "hash2"
                 , SSHRemote (SSH1Addr $ RemoteDNS ["g", "f", "d", "c", "b", "a"]) "alg3" "hash3"
                 ]
testTgtAddr9 = testCase "multiple FQDN address"
               $ (map targetAddr $ parseRemotes addr9)
               @?= [ ("localhost.com", 22)
                   , ("my.host.org", 22)
                   , ("a.b.c.d.f.g", 22)
                   ]

addr12 = T.pack "[1.2.3.4]:56 alg hash"
testParse12 = testCase "single IPv4 port parse"
              $ parseRemotes addr12
              @?= [SSHRemote (SSH1Addr $ RemoteV4Port "1.2.3.4" 56) "alg" "hash"]
testTgtAddr12 = testCase "single IPv4 port address"
                $ (map targetAddr $ parseRemotes addr12)
                @?= [ ("1.2.3.4", 56) ]

addr13 = T.pack "[1.2.3.4]:5 alg hash\n[11.22.33.44]:9876 alg2 hash2\n"
testParse13 = testCase "multiple IPv4 port parse"
              $ parseRemotes addr13
              @?= [ SSHRemote (SSH1Addr $ RemoteV4Port "1.2.3.4" 5) "alg" "hash"
                  , SSHRemote (SSH1Addr $ RemoteV4Port "11.22.33.44" 9876) "alg2" "hash2"
                  ]
testTgtAddr13 = testCase "multiple IPv4 port address"
                $ (map targetAddr $ parseRemotes addr13)
                @?= [ ("1.2.3.4", 5)
                    , ("11.22.33.44", 9876)
                    ]

addr14 = T.pack "[::1]:1234 alg hash"
testParse14 = testCase "single IPv6 port address"
              $ parseRemotes addr14
              @?= [SSHRemote (SSH1Addr $ RemoteV6Port "::1" 1234) "alg" "hash"]
testTgtAddr14 = testCase "single IPv6 port address"
                $ (map targetAddr $ parseRemotes addr14)
                @?= [ ("::1", 1234) ]

addr15 = T.pack "[::1]:100 alg hash\n[11::2bed]:8 alg2 hash2\n"
testParse15 = testCase "multiple IPv4 port address parse"
              $ parseRemotes addr15
              @?= [ SSHRemote (SSH1Addr $ RemoteV6Port "::1" 100) "alg" "hash"
                  , SSHRemote (SSH1Addr $ RemoteV6Port "11::2bed" 8) "alg2" "hash2"
                  ]
testTgtAddr15 = testCase "multiple IPv6 port address"
                $ (map targetAddr $ parseRemotes addr15)
                @?= [ ("::1", 100)
                    , ("11::2bed", 8)
                    ]

addr16 = T.pack "[myhost]:234 alg hash"
testParse16 = testCase "single name port address parse"
              $ parseRemotes addr16
              @?= [SSHRemote (SSH1Addr $ RemoteDNSPort ["myhost"] 234) "alg" "hash"]
testTgtAddr16 = testCase "single name port address"
                $ (map targetAddr $ parseRemotes addr16)
                @?= [ ("myhost", 234) ]


addr17 = T.pack "[localhost]:80 alg hash\n[myhost]:8080 alg2 hash2\n"
testParse17 = testCase "multiple name port address parse"
              $ parseRemotes addr17
              @?= [ SSHRemote (SSH1Addr $ RemoteDNSPort ["localhost"] 80) "alg" "hash"
                  , SSHRemote (SSH1Addr $ RemoteDNSPort ["myhost"] 8080) "alg2" "hash2"
                  ]
testTgtAddr17 = testCase "multiple name port address"
                $ (map targetAddr $ parseRemotes addr17)
                @?= [ ("localhost", 80)
                    , ("myhost", 8080)
                    ]

addr18 = T.pack "[my.host.org]:975 alg hash"
testParse18 = testCase "single FQDN port address parse"
              $ parseRemotes addr18
              @?= [SSHRemote (SSH1Addr $ RemoteDNSPort ["org", "host", "my"] 975) "alg" "hash"]
testTgtAddr18 = testCase "single FQDN port address"
                $ (map targetAddr $ parseRemotes addr18)
                @?= [ ("my.host.org", 975) ]

addr19 = T.pack "[localhost.com]:79 alg hash\n[my.host.org]:135 alg2 hash2\n[a.b.c.d.f.g]:6 alg3 hash3\n"
testParse19 = testCase "multiple FQDN port address parse"
              $ parseRemotes addr19
              @?= [ SSHRemote (SSH1Addr $ RemoteDNSPort ["com", "localhost"] 79) "alg" "hash"
                  , SSHRemote (SSH1Addr $ RemoteDNSPort ["org", "host", "my"] 135) "alg2" "hash2"
                  , SSHRemote (SSH1Addr $ RemoteDNSPort ["g", "f", "d", "c", "b", "a"] 6) "alg3" "hash3"
                  ]
testTgtAddr19 = testCase "multiple FQDN port address"
                $ (map targetAddr $ parseRemotes addr19)
                @?= [ ("localhost.com", 79)
                    , ("my.host.org", 135)
                    , ("a.b.c.d.f.g", 6)
                    ]

testParse20 = testCase "single hashed address parse"
              $ let hash = "|1|KRWKNXaEs155ig4mQkpRu5S7/qM=|EL9HQZe22u+xgX7WK7x+794IN6o="
                in parseRemotes (T.pack $ hash <> " alg hash")
              @?= [SSHRemote (SSH1Addr $ RemoteHashed hash) "alg" "hash"]
testTgtAddr20 = testCase "single hashed address"
                $ let hash = "|1|KRWKNXaEs155ig4mQkpRu5S7/qM=|EL9HQZe22u+xgX7WK7x+794IN6o="
                      addr20 = T.pack $ hash <> " alg hash"
                  in (map targetAddr $ parseRemotes addr20)
                @?= [ ("[{hashed}]", 22) ]


testParse21 = testCase "multiple hashed address parse"
              $ let hash1 = "|1|KRWKNXaEs155ig4mQkpRu5S7/qM=|EL9HQZe22u+xgX7WK7x+794IN6o="
                    hash2 = "|1|KRKNXaWE155igs4mkpRu5QS7/qM=|ELHQZe922+xgX7uWKx+7947IN6o="
                    hash3 = "|1|AAAAAAAAAAAAAAAAAAAAAAAAAAAA|BBBBBBBBBBBBBBBBBBBBBBBBBBB="
                in parseRemotes (T.pack $ hash1 <> " alg hash\n"
                                 <> hash2 <> " alg2 hash2\n"
                                 <> hash3 <> " alg3 hash3")
                   @?= [ SSHRemote (SSH1Addr $ RemoteHashed hash1) "alg" "hash"
                       , SSHRemote (SSH1Addr $ RemoteHashed hash2) "alg2" "hash2"
                       , SSHRemote (SSH1Addr $ RemoteHashed hash3) "alg3" "hash3"
                       ]

testParse22 = testCase "multiple mixed parse"
              $ let hash1 = "|1|KRWKNXaEs155ig4mQkpRu5S7/qM=|EL9HQZe22u+xgX7WK7x+794IN6o="
                    hash2 = "|1|KRKNXaWE155igs4mkpRu5QS7/qM=|ELHQZe922+xgX7uWKx+7947IN6o="
                    hash3 = "|1|AAAAAAAAAAAAAAAAAAAAAAAAAAAA|BBBBBBBBBBBBBBBBBBBBBBBBBBB="
                    ipv61 = "::1"
                    ipv62 = "bad2::74e:b0de"
                    ipv41 = "127.0.0.1"
                    ipv42 = "9.22.8.33"
                    dns1 = "we.are.the.champions"
                    dns2 = "no.time"
                in parseRemotes (T.pack $ hash1 <> " alg hash\n"
                                 <> ipv41 <> " alg4 hash4\n"
                                 <> "localhost alg0 hash0\n"
                                 <> hash2 <> " alg2 hash2\n"
                                 <> ipv61 <> " alg5 hash5\n"
                                 <> "[" <> ipv42 <> "]:18 alg6 hash6\n"
                                 <> "[" <> dns1 <> "]:444 alg7 hash7\n"
                                 <> hash3 <> " alg3 hash3\n"
                                 <> "[" <> ipv62 <> "]:10101 alg8 hash8\n"
                                 <> dns2 <> " alg9 hash9\n"
                                )
                   @?= [ SSHRemote (SSH1Addr $ RemoteHashed hash1) "alg" "hash"
                       , SSHRemote (SSH1Addr $ RemoteV4 $ read ipv41) "alg4" "hash4"
                       , SSHRemote (SSH1Addr $ RemoteDNS ["localhost"]) "alg0" "hash0"
                       , SSHRemote (SSH1Addr $ RemoteHashed hash2) "alg2" "hash2"
                       , SSHRemote (SSH1Addr $ RemoteV6 $ read ipv61) "alg5" "hash5"
                       , SSHRemote (SSH1Addr $ RemoteV4Port (read ipv42) 18) "alg6" "hash6"
                       , SSHRemote (SSH1Addr $ RemoteDNSPort (map T.pack [ "champions"
                                                              , "the"
                                                              , "are"
                                                              , "we"
                                                              ] ) 444) "alg7" "hash7"
                       , SSHRemote (SSH1Addr $ RemoteHashed hash3) "alg3" "hash3"
                       , SSHRemote (SSH1Addr $ RemoteV6Port (read ipv62) 10101) "alg8" "hash8"
                       , SSHRemote (SSH1Addr $ RemoteDNS (map T.pack ["time", "no"])) "alg9" "hash9"
                       ]
testTgtAddr22 = testCase "multiple mixed address"
              $ let hash1 = "|1|KRWKNXaEs155ig4mQkpRu5S7/qM=|EL9HQZe22u+xgX7WK7x+794IN6o="
                    hash2 = "|1|KRKNXaWE155igs4mkpRu5QS7/qM=|ELHQZe922+xgX7uWKx+7947IN6o="
                    hash3 = "|1|AAAAAAAAAAAAAAAAAAAAAAAAAAAA|BBBBBBBBBBBBBBBBBBBBBBBBBBB="
                    ipv61 = "::1"
                    ipv62 = "bad2::74e:b0de"
                    ipv41 = "127.0.0.1"
                    ipv42 = "9.22.8.33"
                    dns1 = "we.are.the.champions"
                    dns2 = "no.time"
                in (map targetAddr $
                    parseRemotes (T.pack $ hash1 <> " alg hash\n"
                                  <> ipv41 <> " alg4 hash4\n"
                                  <> "localhost alg0 hash0\n"
                                  <> hash2 <> " alg2 hash2\n"
                                  <> ipv61 <> " alg5 hash5\n"
                                  <> "[" <> ipv42 <> "]:18 alg6 hash6\n"
                                  <> "[" <> dns1 <> "]:444 alg7 hash7\n"
                                  <> hash3 <> " alg3 hash3\n"
                                  <> "[" <> ipv62 <> "]:10101 alg8 hash8\n"
                                  <> dns2 <> " alg9 hash9\n"
                                 ))
                   @?= [ ("[{hashed}]", 22)
                       , (T.pack ipv41, 22)
                       , ("localhost", 22)
                       , ("[{hashed}]", 22)
                       , (T.pack ipv61, 22)
                       , (T.pack ipv42, 18)
                       , (T.pack dns1, 444)
                       , ("[{hashed}]", 22)
                       , (T.pack ipv62, 10101)
                       , (T.pack dns2, 22)
                       ]


testBestTgtAddr1 = testCase "ipv4 addr port first"
              $ (targetAddr $
                  SSHRemote (SSHAddrs
                             [ (RemoteV4Port "9.10.11.12" 13)
                             , (RemoteV4 "1.2.3.4")
                             , (RemoteV4 "11.22.33.44")
                             , (RemoteV6 "::1")
                             , (RemoteV6Port "::2" 3)
                             , (RemoteDNS ["foo", "bar"])
                             , (RemoteDNSPort ["cow", "moo"] 89)
                             , (RemoteHashed "|1|hash")
                             ]) "alg" "key")
              @?= ("9.10.11.12", 13)

testBestTgtAddr2 = testCase "ipv4 addr port middle"
              $ (targetAddr $
                  SSHRemote (SSHAddrs
                             [ (RemoteV6 "::1")
                             , (RemoteV6Port "::2" 3)
                             , (RemoteV4 "1.2.3.4")
                             , (RemoteV4Port "9.10.11.12" 13)
                             , (RemoteDNS ["foo", "bar"])
                             , (RemoteV4 "11.22.33.44")
                             , (RemoteDNSPort ["cow", "moo"] 89)
                             , (RemoteHashed "|1|hash")
                             ]) "alg" "key")
              @?= ("9.10.11.12", 13)

testBestTgtAddr3 = testCase "ipv4 port addr end"
              $ (targetAddr $
                  SSHRemote (SSHAddrs
                             [ (RemoteV6 "::1")
                             , (RemoteV6Port "::2" 3)
                             , (RemoteDNS ["foo", "bar"])
                             , (RemoteDNSPort ["cow", "moo"] 89)
                             , (RemoteHashed "|1|hash")
                             , (RemoteV4 "1.2.3.4")
                             , (RemoteV4Port "9.10.11.12" 13)
                             ]) "alg" "key")
              @?= ("9.10.11.12", 13)

testBestTgtAddr4 = testCase "ipv4 addr first"
              $ (targetAddr $
                  SSHRemote (SSHAddrs
                             [ (RemoteV4 "1.2.3.4")
                             , (RemoteV4 "11.22.33.44")
                             , (RemoteV6 "::1")
                             , (RemoteV6Port "::2" 3)
                             , (RemoteDNS ["foo", "bar"])
                             , (RemoteDNSPort ["cow", "moo"] 89)
                             , (RemoteHashed "|1|hash")
                             ]) "alg" "key")
              @?= ("1.2.3.4", 22)

testBestTgtAddr5 = testCase "ipv4 addr middle"
              $ (targetAddr $
                  SSHRemote (SSHAddrs
                             [ (RemoteV6 "::1")
                             , (RemoteV6Port "::2" 3)
                             , (RemoteV4 "1.2.3.4")
                             , (RemoteDNS ["foo", "bar"])
                             , (RemoteV4 "11.22.33.44")
                             , (RemoteDNSPort ["cow", "moo"] 89)
                             , (RemoteHashed "|1|hash")
                             ]) "alg" "key")
              @?= ("1.2.3.4", 22)

testBestTgtAddr6 = testCase "ipv4 addr end"
              $ (targetAddr $
                  SSHRemote (SSHAddrs
                             [ (RemoteV6 "::1")
                             , (RemoteV6Port "::2" 3)
                             , (RemoteDNS ["foo", "bar"])
                             , (RemoteDNSPort ["cow", "moo"] 89)
                             , (RemoteHashed "|1|hash")
                             , (RemoteV4 "1.2.3.4")
                             ]) "alg" "key")
              @?= ("1.2.3.4", 22)

testBestTgtAddr7 = testCase "ipv6 addr port first"
              $ (targetAddr $
                  SSHRemote (SSHAddrs
                             [ (RemoteV6Port "::2" 3)
                             , (RemoteV6 "::1")
                             , (RemoteDNS ["foo", "bar"])
                             , (RemoteDNSPort ["cow", "moo"] 89)
                             , (RemoteHashed "|1|hash")
                             ]) "alg" "key")
              @?= ("::2", 3)

testBestTgtAddr8 = testCase "ipv6 addr port middle"
              $ (targetAddr $
                  SSHRemote (SSHAddrs
                             [ (RemoteV6 "::1")
                             , (RemoteDNS ["foo", "bar"])
                             , (RemoteV6Port "::2" 3)
                             , (RemoteDNSPort ["cow", "moo"] 89)
                             , (RemoteHashed "|1|hash")
                             ]) "alg" "key")
              @?= ("::2", 3)

testBestTgtAddr9 = testCase "ipv6 addr port end"
              $ (targetAddr $
                  SSHRemote (SSHAddrs
                             [ (RemoteV6 "::1")
                             , (RemoteDNS ["foo", "bar"])
                             , (RemoteDNSPort ["cow", "moo"] 89)
                             , (RemoteHashed "|1|hash")
                             , (RemoteV6Port "::2" 3)
                             ]) "alg" "key")
              @?= ("::2", 3)

testBestTgtAddr10 = testCase "ipv6 addr first"
              $ (targetAddr $
                  SSHRemote (SSHAddrs
                             [ (RemoteV6 "::1")
                             , (RemoteDNS ["foo", "bar"])
                             , (RemoteDNSPort ["cow", "moo"] 89)
                             , (RemoteHashed "|1|hash")
                             ]) "alg" "key")
              @?= ("::1", 22)

testBestTgtAddr11 = testCase "ipv6 addr middle"
              $ (targetAddr $
                  SSHRemote (SSHAddrs
                             [ (RemoteDNS ["foo", "bar"])
                             , (RemoteV6 "::1")
                             , (RemoteDNSPort ["cow", "moo"] 89)
                             , (RemoteHashed "|1|hash")
                             ]) "alg" "key")
              @?= ("::1", 22)

testBestTgtAddr12 = testCase "ipv6 addr end"
              $ (targetAddr $
                  SSHRemote (SSHAddrs
                             [ (RemoteDNS ["foo", "bar"])
                             , (RemoteDNSPort ["cow", "moo"] 89)
                             , (RemoteHashed "|1|hash")
                             , (RemoteV6 "::1")
                             ]) "alg" "key")
              @?= ("::1", 22)

testBestTgtAddr13 = testCase "dns addr port first"
              $ (targetAddr $
                  SSHRemote (SSHAddrs
                             [ (RemoteDNSPort ["cow", "moo"] 89)
                             , (RemoteDNS ["foo", "bar"])
                             , (RemoteHashed "|1|hash")
                             ]) "alg" "key")
              @?= ("moo.cow", 89)

testBestTgtAddr14 = testCase "dns addr port middle"
              $ (targetAddr $
                  SSHRemote (SSHAddrs
                             [ (RemoteDNS ["foo", "bar"])
                             , (RemoteDNSPort ["cow", "moo"] 89)
                             , (RemoteHashed "|1|hash")
                             ]) "alg" "key")
              @?= ("moo.cow", 89)

testBestTgtAddr15 = testCase "dns addr port end"
              $ (targetAddr $
                  SSHRemote (SSHAddrs
                             [ (RemoteDNS ["foo", "bar"])
                             , (RemoteHashed "|1|hash")
                             , (RemoteDNSPort ["cow", "moo"] 89)
                             ]) "alg" "key")
              @?= ("moo.cow", 89)

testBestTgtAddr16 = testCase "dns addr first"
              $ (targetAddr $
                  SSHRemote (SSHAddrs
                             [ (RemoteDNS ["foo", "bar"])
                             , (RemoteHashed "|1|hash")
                             ]) "alg" "key")
              @?= ("bar.foo", 22)

testBestTgtAddr17 = testCase "dns addr middle"
              $ (targetAddr $
                  SSHRemote (SSHAddrs
                             [ (RemoteHashed "|1|hash")
                             , (RemoteDNS ["foo", "bar"])
                             , (RemoteHashed "|1|hash")
                             ]) "alg" "key")
              @?= ("bar.foo", 22)

testBestTgtAddr18 = testCase "dns addr end"
              $ (targetAddr $
                  SSHRemote (SSHAddrs
                             [ (RemoteHashed "|1|hash")
                             , (RemoteDNS ["foo", "bar"])
                             ]) "alg" "key")
              @?= ("bar.foo", 22)

testBestTgtAddr19 = testCase "settle for hashed"
              $ (targetAddr $
                  SSHRemote (SSHAddrs
                             [ (RemoteHashed "|1|hash1")
                             , (RemoteHashed "|1|hash2")
                             , (RemoteHashed "|1|hash3")
                             ]) "alg" "key")
              @?= ("[{hashed}]", 22)