diff options
Diffstat (limited to 'testkiki/testkiki.hs')
-rw-r--r-- | testkiki/testkiki.hs | 163 |
1 files changed, 141 insertions, 22 deletions
diff --git a/testkiki/testkiki.hs b/testkiki/testkiki.hs index 19c54dc..808900a 100644 --- a/testkiki/testkiki.hs +++ b/testkiki/testkiki.hs | |||
@@ -18,6 +18,10 @@ import System.IO | |||
18 | import Control.Applicative | 18 | import Control.Applicative |
19 | import Control.Monad | 19 | import Control.Monad |
20 | import qualified Data.ByteString.Char8 as B | 20 | import qualified Data.ByteString.Char8 as B |
21 | import Data.Time.Clock | ||
22 | import Data.Time.Clock.POSIX | ||
23 | import Data.IORef | ||
24 | import Crypto.Hash.SHA1 (hash) | ||
21 | 25 | ||
22 | #if !MIN_VERSION_base(4,7,0) | 26 | #if !MIN_VERSION_base(4,7,0) |
23 | setEnv k v = System.Posix.Env.setEnv k v True | 27 | setEnv k v = System.Posix.Env.setEnv k v True |
@@ -34,7 +38,7 @@ main = do | |||
34 | args <- getArgs | 38 | args <- getArgs |
35 | cwd <- getCurrentDirectory | 39 | cwd <- getCurrentDirectory |
36 | let chomp x = takeWhile (/='\n') x | 40 | let chomp x = takeWhile (/='\n') x |
37 | date <- maybe (return "") | 41 | date <- maybe (return "") |
38 | (\x -> chomp <$> readProcess x ["+%Y-%m-%d-%H%M%S"] "") =<< findExecutable "date" | 42 | (\x -> chomp <$> readProcess x ["+%Y-%m-%d-%H%M%S"] "") =<< findExecutable "date" |
39 | 43 | ||
40 | let tdir = cwd </> "TESTS" </> date | 44 | let tdir = cwd </> "TESTS" </> date |
@@ -57,21 +61,21 @@ main = do | |||
57 | createDirectoryIfMissing True chrootdir | 61 | createDirectoryIfMissing True chrootdir |
58 | createDirectoryIfMissing True gnupghomedir | 62 | createDirectoryIfMissing True gnupghomedir |
59 | let config = TKS { chroot = chrootdir , gnupghome = gnupghomedir } | 63 | let config = TKS { chroot = chrootdir , gnupghome = gnupghomedir } |
60 | print config | 64 | print config |
61 | putStrLn "===" | 65 | putStrLn "===" |
62 | doTests config | 66 | doTests config |
63 | 67 | ||
64 | doTests :: TestKikiSettings -> IO () | 68 | doTests :: TestKikiSettings -> IO () |
65 | doTests tkConfig = hspec $ do | 69 | doTests tkConfig = hspec $ do |
66 | {- | 70 | {- |
67 | -- Example of shouldThrow | 71 | -- Example of shouldThrow |
68 | describe "TODO: error" $ | 72 | describe "TODO: error" $ |
69 | it "throws an exception" $ | 73 | it "throws an exception" $ |
70 | evaluate (error "TODO:testsuite") `shouldThrow` anyException | 74 | evaluate (error "TODO:testsuite") `shouldThrow` anyException |
71 | -} | 75 | -} |
72 | 76 | ||
73 | -- **** kiki tests ***** | 77 | -- **** kiki tests ***** |
74 | describe "kiki init" $ do | 78 | describe "kiki init" $ do |
75 | it "honors GNUPGHOME environment variable" $ do | 79 | it "honors GNUPGHOME environment variable" $ do |
76 | let kiki = kiki'Env cfg | 80 | let kiki = kiki'Env cfg |
77 | cfg = appendpaths tkConfig "0" | 81 | cfg = appendpaths tkConfig "0" |
@@ -80,11 +84,11 @@ doTests tkConfig = hspec $ do | |||
80 | it "creates parent directories with --homedir" $ do | 84 | it "creates parent directories with --homedir" $ do |
81 | let home = "home" </> "tester" | 85 | let home = "home" </> "tester" |
82 | cfg = appendpaths tkConfig "1" | 86 | cfg = appendpaths tkConfig "1" |
83 | kiki = kiki'Env'And'HomeArg cfg | 87 | kiki = kiki'Env'And'HomeArg cfg |
84 | { gnupghome = home </> ".gnupg" } | 88 | { gnupghome = home </> ".gnupg" } |
85 | output <- kiki ["init"] | 89 | output <- kiki ["init"] |
86 | b <- doesDirectoryExist (chroot cfg </> home) | 90 | b <- doesDirectoryExist (chroot cfg </> home) |
87 | -- isInfixOf "New packet" output | 91 | -- isInfixOf "New packet" output |
88 | b `shouldBe` True | 92 | b `shouldBe` True |
89 | 93 | ||
90 | it "creates new secring honoring GNUPGHOME" $ do | 94 | it "creates new secring honoring GNUPGHOME" $ do |
@@ -101,25 +105,134 @@ doTests tkConfig = hspec $ do | |||
101 | createDirectoryIfMissing True (chroot cfg </> "root" </> ".gnupg") | 105 | createDirectoryIfMissing True (chroot cfg </> "root" </> ".gnupg") |
102 | output <- kiki ["init"] | 106 | output <- kiki ["init"] |
103 | let p = (chroot cfg </> "root" </> ".gnupg" </> "secring.gpg") | 107 | let p = (chroot cfg </> "root" </> ".gnupg" </> "secring.gpg") |
104 | putStrLn $ "Does exist? " ++ show p | ||
105 | b <- doesFileExist p | 108 | b <- doesFileExist p |
106 | -- (isInfixOf "New packet" output && b ) | 109 | let c = isInfixOf "New packet" output |
107 | b `shouldBe` True | 110 | (b,c) `shouldBe` (True,True) |
111 | |||
112 | describe "kiki export-secret" $ do | ||
113 | |||
114 | t <- runIO $ getPOSIXTime | ||
115 | mtime1 <- runIO $ newIORef (posixSecondsToUTCTime t) | ||
116 | mtime2 <- runIO $ newIORef (posixSecondsToUTCTime t) | ||
117 | hash1 <- runIO $ newIORef "" | ||
118 | hash2 <- runIO $ newIORef "" | ||
108 | 119 | ||
109 | describe "kiki export-public" $ do | ||
110 | it "does not modify mtime of GNUPGHOME keyrings" $ do | ||
111 | pending | ||
112 | it "creates external pem files which do not exist" $ do | 120 | it "creates external pem files which do not exist" $ do |
113 | pending | 121 | let cfg' = appendpaths tkConfig "3" |
114 | it "does not leak secret data from GNUPGHOME keyrings" $ do | 122 | home = chroot cfg' </> "root" |
115 | pending | 123 | gnuhome = home </> ".gnupg" |
124 | cfg = cfg' { gnupghome = gnuhome } | ||
125 | kiki = kiki'Env'NoChroot cfg | ||
126 | secs = home </> "secs" | ||
127 | tags = [ "tor", "ssh-client", "ssh-server", "ipsec" ] | ||
128 | files = map ((++ ".sec") . (secs </>)) tags | ||
129 | extraArgs = zipWith (\x y -> concat [x,"=",y]) tags files | ||
130 | |||
131 | tsec0 <- getModificationTime (gnuhome </> "secring.gpg") | ||
132 | tpub0 <- getModificationTime (gnuhome </> "pubring.gpg") | ||
133 | |||
134 | writeIORef mtime1 tsec0 | ||
135 | writeIORef mtime2 tpub0 | ||
136 | |||
137 | hsec0 <- hash <$> B.readFile (gnuhome </> "secring.gpg") | ||
138 | hpub0 <- hash <$> B.readFile (gnuhome </> "pubring.gpg") | ||
139 | |||
140 | writeIORef hash1 hsec0 | ||
141 | writeIORef hash2 hpub0 | ||
142 | |||
143 | createDirectoryIfMissing True secs | ||
144 | kiki ("export-secret":extraArgs) | ||
145 | exists <- mapM doesFileExist files | ||
146 | exists `shouldBe` replicate (length files) True | ||
147 | |||
148 | it "does not modify mtime nor SHA1 of GNUPGHOME keyrings" $ do | ||
149 | let cfg' = appendpaths tkConfig "3" | ||
150 | home = chroot cfg' </> "root" | ||
151 | gnuhome = home </> ".gnupg" | ||
152 | -- mtimes | ||
153 | tsec0 <- readIORef mtime1 | ||
154 | tpub0 <- readIORef mtime2 | ||
155 | tsec <- getModificationTime (gnuhome </> "secring.gpg") | ||
156 | tpub <- getModificationTime (gnuhome </> "pubring.gpg") | ||
157 | -- SHA1s | ||
158 | hsec0 <- readIORef hash1 | ||
159 | hpub0 <- readIORef hash2 | ||
160 | hsec <- hash <$> B.readFile (gnuhome </> "secring.gpg") | ||
161 | hpub <- hash <$> B.readFile (gnuhome </> "pubring.gpg") | ||
162 | ([ tsec , tpub], hsec == hsec0, hpub == hpub0 ) `shouldBe` ([ tsec0,tpub0],True,True) | ||
116 | 163 | ||
117 | describe "kiki export-secret" $ do | ||
118 | it "fails when public keys in existing PEM files do not match" $ do | 164 | it "fails when public keys in existing PEM files do not match" $ do |
119 | pending | 165 | pending |
120 | it "updates public pem files to private ones when told to" $ do | 166 | it "updates public pem files to private ones when told to" $ do |
121 | pending | 167 | pending |
168 | |||
169 | |||
170 | describe "kiki export-public" $ do | ||
171 | |||
172 | t <- runIO $ getPOSIXTime | ||
173 | mtime1 <- runIO $ newIORef (posixSecondsToUTCTime t) | ||
174 | mtime2 <- runIO $ newIORef (posixSecondsToUTCTime t) | ||
175 | hash1 <- runIO $ newIORef "" | ||
176 | hash2 <- runIO $ newIORef "" | ||
177 | |||
122 | it "creates external pem files which do not exist" $ do | 178 | it "creates external pem files which do not exist" $ do |
179 | let cfg' = appendpaths tkConfig "3" | ||
180 | home = chroot cfg' </> "root" | ||
181 | gnuhome = home </> ".gnupg" | ||
182 | cfg = cfg' { gnupghome = gnuhome } | ||
183 | kiki = kiki'Env'NoChroot cfg | ||
184 | pubs = home </> "pubs" | ||
185 | tags = [ "tor", "ssh-client", "ssh-server", "ipsec" ] | ||
186 | files = map ((++ ".pub") . (pubs </>)) tags | ||
187 | extraArgs = zipWith (\x y -> concat [x,"=",y]) tags files | ||
188 | |||
189 | tsec0 <- getModificationTime (gnuhome </> "secring.gpg") | ||
190 | tpub0 <- getModificationTime (gnuhome </> "pubring.gpg") | ||
191 | writeIORef mtime1 tsec0 -- <$> getModificationTime (gnuhome </> "secring.gpg") | ||
192 | writeIORef mtime2 tpub0 -- <$> getModificationTime (gnuhome </> "pubring.gpg") | ||
193 | |||
194 | hashSec0 <- hash <$> B.readFile (gnuhome </> "secring.gpg") | ||
195 | hashPub0 <- hash <$> B.readFile (gnuhome </> "pubring.gpg") | ||
196 | |||
197 | writeIORef hash1 hashSec0 -- . hash <$> B.readFile (gnuhome </> "secring.gpg") | ||
198 | writeIORef hash2 hashPub0 -- . hash <$> B.readFile (gnuhome </> "pubring.gpg") | ||
199 | |||
200 | createDirectoryIfMissing True pubs | ||
201 | kiki ("export-public":extraArgs) | ||
202 | exists <- mapM doesFileExist files | ||
203 | exists `shouldBe` replicate (length files) True | ||
204 | |||
205 | it "does not modify mtime nor SHA1 of GNUPGHOME keyrings" $ do | ||
206 | let cfg' = appendpaths tkConfig "3" | ||
207 | home = chroot cfg' </> "root" | ||
208 | gnuhome = home </> ".gnupg" | ||
209 | -- mtimes | ||
210 | tsec0 <- readIORef mtime1 | ||
211 | tpub0 <- readIORef mtime2 | ||
212 | tsec <- getModificationTime (gnuhome </> "secring.gpg") | ||
213 | tpub <- getModificationTime (gnuhome </> "pubring.gpg") | ||
214 | -- SHA1s | ||
215 | hsec0 <- readIORef hash1 | ||
216 | hpub0 <- readIORef hash2 | ||
217 | hsec <- hash <$> B.readFile (gnuhome </> "secring.gpg") | ||
218 | hpub <- hash <$> B.readFile (gnuhome </> "pubring.gpg") | ||
219 | ([ tsec , tpub], hsec == hsec0, hpub == hpub0 ) `shouldBe` ([ tsec0,tpub0],True,True) | ||
220 | |||
221 | it "creates public PEM files smaller than exported private PEMs" $ do | ||
222 | let cfg' = appendpaths tkConfig "3" | ||
223 | home = chroot cfg' </> "root" | ||
224 | gnuhome = home </> ".gnupg" | ||
225 | pubs = home </> "pubs" | ||
226 | secs = home </> "secs" | ||
227 | tags = [ "tor", "ssh-client", "ssh-server", "ipsec" ] | ||
228 | filesPub = map ((++ ".pub") . (pubs </>)) tags | ||
229 | filesSec = map ((++ ".sec") . (secs </>)) tags | ||
230 | lengthsPub <- map B.length <$> mapM (B.readFile) filesPub | ||
231 | lengthsSec <- map B.length <$> mapM (B.readFile) filesSec | ||
232 | let compares = zipWith (<) lengthsPub lengthsSec | ||
233 | compares `shouldBe` replicate (length tags) True | ||
234 | |||
235 | it "does not leak secret data from GNUPGHOME keyrings" $ do | ||
123 | pending | 236 | pending |
124 | 237 | ||
125 | -- **** cokiki tests ***** | 238 | -- **** cokiki tests ***** |
@@ -142,12 +255,18 @@ doTests tkConfig = hspec $ do | |||
142 | pending | 255 | pending |
143 | where | 256 | where |
144 | kiki'Env config args = do | 257 | kiki'Env config args = do |
145 | setEnv "GNUPGHOME" (gnupghome config) | 258 | setEnv "GNUPGHOME" (chroot config </> gnupghome config) |
146 | let args' = args ++ ["--chroot=" ++ chroot config] | 259 | let args' = args ++ ["--chroot=" ++ chroot config] |
147 | r <- readProcess "./dist/build/kiki/kiki" args' "" | 260 | r <- readProcess "./dist/build/kiki/kiki" args' "" |
148 | unsetEnv "GNUPGHOME" | 261 | unsetEnv "GNUPGHOME" |
149 | return r | 262 | return r |
150 | 263 | ||
264 | kiki'Env'NoChroot config args = do | ||
265 | setEnv "GNUPGHOME" (chroot config </> gnupghome config) | ||
266 | r <- readProcess "./dist/build/kiki/kiki" args "" | ||
267 | unsetEnv "GNUPGHOME" | ||
268 | return r | ||
269 | |||
151 | kiki'No'Env'No'Home config args = do | 270 | kiki'No'Env'No'Home config args = do |
152 | let args' = args ++ ["--chroot=" ++ chroot config] | 271 | let args' = args ++ ["--chroot=" ++ chroot config] |
153 | readProcess "./dist/build/kiki/kiki" args' "" | 272 | readProcess "./dist/build/kiki/kiki" args' "" |
@@ -157,7 +276,7 @@ doTests tkConfig = hspec $ do | |||
157 | readProcess "./dist/build/kiki/kiki" args' "" | 276 | readProcess "./dist/build/kiki/kiki" args' "" |
158 | 277 | ||
159 | kiki'Env'And'HomeArg config args = do | 278 | kiki'Env'And'HomeArg config args = do |
160 | setEnv "GNUPGHOME" (gnupghome config) | 279 | setEnv "GNUPGHOME" (chroot config </> gnupghome config) |
161 | let args' = args ++ ["--chroot=" ++ chroot config,"--homedir=" ++ gnupghome config] | 280 | let args' = args ++ ["--chroot=" ++ chroot config,"--homedir=" ++ gnupghome config] |
162 | r <- readProcess "./dist/build/kiki/kiki" args' "" | 281 | r <- readProcess "./dist/build/kiki/kiki" args' "" |
163 | unsetEnv "GNUPGHOME" | 282 | unsetEnv "GNUPGHOME" |