GSS Wrap implementation.
authorMark Donnelly <mark@painless-security.com>
Mon, 12 May 2014 19:50:04 +0000 (15:50 -0400)
committerMark Donnelly <mark@painless-security.com>
Mon, 12 May 2014 19:50:04 +0000 (15:50 -0400)
Successfully:
* Calls gss_wrap
* Passes arguments back and forth
* Marshals to JSON
* Unmarshals from JSON

Has yet to:
* Load the security context from a yet-to-be-written in-memory cache

json_gssapi/CMakeLists.txt
json_gssapi/src/GSSWrap.cpp [new file with mode: 0644]
json_gssapi/src/GSSWrap.h [new file with mode: 0644]
json_gssapi/test/CMakeLists.txt
json_gssapi/test/GSSWrapTest.cpp [new file with mode: 0644]
json_gssapi/test/GSSWrapTest.h [new file with mode: 0644]
json_gssapi/test/command_mocks/MockWrap.cpp [new file with mode: 0644]
json_gssapi/test/command_mocks/MockWrap.h [new file with mode: 0644]

index 8971c27..c013e81 100644 (file)
@@ -12,6 +12,7 @@ add_executable(json_gssapi src/datamodel/GSSName.cpp
                            src/GSSCommand.cpp 
                            src/GSSImportName.cpp
                            src/GSSAcquireCred.cpp 
+                           src/GSSWrap.cpp 
                            src/util_json.cpp 
                            main.cpp)
 target_link_libraries(json_gssapi gssapi_krb5 jansson)
diff --git a/json_gssapi/src/GSSWrap.cpp b/json_gssapi/src/GSSWrap.cpp
new file mode 100644 (file)
index 0000000..c633679
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2014 <copyright holder> <email>
+ *
+ * For license details, see the LICENSE file in the root of this project.
+ *
+ */
+
+#include "GSSWrap.h"
+#include <stdexcept>
+
+/*
+ *     gss_wrap_type function;
+    int conf_req;
+    gss_ctx_id_t context;
+    gss_qop_t qop_req;
+    GSSBuffer inputMessage;
+    GSSBuffer outputMessage;
+    
+  
+    OM_uint32 retVal;
+    OM_uint32 minor_status;
+    int conf_state;
+ */
+
+bool GSSWrap::loadParameters(JSONObject *params)
+{
+  /* Variables */
+  std::string sQopReq, sConfReq, sInputMessage;
+  
+  /* Error checking */
+  /* Setup */
+  // Should I zeroOut?
+  
+  /* Main processing */
+  
+  /************
+   * CONF_REQ *
+   ************/
+  if ( ! params->get("arguments").get("conf_req").isNull() )
+  {
+    if (params->get("arguments").get("conf_req").isString())
+    {
+      sConfReq = params->get("arguments").get("conf_req").string();
+      if (sConfReq == "TRUE")
+        this->conf_req = 1;
+      else if (sConfReq == "FALSE")
+        this->conf_req = 0;
+      else
+        throw std::invalid_argument( std::string("Invalid QOP type given: ") + sConfReq );
+    } else if (params->get("arguments").get("conf_req").isInteger())
+      this->conf_req = (gss_cred_usage_t)( params->get("arguments").get("conf_req").integer() );
+    else
+      throw std::invalid_argument( "Unrecognized argument type for conf_req." );
+  }  
+  
+  /***********
+   * 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;
+}
+
+GSSWrap::GSSWrap ( JSONObject* params, gss_wrap_type fn )
+{
+  function = fn;
+  loadParameters(params);
+}
+
+
+GSSWrap::~GSSWrap()
+{
+
+}
+
+void GSSWrap::execute()
+{
+  /* Variables */
+  gss_buffer_desc output_buf;
+  
+  retVal = function(
+    &(this->minor_status),
+    this->context,
+    this->conf_req,
+    this->qop_req,
+    this->inputMessage.toGss(),
+    &(this->conf_state),
+    &output_buf
+  );
+  
+  this->outputMessage.setValue( (char *)output_buf.value, output_buf.length );
+}
+
+/* Desired JSON output:
+ * 
+ * {
+ *  "command":       "gss_wrap",
+ *  "return_values": 
+ *  {
+ *      "major_status":   0,
+ *      "minor_status":   0,
+ *      "conf_state":     "TRUE",
+ *      "output_message": "asdf"
+ *  }
+ * }
+ */
+JSONObject *GSSWrap::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);
+  
+  conf_state = (this->conf_state) ? "TRUE" : "FALSE";
+  values->set("conf_state", conf_state);
+  
+  values->set(
+    "output_message",
+    this->outputMessage.toString().c_str()
+  );
+  
+  // Put it all together.
+  ret->set("command", "gss_wrap");
+  ret->set("return_values", *values);
+  
+  /* Cleanup */
+  
+  /* Return */
+  return(ret);
+}
+
diff --git a/json_gssapi/src/GSSWrap.h b/json_gssapi/src/GSSWrap.h
new file mode 100644 (file)
index 0000000..aba5a65
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2014 <copyright holder> <email>
+ *
+ * For license details, see the LICENSE file in the root of this project.
+ *
+ */
+
+#ifndef GSSWRAP_H
+#define GSSWRAP_H
+
+#include <gssapi.h>
+
+#include "GSSCommand.h"
+#include "datamodel/GSSBuffer.h"
+
+typedef OM_uint32 (*gss_wrap_type) (
+    OM_uint32 *,        /* minor_status */
+    gss_ctx_id_t,       /* context_handle */
+    int,                /* conf_req_flag */
+    gss_qop_t,          /* qop_req */
+    gss_buffer_t,       /* input_message_buffer */
+    int *,              /* conf_state */
+    gss_buffer_t);      /* output_message_buffer */
+
+
+class GSSWrap :  GSSCommand
+{
+public:
+    GSSWrap( gss_wrap_type fn = &gss_wrap ) : function(fn) {};
+    GSSWrap( JSONObject *params, gss_wrap_type fn = &gss_wrap);
+    ~GSSWrap();
+    virtual void execute();
+    virtual JSONObject* toJSON();
+    
+    gss_wrap_type getGSSFunction() const { return(function); }
+    
+    void setConfReq(int conf_req_flag) { conf_req = conf_req_flag; }
+    void setContextHandle ( gss_ctx_id_t context_handle ) { context = context_handle; }
+    void setQopReq ( int arg1 ) { qop_req = arg1; }
+    void setInputMessage ( GSSBuffer* input ) { inputMessage.setValue(input->toString()); };
+    
+    int getConfState () const { return(conf_state); }
+    GSSBuffer getOutputMessage () const { return(outputMessage); }
+    int getConfReq() const { return(conf_req); }
+    gss_qop_t getQopReq() const { return(qop_req); }
+    GSSBuffer getInputMessage () const { return(inputMessage); }
+    
+private:
+    gss_wrap_type function;
+    int conf_req;
+    gss_ctx_id_t context;
+    gss_qop_t qop_req;
+    GSSBuffer inputMessage;
+    GSSBuffer outputMessage;
+    
+  
+    OM_uint32 retVal;
+    OM_uint32 minor_status;
+    int conf_state;
+
+    bool loadParameters(JSONObject *params);
+};
+
+#endif // GSSWRAP_H
index 25199fc..b2f2ecf 100644 (file)
@@ -2,8 +2,10 @@ include_directories(${CMAKE_SOURCE_DIR}/src)
 
 add_executable(test GSSExceptionTest.cpp 
                     GSSAcquireCredTest.cpp
+                    GSSWrapTest.cpp
                     command_mocks/InitSecContextMock.cpp
                     command_mocks/MockAcquireCred.cpp 
+                    command_mocks/MockWrap.cpp 
                     GSSCreateSecContextTest.cpp 
                     GSSImportNameTest.cpp
                     command_mocks/MockImportName.cpp
@@ -13,6 +15,7 @@ add_executable(test GSSExceptionTest.cpp
                     ../src/GSSImportName.cpp
                     ../src/GSSException.cpp
                     ../src/GSSAcquireCred.cpp
+                    ../src/GSSWrap.cpp
                     ../src/datamodel/GSSBuffer.cpp
                     ../src/datamodel/GSSCredential.cpp
                     ../src/datamodel/GSSName.cpp
diff --git a/json_gssapi/test/GSSWrapTest.cpp b/json_gssapi/test/GSSWrapTest.cpp
new file mode 100644 (file)
index 0000000..7582722
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2014 <copyright holder> <email>
+ *
+ * For license details, see the LICENSE file in the root of this project.
+ *
+ */
+
+#include "GSSWrapTest.h"
+#include "command_mocks/MockWrap.h"
+#include "GSSWrap.h"
+#include <gssapi/gssapi.h>
+
+CPPUNIT_TEST_SUITE_REGISTRATION( GSSWrapTest );
+
+/* 
+ * a mock of the gss_import_name call
+ * 
+ * Basically, just copy the arguments over to/from the
+ * MockWrap global object
+ */
+
+static OM_uint32 KRB5_CALLCONV
+mock_wrap(
+    OM_uint32    *minor_status,
+    gss_ctx_id_t  context_handle,
+    int           conf_req_flag,
+    gss_qop_t     qop_req,
+    gss_buffer_t  input_message_buffer,
+    int          *conf_state,
+    gss_buffer_t  output_message_buffer)
+{
+  /* Error checking */
+  /* Variables */
+  std::string buffer;
+  
+  /* Setup */
+  buffer = MockWrap::outputMessageBuffer.toString();
+  
+  /* Main */
+  // Copy our input from the appropriate parameters to MockWrap
+  MockWrap::context_handle = context_handle;
+  MockWrap::conf_req_flag  = conf_req_flag;
+  MockWrap::qop_req        = qop_req;
+  MockWrap::inputMessageBuffer.setValue(input_message_buffer);
+  
+  
+  // copy our output to the appropriate parameters
+  *minor_status = MockWrap::minor_status;
+  *conf_state = MockWrap::conf_state;
+  output_message_buffer->length = buffer.length();
+  output_message_buffer->value  = (void *)buffer.c_str();
+  
+  /* Cleanup */
+  /* return */
+  return MockWrap::retVal;
+}
+
+void GSSWrapTest::setUp()
+{
+  CppUnit::TestFixture::setUp();
+  MockWrap::reset();
+}
+
+void GSSWrapTest::testConstructor()
+{
+  /* Variables */
+  GSSWrap cmd = GSSWrap();
+  
+  /* Error checking */
+  /* Setup */
+  /* Main */
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The GSSWrap object has the wrong GSS function",
+    (void *)&gss_wrap,
+    (void *)cmd.getGSSFunction()
+  );
+  
+  /* Cleanup */
+  /* Return */
+}
+
+void GSSWrapTest::testEmptyCall()
+{
+  /* Variables */
+  GSSWrap cmd = GSSWrap(&mock_wrap);
+  GSSBuffer input((char *)"Input message");
+  gss_qop_t desiredQop = rand();
+  int desiredConf = rand();
+  gss_ctx_id_t desiredContext = (gss_ctx_id_t)rand();
+  
+  /* Error checking */
+  /* Setup */
+  cmd.setContextHandle(desiredContext);
+  cmd.setConfReq( desiredConf );
+  cmd.setQopReq( desiredQop );
+  cmd.setInputMessage(&input);
+  
+  MockWrap::minor_status = 0;
+  MockWrap::retVal = 0;
+  MockWrap::conf_state = rand();
+  MockWrap::outputMessageBuffer.setValue((char *)"Output message");
+  
+  
+  /* Main */
+  cmd.execute();
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The requested GSS context handle is not correct",
+    desiredContext,
+    MockWrap::context_handle
+  );
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The conf_req flag was incorrect.",
+    desiredConf,
+    MockWrap::conf_req_flag
+  );
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The qop_req flag was incorrect.",
+    desiredQop,
+    MockWrap::qop_req
+  );
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The input message was incorrect.",
+    input.toString(),
+    MockWrap::inputMessageBuffer.toString()
+  );
+  
+  
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The conf_state flag was incorrect.",
+    MockWrap::conf_state,
+    cmd.getConfState()
+  );
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The input message was incorrect.",
+    cmd.getOutputMessage().toString(),
+    MockWrap::outputMessageBuffer.toString()
+  );
+  
+  
+  /* Cleanup */
+  /* Return */
+}
+
+void GSSWrapTest::testConstructorWithJSONObject()
+{
+  /* Variables */
+  const char* input = "{\"method\": \"gss_wrap\", \
+    \"arguments\": \
+    { \
+         \"context_handle\": \"#######\", \
+         \"conf_req\": \"TRUE\", \
+         \"qop_req\": \"GSS_C_QOP_DEFAULT\", \
+         \"input_message\": \"mary had a little lamb\" \
+    }\
+  }";
+  json_error_t jsonErr;
+  JSONObject json = JSONObject::load(input, 0, &jsonErr);
+  
+  GSSWrap cmd = GSSWrap(&json, &mock_wrap);
+  
+  /* Error checking */
+  /* Setup */
+  /* Main */
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "GSSWrap did not parse the conf_req argument correctly",
+    1,
+    cmd.getConfReq()
+  );
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "GSSWrap did not parse the qop_req argument correctly",
+    (gss_qop_t)0,
+    cmd.getQopReq()
+  );
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "GSSWrap did not parse the input message argument correctly",
+    std::string("mary had a little lamb"),
+    cmd.getInputMessage().toString()
+  );
+  
+  
+  
+  /* Cleanup */
+  /* Return */
+}
+
+
+void GSSWrapTest::testJSONMarshal()
+{
+  /* Variables */
+  std::string output("dns@google.com");
+  int confState = 1;
+  JSONObject *result;
+  GSSWrap cmd = GSSWrap(&mock_wrap);
+  
+  /* Error checking */
+  /* Setup */
+  MockWrap::minor_status = 0;
+  MockWrap::retVal = 0;
+  MockWrap::outputMessageBuffer.setValue(output);
+  MockWrap::conf_state = confState;
+  
+  /* Main */
+  cmd.execute();
+  result = cmd.toJSON();
+//   std::cout << "\nGSSWrap JSON: \n" << result->dump() << "\n";
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The command name is incorrect",
+    std::string("gss_wrap"),
+    std::string( (*result)["command"].string() )
+  );
+  
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The return value was reported incorrectly",
+    (int)MockWrap::retVal,
+    (int)( (*result)["return_values"]["major_status"].integer() )
+  );
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The minor_status value was reported incorrectly",
+    (int)MockWrap::minor_status,
+    (int)( (*result)["return_values"]["minor_status"].integer() )
+  );
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The output message was reported incorrectly",
+    MockWrap::outputMessageBuffer.toString(),
+    std::string( (*result)["return_values"]["output_message"].string() )
+  );
+  
+  
+  /* Cleanup */
+  /* Return */
+}
diff --git a/json_gssapi/test/GSSWrapTest.h b/json_gssapi/test/GSSWrapTest.h
new file mode 100644 (file)
index 0000000..18a7c0b
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014 <copyright holder> <email>
+ *
+ * For license details, see the LICENSE file in the root of this project.
+ *
+ */
+
+#ifndef GSSWRAPTEST_H
+#define GSSWRAPTEST_H
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+class GSSWrapTest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( GSSWrapTest );
+  CPPUNIT_TEST( testConstructor );
+  CPPUNIT_TEST( testConstructorWithJSONObject );
+  CPPUNIT_TEST( testEmptyCall );
+  CPPUNIT_TEST( testJSONMarshal );
+  CPPUNIT_TEST_SUITE_END();
+  
+public:
+  void setUp();
+  
+  void testConstructor();
+  void testConstructorWithJSONObject();
+  void testEmptyCall();
+  void testJSONMarshal();
+
+};
+
+#endif // GSSWRAPTEST_H
diff --git a/json_gssapi/test/command_mocks/MockWrap.cpp b/json_gssapi/test/command_mocks/MockWrap.cpp
new file mode 100644 (file)
index 0000000..6ef3513
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2014 <copyright holder> <email>
+ *
+ * For license details, see the LICENSE file in the root of this project.
+ *
+ */
+
+#include "MockWrap.h"
+
+
+/*
+  static OM_uint32     retVal;
+  static OM_uint32     minor_status;
+  static gss_ctx_id_t  context_handle;
+  static int           conf_req_flag;
+  static gss_qop_t     qop_req;
+  static gss_buffer_t  input_message_buffer;
+  static int          *conf_state;
+  static gss_buffer_t  output_message_buffer;
+*/
+
+OM_uint32    MockWrap::retVal;
+OM_uint32    MockWrap::minor_status;
+gss_ctx_id_t MockWrap::context_handle;
+int          MockWrap::conf_req_flag;
+gss_qop_t    MockWrap::qop_req;
+GSSBuffer    MockWrap::inputMessageBuffer;
+int          MockWrap::conf_state;
+GSSBuffer    MockWrap::outputMessageBuffer;
+
+
+void MockWrap::reset()
+{
+  retVal = 0;
+  minor_status = 0;
+  context_handle = GSS_C_NO_CONTEXT;
+  conf_req_flag = 0;
+  qop_req = 0;
+  inputMessageBuffer.setValue(std::string());
+  conf_state = 0;
+  outputMessageBuffer.setValue(std::string());
+}
diff --git a/json_gssapi/test/command_mocks/MockWrap.h b/json_gssapi/test/command_mocks/MockWrap.h
new file mode 100644 (file)
index 0000000..a112d4c
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2014 <copyright holder> <email>
+ *
+ * For license details, see the LICENSE file in the root of this project.
+ *
+ */
+
+#ifndef MOCKWRAP_H
+#define MOCKWRAP_H
+
+#include "datamodel/GSSBuffer.h"
+
+class MockWrap
+{
+public:
+  static OM_uint32     retVal;
+  static OM_uint32     minor_status;
+  static gss_ctx_id_t  context_handle;
+  static int           conf_req_flag;
+  static gss_qop_t     qop_req;
+  static GSSBuffer     inputMessageBuffer;
+  static int           conf_state;
+  static GSSBuffer     outputMessageBuffer;
+  
+  static void reset();
+};
+
+#endif // MOCKWRAP_H