GSSGetMic
authorMark Donnelly <mark@painless-security.com>
Wed, 14 May 2014 19:42:48 +0000 (15:42 -0400)
committerMark Donnelly <mark@painless-security.com>
Wed, 14 May 2014 19:42:48 +0000 (15:42 -0400)
* Load parameters from JSON
* Sends the arguments to the GSS function correctly
* Reads arguments back out of the GSS function correctly
* Formats the return arguments as JSON correctly

json_gssapi/CMakeLists.txt
json_gssapi/src/GSSGetMic.cpp [new file with mode: 0644]
json_gssapi/src/GSSGetMic.h [new file with mode: 0644]
json_gssapi/test/CMakeLists.txt
json_gssapi/test/GSSGetMicTest.cpp [new file with mode: 0644]
json_gssapi/test/GSSGetMicTest.h [new file with mode: 0644]
json_gssapi/test/command_mocks/MockGetMic.cpp [new file with mode: 0644]
json_gssapi/test/command_mocks/MockGetMic.h [new file with mode: 0644]

index 2ac73d0..16b7441 100644 (file)
@@ -7,7 +7,8 @@ add_executable(json_gssapi src/datamodel/GSSName.cpp
                            src/datamodel/GSSOIDSet.cpp
                            src/datamodel/GSSBuffer.cpp
                            src/datamodel/GSSCredential.cpp
-                           src/GSSException.cpp 
+                           src/GSSException.cpp
+                           src/GSSGetMic.cpp
                            src/GSSCreateSecContextCommand.cpp
                            src/GSSCommand.cpp 
                            src/GSSImportName.cpp
diff --git a/json_gssapi/src/GSSGetMic.cpp b/json_gssapi/src/GSSGetMic.cpp
new file mode 100644 (file)
index 0000000..8782186
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2014 <copyright holder> <email>
+ *
+ * For license details, see the LICENSE file in the root of this project.
+ *
+ */
+
+#include "GSSGetMic.h"
+
+#include <stdexcept>
+#include <mit-krb5/gssapi/gssapi.h>
+
+GSSGetMic::GSSGetMic ( JSONObject* params, gss_get_mic_type fn )
+{
+    this->function = fn;
+    loadParameters(params);
+}
+
+/*
+ * {"method": "gss_get_mic",
+ *  "arguments":
+ *  {
+ *       "context_handle": "#######",
+ *       "qop_req": "GSS_C_QOP_DEFAULT",
+ *       "input_message": "mary had a little lamb"
+ *  }
+ * }
+ * 
+ */
+bool GSSGetMic::loadParameters ( JSONObject* params )
+{
+  std::string sQopReq, sConfReq, sInputMessage;
+  
+  /* Error checking */
+  /* Setup */
+  // Should I zeroOut?
+  
+  /* Main processing */
+  
+  /***********
+   * QOP_REQ *
+   ***********/
+  if ( ! params->get("arguments").get("qop_req").isNull() )
+  {
+    if (params->get("arguments").get("qop_req").isString())
+    {
+      sQopReq = params->get("arguments").get("qop_req").string();
+      if (sQopReq == "GSS_C_QOP_DEFAULT")
+        this->qop_req = GSS_C_QOP_DEFAULT;
+      else
+        throw std::invalid_argument( std::string("Invalid QOP type given: ") + sQopReq );
+    } else if (params->get("arguments").get("qop_req").isInteger())
+      this->qop_req = (gss_cred_usage_t)( params->get("arguments").get("qop_req").integer() );
+    else
+      throw std::invalid_argument( "Unrecognized argument type for qop_req." );
+  }
+  
+  /*****************
+   * input_message *
+   *****************/
+  if ( ! params->get("arguments").get("input_message").isNull() )
+  {
+    sInputMessage = params->get("arguments").get("input_message").string();
+    this->inputMessage.setValue(sInputMessage);
+  }
+  
+  /* Cleanup */
+  /* Return */
+  return true;
+}
+
+void GSSGetMic::execute()
+{
+    gss_buffer_desc output;
+    
+    this->retVal =  this->function(
+      &(this->minor_status),
+      this->context,
+      this->qop_req,
+      this->inputMessage.toGss(),
+      &output
+    );
+    
+    this->outputToken.setValue( (char *)(output.value), output.length );
+}
+
+JSONObject* GSSGetMic::toJSON()
+{
+  /* Variables */
+  const char *conf_state;
+  JSONObject *ret = new JSONObject();
+  JSONObject *values = new JSONObject();
+  
+  /* Error checking */
+  
+  /* Setup */
+  
+  /* Main */
+  // Return Values
+  // Easy stuff
+  values->set("major_status", this->retVal);
+  values->set("minor_status", this->minor_status);
+  
+  values->set(
+    "output_token",
+    this->outputToken.toString().c_str()
+  );
+  
+  // Put it all together.
+  ret->set("command", "gss_get_mic");
+  ret->set("return_values", *values);
+  
+  /* Cleanup */
+  
+  /* Return */
+  return(ret);
+}
diff --git a/json_gssapi/src/GSSGetMic.h b/json_gssapi/src/GSSGetMic.h
new file mode 100644 (file)
index 0000000..956a0de
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014 <copyright holder> <email>
+ *
+ * For license details, see the LICENSE file in the root of this project.
+ *
+ */
+
+#ifndef GSSGETMIC_H
+#define GSSGETMIC_H
+
+#include "GSSCommand.h"
+#include "datamodel/GSSBuffer.h"
+#include <gssapi/gssapi.h>
+
+typedef OM_uint32 (*gss_get_mic_type) (
+    OM_uint32 *,        /* minor_status */
+    gss_ctx_id_t,       /* context_handle */
+    gss_qop_t,          /* qop_req */
+    gss_buffer_t,       /* message_buffer */
+    gss_buffer_t);      /* message_token */
+
+class GSSGetMic : public GSSCommand
+{
+public:
+    GSSGetMic( gss_get_mic_type fn = &gss_get_mic ) : function(fn) {};
+    GSSGetMic( JSONObject *params, gss_get_mic_type fn = &gss_get_mic);
+    ~GSSGetMic() {};
+    virtual void execute();
+    virtual JSONObject* toJSON();
+    
+    gss_get_mic_type getGSSFunction() const { return(function); }
+
+    // Setters
+    void setQopReq(gss_qop_t req) { this->qop_req = req; }
+    void setInputMessage ( GSSBuffer* input ) { inputMessage.setValue(input->toString()); };
+    void setContextHandle ( gss_ctx_id_t context_handle) { context = context_handle; }
+    
+    // Getters
+    gss_ctx_id_t getContextHandle() const { return(this->context); }
+    gss_qop_t    getQopReq() const { return(this->qop_req); }
+    GSSBuffer    getInputMessage() const { return(this->inputMessage); }
+    GSSBuffer    getOutputToken() const { return(this->outputToken); }
+  
+private:
+    OM_uint32        retVal;
+    OM_uint32        minor_status;
+
+    gss_get_mic_type function;
+    gss_ctx_id_t     context;
+    gss_qop_t        qop_req;
+    GSSBuffer        inputMessage;
+    GSSBuffer        outputToken;
+    
+    bool loadParameters( JSONObject *params );
+};
+
+#endif // GSSGETMIC_H
index ee516c0..6098aa8 100644 (file)
@@ -1,11 +1,13 @@
 include_directories(${CMAKE_SOURCE_DIR}/src)
 
 add_executable(test GSSExceptionTest.cpp 
-                    GSSAcquireCredTest.cpp
+                    GSSAcquireCredTest.cpp 
+                    GSSGetMicTest.cpp
                     GSSWrapTest.cpp 
                     GSSUnwrapTest.cpp
                     command_mocks/InitSecContextMock.cpp
-                    command_mocks/MockAcquireCred.cpp  
+                    command_mocks/MockAcquireCred.cpp
+                    command_mocks/MockGetMic.cpp
                     command_mocks/MockUnwrap.cpp
                     command_mocks/MockWrap.cpp 
                     GSSCreateSecContextTest.cpp 
@@ -16,6 +18,7 @@ add_executable(test GSSExceptionTest.cpp
                     ../src/util_json.cpp 
                     ../src/GSSImportName.cpp
                     ../src/GSSException.cpp
+                    ../src/GSSGetMic.cpp
                     ../src/GSSAcquireCred.cpp
                     ../src/GSSUnwrap.cpp
                     ../src/GSSWrap.cpp
diff --git a/json_gssapi/test/GSSGetMicTest.cpp b/json_gssapi/test/GSSGetMicTest.cpp
new file mode 100644 (file)
index 0000000..6600be8
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2014 <copyright holder> <email>
+ *
+ * For license details, see the LICENSE file in the root of this project.
+ *
+ */
+
+#include "GSSGetMicTest.h"
+#include "command_mocks/MockGetMic.h"
+#include "GSSGetMic.h"
+#include <gssapi/gssapi.h>
+
+CPPUNIT_TEST_SUITE_REGISTRATION( GSSGetMicTest );
+
+/* 
+ * a mock of the gss_import_name call
+ * 
+ * Basically, just copy the arguments over to/from the
+ * MockGetMic global object
+ */
+
+static OM_uint32 KRB5_CALLCONV
+mock_get_mic(
+    OM_uint32    *minor_status,
+    gss_ctx_id_t  context_handle,
+    gss_qop_t     qop_req,
+    gss_buffer_t  message_buffer,
+    gss_buffer_t  message_token)
+{
+  /* Error checking */
+  /* Variables */
+  std::string buffer;
+  
+  /* Setup */
+  buffer = MockGetMic::outputToken.toString();
+  
+  /* Main */
+  // Copy our input from the appropriate parameters to MockGetMic
+  MockGetMic::context_handle = context_handle;
+  MockGetMic::qop_req        = qop_req;
+  MockGetMic::inputMessage.setValue((char *)message_buffer->value, message_buffer->length);
+  
+  
+  // copy our output to the appropriate parameters
+  *minor_status = MockGetMic::minor_status;
+  message_token->length = buffer.length();
+  message_token->value  = (void *)buffer.c_str();
+  
+  /* Cleanup */
+  /* return */
+  return MockGetMic::retVal;
+}
+
+void GSSGetMicTest::setUp()
+{
+  CppUnit::TestFixture::setUp();
+  MockGetMic::reset();
+}
+
+void GSSGetMicTest::testConstructor()
+{
+  /* Variables */
+  GSSGetMic cmd = GSSGetMic();
+  
+  /* Error checking */
+  /* Setup */
+  /* Main */
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The GSSGetMic object has the wrong GSS function",
+    (void *)&gss_get_mic,
+    (void *)cmd.getGSSFunction()
+  );
+  
+  /* Cleanup */
+  /* Return */
+}
+
+void GSSGetMicTest::testEmptyCall()
+{
+  /* Variables */
+  GSSGetMic cmd = GSSGetMic(&mock_get_mic);
+  GSSBuffer input((char *)"Input message");
+  std::string out("Output Message");
+  gss_qop_t desiredQop = rand();
+  gss_ctx_id_t desiredContext = (gss_ctx_id_t)rand();
+  
+  /* Error checking */
+  /* Setup */
+  cmd.setContextHandle(desiredContext);
+  cmd.setQopReq( desiredQop );
+  cmd.setInputMessage(&input);
+  
+  MockGetMic::minor_status = 0;
+  MockGetMic::retVal = 0;
+  MockGetMic::outputToken.setValue(out);
+  
+  
+  /* Main */
+  cmd.execute();
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The requested GSS context handle is not correct",
+    desiredContext,
+    MockGetMic::context_handle
+  );
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The qop_req flag was incorrect.",
+    desiredQop,
+    MockGetMic::qop_req
+  );
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The input message was incorrect.",
+    input.toString(),
+    MockGetMic::inputMessage.toString()
+  );
+  
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The output message token was incorrect.",
+    out,
+    cmd.getOutputToken().toString()
+  );
+  
+  
+  /* Cleanup */
+  /* Return */
+}
+
+void GSSGetMicTest::testConstructorWithJSONObject()
+{
+  /* Variables */
+  const char* input = "{\"method\": \"gss_get_mic\", \
+    \"arguments\": \
+    { \
+         \"context_handle\": \"#######\", \
+         \"qop_req\": \"GSS_C_QOP_DEFAULT\", \
+         \"input_message\": \"mary had a little lamb\" \
+    }\
+  }";
+  json_error_t jsonErr;
+  JSONObject json = JSONObject::load(input, 0, &jsonErr);
+  
+  GSSGetMic cmd = GSSGetMic(&json, &mock_get_mic);
+  
+  /* Error checking */
+  /* Setup */
+  /* Main */
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "GSSGetMic did not parse the qop_req argument correctly",
+    (gss_qop_t)0,
+    cmd.getQopReq()
+  );
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "GSSGetMic did not parse the input message argument correctly",
+    std::string("mary had a little lamb"),
+    cmd.getInputMessage().toString()
+  );
+  
+  /* Cleanup */
+  /* Return */
+}
+
+
+/* Desired JSON output:
+ * 
+ * {
+ *  "command":       "gss_get_mic",
+ *  "return_values": 
+ *  {
+ *      "major_status": 0,
+ *      "minor_status": 0,
+ *      "output_token": "asdf"
+ *  }
+ * }
+ */
+
+void GSSGetMicTest::testJSONMarshal()
+{
+  /* Variables */
+  std::string output("dns@google.com");
+  GSSBuffer input( (char*)"abc" );
+  JSONObject *result;
+  GSSGetMic cmd = GSSGetMic(&mock_get_mic);
+  
+  /* Error checking */
+  /* Setup */
+  MockGetMic::minor_status = 0;
+  MockGetMic::retVal = 0;
+  MockGetMic::outputToken.setValue(output);
+  
+  cmd.setContextHandle(GSS_C_NO_CONTEXT);
+  cmd.setInputMessage( &input );
+  cmd.setQopReq(GSS_C_QOP_DEFAULT);
+  
+  /* Main */
+  cmd.execute();
+  result = cmd.toJSON();
+//   std::cout << "\nGSSGetMic JSON: \n" << result->dump() << "\n";
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The command name is incorrect",
+    std::string("gss_get_mic"),
+    std::string( (*result)["command"].string() )
+  );
+  
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The return value was reported incorrectly",
+    (int)MockGetMic::retVal,
+    (int)( (*result)["return_values"]["major_status"].integer() )
+  );
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The minor_status value was reported incorrectly",
+    (int)MockGetMic::minor_status,
+    (int)( (*result)["return_values"]["minor_status"].integer() )
+  );
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The output message was reported incorrectly",
+    output,
+    std::string( (*result)["return_values"]["output_token"].string() )
+  );
+  
+  
+  /* Cleanup */
+  /* Return */
+}
diff --git a/json_gssapi/test/GSSGetMicTest.h b/json_gssapi/test/GSSGetMicTest.h
new file mode 100644 (file)
index 0000000..7458441
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014 <copyright holder> <email>
+ *
+ * For license details, see the LICENSE file in the root of this project.
+ *
+ */
+
+#ifndef GSSGETMICTEST_H
+#define GSSGETMICTEST_H
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+class GSSGetMicTest : public CppUnit::TestFixture
+{
+
+  CPPUNIT_TEST_SUITE( GSSGetMicTest );
+  CPPUNIT_TEST( testConstructor );
+  CPPUNIT_TEST( testConstructorWithJSONObject );
+  CPPUNIT_TEST( testEmptyCall );
+  CPPUNIT_TEST( testJSONMarshal );
+  CPPUNIT_TEST_SUITE_END();
+
+public:
+    virtual void setUp();
+    
+    void testConstructor();
+    void testConstructorWithJSONObject();
+    void testEmptyCall();
+    void testJSONMarshal();
+
+
+};
+
+#endif // GSSGETMICTEST_H
diff --git a/json_gssapi/test/command_mocks/MockGetMic.cpp b/json_gssapi/test/command_mocks/MockGetMic.cpp
new file mode 100644 (file)
index 0000000..d645bf2
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2014 <copyright holder> <email>
+ *
+ * For license details, see the LICENSE file in the root of this project.
+ *
+ */
+
+#include "MockGetMic.h"
+
+/*
+ * OM_uint32 KRB5_CALLCONV
+ * gss_get_mic(
+ *    OM_uint32 *,         / * minor_status * /
+ *     gss_ctx_id_t,       / * context_handle * /
+ *     gss_qop_t,          / * qop_req * /
+ *     gss_buffer_t,       / * message_buffer * /
+ *     gss_buffer_t);      / * message_token * /
+ *
+ * 
+ *   class MockGetMic
+ *   {
+ *   public:
+ *     static OM_uint32     retVal;
+ *     static OM_uint32     minor_status;
+ *     static gss_ctx_id_t  context_handle;
+ *     static gss_qop_t     qop_req;
+ *     static GSSBuffer     messageBuffer;
+ *     static GSSBuffer     messageToken;
+ *     
+ *     static void reset();
+ *
+ *   };
+ */
+
+OM_uint32     MockGetMic::retVal;
+OM_uint32     MockGetMic::minor_status;
+gss_ctx_id_t  MockGetMic::context_handle;
+gss_qop_t     MockGetMic::qop_req;
+GSSBuffer     MockGetMic::inputMessage;
+GSSBuffer     MockGetMic::outputToken;
+
+void MockGetMic::reset()
+{
+  MockGetMic::retVal         = 0;
+  MockGetMic::minor_status   = 0;
+  MockGetMic::context_handle = GSS_C_NO_CONTEXT;
+  MockGetMic::qop_req        = GSS_C_QOP_DEFAULT;
+  MockGetMic::inputMessage   = GSSBuffer();
+  MockGetMic::outputToken    = GSSBuffer();
+}
diff --git a/json_gssapi/test/command_mocks/MockGetMic.h b/json_gssapi/test/command_mocks/MockGetMic.h
new file mode 100644 (file)
index 0000000..6901e9f
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014 <copyright holder> <email>
+ *
+ * For license details, see the LICENSE file in the root of this project.
+ *
+ */
+
+#ifndef MOCKGETMIC_H
+#define MOCKGETMIC_H
+
+#include "datamodel/GSSBuffer.h"
+#include <gssapi/gssapi.h>
+
+/*
+ * OM_uint32 KRB5_CALLCONV
+ * gss_get_mic(
+ *    OM_uint32 *,         / * minor_status * /
+ *     gss_ctx_id_t,       / * context_handle * /
+ *     gss_qop_t,          / * qop_req * /
+ *     gss_buffer_t,       / * message_buffer * /
+ *     gss_buffer_t);      / * message_token * /
+ */
+
+class MockGetMic
+{
+public:
+  static OM_uint32     retVal;
+  static OM_uint32     minor_status;
+  static gss_ctx_id_t  context_handle;
+  static gss_qop_t     qop_req;
+  static GSSBuffer     inputMessage;
+  static GSSBuffer     outputToken;
+  
+  static void reset();
+
+};
+
+#endif // MOCKGETMIC_H