Add the parseReply function to the Confd utils
authorMichele Tartara <mtartara@google.com>
Mon, 17 Dec 2012 16:10:28 +0000 (16:10 +0000)
committerMichele Tartara <mtartara@google.com>
Thu, 20 Dec 2012 16:17:06 +0000 (17:17 +0100)
This function will be used by the Haskell Confd client to parse the replies
it receives from the server.

Unit test is included as well.

Signed-off-by: Michele Tartara <mtartara@google.com>
Reviewed-by: Iustin Pop <iustin@google.com>

htest/Test/Ganeti/Confd/Utils.hs
htools/Ganeti/Confd/Utils.hs

index 8c1590e..9d27deb 100644 (file)
@@ -67,6 +67,21 @@ prop_req_sign key (NonNegative timestamp) (Positive bad_delta)
                     \ timestamp, got " ++ show ts_bad)
        (ts_bad ==? BasicTypes.Bad "Too old/too new timestamp or clock skew")
 
+-- | Tests that a ConfdReply can be properly encoded, signed and parsed using
+-- the proper salt, but fails parsing with the wrong salt.
+prop_rep_salt :: Hash.HashKey     -- ^ The hash key
+              -> Confd.ConfdReply -- ^ A Confd reply
+              -> Property
+prop_rep_salt hmac reply =
+  forAll arbitrary $ \salt1 ->
+  forAll (arbitrary `suchThat` (/= salt1)) $ \salt2 ->
+  let innerMsg = J.encode reply
+      msg = J.encode $ Confd.Utils.signMessage hmac salt1 innerMsg
+  in
+    Confd.Utils.parseReply hmac msg salt1 ==? BasicTypes.Ok (innerMsg, reply)
+      .&&. Confd.Utils.parseReply hmac msg salt2 ==?
+           BasicTypes.Bad "The received salt differs from the expected salt"
+
 -- | Tests that signing with a different key fails detects failure
 -- correctly.
 prop_bad_key :: String             -- ^ Salt
@@ -88,5 +103,6 @@ prop_bad_key salt crq =
 
 testSuite "Confd/Utils"
   [ 'prop_req_sign
+  , 'prop_rep_salt
   , 'prop_bad_key
   ]
index d19c9cf..770c6f6 100644 (file)
@@ -30,6 +30,7 @@ module Ganeti.Confd.Utils
   ( getClusterHmac
   , parseSignedMessage
   , parseRequest
+  , parseReply
   , signMessage
   , getCurrentTime
   ) where
@@ -65,8 +66,8 @@ parseSignedMessage key str = do
            else Bad "HMAC verification failed"
   return (salt, msg, parsedMsg)
 
--- | Message parsing. This can either result in a good, valid message,
--- or fail in the Result monad.
+-- | Message parsing. This can either result in a good, valid request
+-- message, or fail in the Result monad.
 parseRequest :: HashKey -> String -> Integer
              -> Result (String, ConfdRequest)
 parseRequest hmac msg curtime = do
@@ -76,6 +77,17 @@ parseRequest hmac msg curtime = do
     then fail "Too old/too new timestamp or clock skew"
     else return (origmsg, request)
 
+-- | Message parsing. This can either result in a good, valid reply
+-- message, or fail in the Result monad.
+-- It also checks that the salt in the message corresponds to the one
+-- that is expected
+parseReply :: HashKey -> String -> String -> Result (String, ConfdReply)
+parseReply hmac msg expSalt = do
+  (salt, origmsg, reply) <- parseSignedMessage hmac msg
+  if salt /= expSalt
+    then fail "The received salt differs from the expected salt"
+    else return (origmsg, reply)
+
 -- | Signs a message with a given key and salt.
 signMessage :: HashKey -> String -> String -> SignedMessage
 signMessage key salt msg =