Commit an overly-large chunk of work.
authorMark Donnelly <mark@painless-security.com>
Thu, 4 Sep 2014 14:10:20 +0000 (10:10 -0400)
committerMark Donnelly <mark@painless-security.com>
Thu, 4 Sep 2014 14:10:20 +0000 (10:10 -0400)
This commit contains at least the following changes:
* The addition of pseudo_random
* The addition of memory caches for contexts and names
* The return of handles (base64-encoded) to the memory caches for context and name objects
* Moving the gss_import_name functionality out of the GSSName object properly into the GSSImportName object
* Give GSSImportName defaults of interpreting the name as OID { 1 2 840 113554 1 2 1 4 } - GSSAPI Service Name (ISO / Member / US / MIT / Infosys / GSSAPI / generic / service-name)
* Implement the copy-creator of GSSName to call gss_duplicate_name.  Each object has its own memory handle.  Neat!
* Addition of GSSContext objects to hold GSS contexts

33 files changed:
json_gssapi/CMakeLists.txt
json_gssapi/src/CMakeLists.txt
json_gssapi/src/cache/CMakeLists.txt [new file with mode: 0644]
json_gssapi/src/cache/GSSContextCache.cpp [new file with mode: 0644]
json_gssapi/src/cache/GSSContextCache.h [new file with mode: 0644]
json_gssapi/src/cache/GSSNameCache.cpp [new file with mode: 0644]
json_gssapi/src/cache/GSSNameCache.h [new file with mode: 0644]
json_gssapi/src/commands/GSSCreateSecContextCommand.cpp
json_gssapi/src/commands/GSSCreateSecContextCommand.h
json_gssapi/src/commands/GSSGetMic.cpp
json_gssapi/src/commands/GSSImportName.cpp
json_gssapi/src/commands/GSSImportName.h
json_gssapi/src/commands/GSSPseudoRandom.cpp
json_gssapi/src/commands/GSSPseudoRandom.h
json_gssapi/src/commands/GSSUnwrap.cpp
json_gssapi/src/commands/GSSUnwrap.h
json_gssapi/src/commands/GSSWrap.cpp
json_gssapi/src/commands/GSSWrap.h
json_gssapi/src/datamodel/GSSContext.cpp [new file with mode: 0644]
json_gssapi/src/datamodel/GSSContext.h [new file with mode: 0644]
json_gssapi/src/datamodel/GSSName.cpp
json_gssapi/src/datamodel/GSSName.h
json_gssapi/test/CMakeLists.txt
json_gssapi/test/GSSAcquireCredTest.cpp
json_gssapi/test/GSSCreateSecContextTest.cpp
json_gssapi/test/GSSCreateSecContextTest.h
json_gssapi/test/GSSGetMicTest.cpp
json_gssapi/test/GSSImportNameTest.cpp
json_gssapi/test/GSSPseudoRandomTest.cpp
json_gssapi/test/GSSUnwrapTest.cpp
json_gssapi/test/GSSWrapTest.cpp
json_gssapi/test/NameCacheTest.cpp [new file with mode: 0644]
json_gssapi/test/NameCacheTest.h [new file with mode: 0644]

index 317732d..9d791b2 100644 (file)
@@ -18,9 +18,21 @@ add_executable(json_gssapi src/datamodel/GSSName.cpp
                            src/commands/GSSPseudoRandom.cpp
                            src/commands/GSSWrap.cpp  
                            src/commands/GSSUnwrap.cpp
-                           src/util_json.cpp 
+                           src/util_json.cpp
+                           src/cache/GSSContextCache.cpp
+                           src/cache/GSSNameCache.cpp
+                           src/datamodel/GSSContext.cpp
+                           src/util/base64.cpp
                            main.cpp)
-target_link_libraries(json_gssapi gssapi_krb5 jansson)
+target_link_libraries(json_gssapi gssapi_krb5 jansson crypto)
+
+find_package (PkgConfig)
+pkg_check_modules (GLIB2   glib-2.0)
+if (GLIB2_FOUND)
+  include_directories(${GLIB2_INCLUDE_DIRS})
+  target_link_libraries(json_gssapi ${GLIB2_LIBRARIES})
+endif(GLIB2_FOUND)
 
 
 set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules/")
index dc56adb..f57fb45 100644 (file)
@@ -1,3 +1,5 @@
 
 add_subdirectory(datamodel)
-add_subdirectory(commands)
\ No newline at end of file
+add_subdirectory(commands)
+add_subdirectory(util)
+add_subdirectory(cache)
\ No newline at end of file
diff --git a/json_gssapi/src/cache/CMakeLists.txt b/json_gssapi/src/cache/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/json_gssapi/src/cache/GSSContextCache.cpp b/json_gssapi/src/cache/GSSContextCache.cpp
new file mode 100644 (file)
index 0000000..c4a518d
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2014 <copyright holder> <email>
+ *
+ * For license details, see the LICENSE file in the root of this project.
+ *
+ */
+
+#include <glib.h>
+#include <stdexcept>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+
+#include "GSSContextCache.h"
+
+#define KEYLEN 128
+
+GSSContextCache* GSSContextCache::_instance = 0;
+
+GSSContextCache::GSSContextCache()
+{
+
+}
+
+GSSContextCache::~GSSContextCache()
+{
+
+}
+
+GSSContextCache* GSSContextCache::instance()
+{
+    if (_instance == 0)
+      _instance = new GSSContextCache;
+    
+    return _instance;
+}
+
+
+std::string GSSContextCache::store ( GSSContext& data, std::string inKey )
+{
+  /* Variables      */
+  std::string key;
+  
+  /* Error checking */
+  /* Setup          */
+  /* Main           */
+  // Generate a key
+  if ( inKey.length() > 0 )
+  {
+    key = inKey;
+  }
+  else if ( !generateKey(key) )
+  {
+    // Key generation failed.  Eeek!
+    throw std::runtime_error("Could not generate random data for an ID");
+  }
+  
+  // Store the key/value pair in the map
+  // Store the key in the context for convenience
+  contexts[key] = data;
+  
+  /* Cleanup        */
+  /* Return         */
+  // Return the key for future reference
+  return(key);
+}
+
+/*************************************
+ * Generate random bytes, and base64 *
+ * encode them to be JSONable keys   *
+ *************************************/
+bool GSSContextCache::generateKey(std::string &key)
+{
+  /* Variables      */
+  int  osslReturn = 0;
+  unsigned char theKey[KEYLEN];
+  bool existingErrors = false;
+  
+  /* Error checking */
+  // See if there are any queued OpenSSL errors already.
+  existingErrors = ( 0 == ERR_peek_error() ); 
+  
+  /* Setup          */
+  /* Main           */
+  // Generate random byte string
+  osslReturn = RAND_pseudo_bytes(theKey, KEYLEN);
+  
+  // Discard the error message if there weren't any OpenSSL errors to begin with.
+  if (osslReturn == 1 && !existingErrors)
+  {
+    while (0 != ERR_get_error() );
+    return(false);
+  }
+
+  // Encode the binary string
+  key = g_base64_encode(theKey, KEYLEN);
+  
+  /* Cleanup        */
+  /* Return         */
+  return(true);
+}
+
+GSSContext& GSSContextCache::retrieve ( std::string key )
+{
+  /* Variables      */
+  //GSSContext data;
+  
+  /* Error checking */
+  /* Setup          */
+  /* Main           */
+  // Maybe do something about data entries that are expired?
+  
+  /* Cleanup        */
+  /* Return         */
+  return contexts[key];
+}
+
+  /* Variables      */
+  /* Error checking */
+  /* Setup          */
+  /* Main           */
+  /* Cleanup        */
+  /* Return         */
diff --git a/json_gssapi/src/cache/GSSContextCache.h b/json_gssapi/src/cache/GSSContextCache.h
new file mode 100644 (file)
index 0000000..786044a
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 <copyright holder> <email>
+ *
+ * For license details, see the LICENSE file in the root of this project.
+ *
+ */
+
+#ifndef GSSCONTEXTCACHE_H
+#define GSSCONTEXTCACHE_H
+
+#include <map>
+#include <string>
+
+#include "datamodel/GSSContext.h"
+
+typedef std::map<std::string, GSSContext> ContextMap;
+
+class GSSContextCache
+{
+public:
+    static GSSContextCache* instance();
+    std::string store(GSSContext &data, const std::string key = "");
+    GSSContext &retrieve(std::string key);
+
+protected:
+    GSSContextCache();
+    ~GSSContextCache();
+
+private:
+    ContextMap contexts;
+    
+    bool generateKey(std::string &key);
+    
+    static GSSContextCache* _instance;
+};
+
+#endif // GSSCONTEXTCACHE_H
diff --git a/json_gssapi/src/cache/GSSNameCache.cpp b/json_gssapi/src/cache/GSSNameCache.cpp
new file mode 100644 (file)
index 0000000..7044edc
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2014 <copyright holder> <email>
+ *
+ * For license details, see the LICENSE file in the root of this project.
+ *
+ */
+
+#include <glib.h>
+#include <stdexcept>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+
+#include "GSSNameCache.h"
+// #include "util/base64.h"
+
+#define KEYLEN 128
+
+GSSNameCache* GSSNameCache::_instance = 0;
+
+GSSNameCache::GSSNameCache()
+{
+
+}
+
+GSSNameCache::GSSNameCache ( const GSSNameCache& other )
+{
+  names = other.names;
+}
+
+GSSNameCache::~GSSNameCache()
+{
+
+}
+
+GSSNameCache& GSSNameCache::operator= ( const GSSNameCache& other )
+{
+  names = other.names;
+  
+  return *this;
+}
+
+
+std::string GSSNameCache::store ( GSSName& data, std::string inKey )
+{
+  /* Variables      */
+  std::string key;
+  
+  /* Error checking */
+  /* Setup          */
+  /* Main           */
+  // Generate a key
+  if ( inKey.length() > 0 )
+  {
+    key = inKey;
+  }
+  else if ( !generateKey(key) )
+  {
+    // Key generation failed.  Eeek!
+    throw std::runtime_error("Could not generate random data for an ID");
+  }
+  
+  // Store the key/value pair in the map
+  // Store the key in the context for convenience
+//   std::cout << "\n==> In GSSNameCache::store, about to store data in the names hash.\n";
+  names[key] = data;
+  
+  /* Cleanup        */
+  /* Return         */
+  // Return the key for future reference
+  return(key);
+}
+
+/*************************************
+ * Generate random bytes, and base64 *
+ * encode them to be JSONable keys   *
+ *************************************/
+bool GSSNameCache::generateKey(std::string &key)
+{
+  /* Variables      */
+  int  osslReturn = 0;
+  unsigned char theKey[KEYLEN];
+  bool existingErrors = false;
+  
+  /* Error checking */
+  // See if there are any queued OpenSSL errors already.
+  existingErrors = ( 0 == ERR_peek_error() ); 
+  
+  /* Setup          */
+  /* Main           */
+  // Generate random byte string
+  osslReturn = RAND_pseudo_bytes(theKey, KEYLEN);
+  
+  // Discard the error message if there weren't any OpenSSL errors to begin with.
+  if (osslReturn == 1 && !existingErrors)
+  {
+    while (0 != ERR_get_error() );
+    return(false);
+  }
+
+  // Encode the binary string
+  key = g_base64_encode(theKey, KEYLEN);
+  
+  /* Cleanup        */
+  /* Return         */
+  return(true);
+}
+
+GSSName& GSSNameCache::retrieve ( std::string key )
+{
+  /* Variables      */
+  //GSSName data;
+  
+  /* Error checking */
+  /* Setup          */
+  /* Main           */
+  // Maybe do something about data entries that are expired?
+  
+  /* Cleanup        */
+  /* Return         */
+  return names[key];
+}
+
+GSSNameCache* GSSNameCache::instance()
+{
+    if (_instance == 0)
+      _instance = new GSSNameCache;
+    
+    return _instance;
+}
+
+
+
+  /* Variables      */
+  /* Error checking */
+  /* Setup          */
+  /* Main           */
+  /* Cleanup        */
+  /* Return         */
diff --git a/json_gssapi/src/cache/GSSNameCache.h b/json_gssapi/src/cache/GSSNameCache.h
new file mode 100644 (file)
index 0000000..b395af9
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014 <copyright holder> <email>
+ *
+ * For license details, see the LICENSE file in the root of this project.
+ *
+ */
+
+#ifndef GSSCONTEXTCACHE_H
+#define GSSCONTEXTCACHE_H
+
+#include <map>
+#include <string>
+
+#include "datamodel/GSSName.h"
+
+typedef std::map<std::string, GSSName> NameMap;
+
+class GSSNameCache
+{
+public:
+    static GSSNameCache* instance();
+    ~GSSNameCache();
+    GSSNameCache& operator= ( const GSSNameCache& other );
+    
+    std::string store(GSSName &data, const std::string key = "");
+    GSSName &retrieve(std::string key);
+    NameMap getNames() { return(names); };
+
+protected:
+    GSSNameCache();
+    GSSNameCache ( const GSSNameCache& other );
+
+private:
+    NameMap names;
+    
+    bool generateKey(std::string &key);
+    static GSSNameCache* _instance;
+};
+
+#endif // GSSCONTEXTCACHE_H
index 6104046..2d1fa51 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "GSSCreateSecContextCommand.h"
 #include "GSSException.h"
+#include <cache/GSSContextCache.h>
 #include <gssapi.h>
 #include <stdlib.h>
 #include <string.h>
@@ -86,6 +87,9 @@ GSSCreateSecContextCommand::execute()
     &ret_flags,
     &time_rec);
   
+  context.setContext(context_handle, true);
+  contextKey = GSSContextCache::instance()->store(context);
+  
   /* Cleanup */
   
   /* Return */
@@ -272,7 +276,7 @@ JSONObject *GSSCreateSecContextCommand::toJSON()
   /* Main */
   values->set("major_status", this->retVal);
   values->set("minor_status", this->minor_status);
-  values->set("context_handle", (json_int_t)0);
+  values->set("context_handle", this->contextKey.c_str());
   values->set("actual_mech_type", this->getActualMechType());
   values->set("output_token", (const char *)this->output_token.value);
   values->set("ret_flags", this->ret_flags);
index 52dcdd2..364d69e 100644 (file)
@@ -9,6 +9,7 @@
 #define GSSCREATESECCONTEXTCOMMAND_H
 
 #include "GSSCommand.h"
+#include <datamodel/GSSContext.h>
 #include <gssapi.h>
 
 class GSSCreateSecContextCommand : public GSSCommand
@@ -52,6 +53,8 @@ public:
 private:
     void *function;
     const char * oidToStr(gss_OID oid);
+    GSSContext context;
+    std::string contextKey;
 };
 
 #endif // GSSCREATESECCONTEXTCOMMAND_H
index 8782186..7fdbe2a 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include "GSSGetMic.h"
+#include <cache/GSSContextCache.h>
 
 #include <stdexcept>
 #include <mit-krb5/gssapi/gssapi.h>
@@ -64,6 +65,16 @@ bool GSSGetMic::loadParameters ( JSONObject* params )
     this->inputMessage.setValue(sInputMessage);
   }
   
+  /******************
+   * context_handle *
+   ******************/
+  if ( ! params->get("arguments").get("context_handle").isNull() )
+  {
+    sInputMessage = params->get("arguments").get("context_handle").string();
+    GSSContext ctx = GSSContextCache::instance()->retrieve(sInputMessage);
+    this->context = ctx.getContext();
+  }
+  
   /* Cleanup */
   /* Return */
   return true;
@@ -87,7 +98,6 @@ void GSSGetMic::execute()
 JSONObject* GSSGetMic::toJSON()
 {
   /* Variables */
-  const char *conf_state;
   JSONObject *ret = new JSONObject();
   JSONObject *values = new JSONObject();
   
index 5284009..6045a81 100644 (file)
@@ -7,15 +7,57 @@
 
 #include "GSSImportName.h"
 #include "GSSException.h"
+#include <cache/GSSNameCache.h>
+
+
+typedef OM_uint32 (*gss_imp_name_type)(
+    OM_uint32 *,        /* minor_status */
+    gss_buffer_t,       /* input_name_buffer */
+    gss_OID,            /* input_name_type(used to be const) */
+    gss_name_t *);      /* output_name */
+
+
 
 void GSSImportName::execute()
 {
-  this->outputName = GSSName(inputName, inputNameType, function);
-  this->retVal = this->outputName.getMajorStatus();
-  this->minor_status = this->outputName.getMinorStatus();
-  this->outputName.setKey("constant for now");
+  /* Variables */
+  gss_name_t name;
+  std::string key;
+
+  /* Error checking */
+  /* Setup */
+
+  /* Main */
+  retVal = function(&minor_status, inputName.toGss(), inputNameType.toGss(), &name);
+  if ( GSS_ERROR(this->retVal) )
+  {
+    std::string errMsg;
+    errMsg += "Cannot import name: ";
+    errMsg += inputName.toString();
+    throw GSSException(errMsg.c_str(), this->retVal, this->minor_status, inputNameType.toGss());
+  }
+  this->outputName.setValue(name);
+  key = GSSNameCache::instance()->store(this->outputName);
+//   std::cout << "Storing key: " << key << std::endl;
+  this->outputName.setKey(key);
+  /* Cleanup */
+  /* Return */
+  
 }
 
+/* Example output:
+ * 
+ * {
+ *   "command": "gss_import_name",
+ *   "return_values":
+ *   {
+ *     "major_status": 0,
+ *     "minor_status": 0,
+ *     "gss_name": "base64_encoded_string"
+ *   }
+ * }
+ * 
+ */
 JSONObject *GSSImportName::toJSON()
 {
   /* Variables */
@@ -39,6 +81,14 @@ JSONObject *GSSImportName::toJSON()
   return(ret);
 }
 
+GSSImportName::GSSImportName ( gss_imp_name_type fn )
+{
+  // defaults
+  function = fn;
+  inputName = "";
+  inputNameType.setValue(GSSBuffer("{ 1 2 840 113554 1 2 1 4 }"));
+}
+
 GSSImportName::GSSImportName(JSONObject *params, gss_imp_name_type fn) : GSSCommand(params)
 {
   /* Variables */
index 9adea4d..534604f 100644 (file)
@@ -17,7 +17,7 @@
 class GSSImportName : public GSSCommand
 {
 public:
-  GSSImportName(gss_imp_name_type fn = &gss_import_name) : function(fn) {};
+  GSSImportName(gss_imp_name_type fn = &gss_import_name);
   GSSImportName(JSONObject *params, gss_imp_name_type fn = &gss_import_name);
   
   void execute();
index fbb111b..48ea33d 100644 (file)
@@ -8,6 +8,8 @@
 #include <stdexcept>
 
 #include "GSSPseudoRandom.h"
+#include <cache/GSSContextCache.h>
+#include <datamodel/GSSContext.h>
 
 GSSPseudoRandom::GSSPseudoRandom(JSONObject *params, 
                                               gss_pseudo_random_type fn) : GSSCommand(params)
@@ -79,6 +81,20 @@ bool GSSPseudoRandom::loadParameters ( JSONObject* params )
       this->inputMessage.setValue(sInputMessage);
     }
   }
+
+  
+  /******************
+   * context_handle *
+   ******************/
+  if ( ! params->get("arguments").get("context_handle").isNull() )
+  {
+    if (params->get("arguments").get("context_handle").isString())
+    {
+      std::string contextKey = params->get("arguments").get("context_handle").string();
+      GSSContext ctx = GSSContextCache::instance()->retrieve(contextKey);
+      this->context = ctx.getContext();
+    }
+  }
   
   /* Cleanup */
   /* Return */
index 11d06df..8bcba64 100644 (file)
@@ -45,6 +45,7 @@ public:
     OM_uint32 getMinorStatus() { return(minor_status); }
     int       getKey() { return(key); }
     int       getDesiredOutputLength() { return(desiredOutputLength); }
+    gss_ctx_id_t getContextHandle() const { return(this->context); }
     gss_pseudo_random_type getGSSFunction() { return function; };
     
 private:
index 376350f..8e2d742 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include "GSSUnwrap.h"
+#include <cache/GSSContextCache.h>
 
 GSSUnwrap::GSSUnwrap ( JSONObject* params, gss_unwrap_type fn )
 {
@@ -33,6 +34,16 @@ bool GSSUnwrap::loadParameters(JSONObject *params)
     this->inputMessage.setValue(sInputMessage);
   }
   
+  /******************
+   * context_handle *
+   ******************/
+  if ( ! params->get("arguments").get("context_handle").isNull() )
+  {
+    sInputMessage = params->get("arguments").get("context_handle").string();
+    GSSContext ctx = GSSContextCache::instance()->retrieve(sInputMessage);
+    this->context = ctx.getContext();
+  }
+  
   /* Cleanup */
   /* Return */
   return true;
index ac29117..4178a2f 100644 (file)
@@ -35,6 +35,7 @@ public:
     int getConfState() const { return(conf_state); }
     GSSBuffer getInputMessage() const { return(inputMessage); }
     GSSBuffer getOutputMessage() const { return(outputMessage); }
+    gss_ctx_id_t getContextHandle() const { return(context); }
 
     virtual void execute();  
     virtual JSONObject* toJSON();
index c633679..64bd065 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include "GSSWrap.h"
+#include <cache/GSSContextCache.h>
 #include <stdexcept>
 
 /*
@@ -80,6 +81,16 @@ bool GSSWrap::loadParameters(JSONObject *params)
     this->inputMessage.setValue(sInputMessage);
   }
   
+  /***********
+   * context *
+   ***********/
+  if ( ! params->get("arguments").get("context_handle").isNull() )
+  {
+    std::string contextKey = params->get("arguments").get("context_handle").string();
+    GSSContext ctx = GSSContextCache::instance()->retrieve(contextKey);
+    this->context = ctx.getContext();
+  }
+  
   /* Cleanup */
   /* Return */
   return true;
index aba5a65..e7f27c6 100644 (file)
@@ -44,6 +44,7 @@ public:
     int getConfReq() const { return(conf_req); }
     gss_qop_t getQopReq() const { return(qop_req); }
     GSSBuffer getInputMessage () const { return(inputMessage); }
+    gss_ctx_id_t getContext() const { return(context); }
     
 private:
     gss_wrap_type function;
diff --git a/json_gssapi/src/datamodel/GSSContext.cpp b/json_gssapi/src/datamodel/GSSContext.cpp
new file mode 100644 (file)
index 0000000..982033d
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014 <copyright holder> <email>
+ *
+ * For license details, see the LICENSE file in the root of this project.
+ *
+ */
+
+#include "GSSContext.h"
+#include "GSSException.h"
+
+#include <gssapi/gssapi.h>
+
+GSSContext::GSSContext()
+{
+  skipRelease = false;
+  context = GSS_C_NO_CONTEXT;
+}
+
+GSSContext::GSSContext ( const GSSContext& other )
+{
+  // Variables
+  // Error checking
+  // Setup
+  // Main
+  skipRelease = true;
+  this->context = other.context;
+  // Cleanup
+  // Return
+
+}
+
+GSSContext::~GSSContext()
+{
+  // Variables
+  GSSBuffer output;
+  // Error checking
+  // Setup
+  // Main
+  release(&output);
+
+  // Cleanup
+  // Would love to do something useful with outputToken, but in a destructor that's
+  // not particularly meaningful.
+  // Return
+}
+
+void GSSContext::setContext ( gss_ctx_id_t ctxt, bool skipRelease )
+{
+  context = ctxt; 
+  this->skipRelease = skipRelease;
+}
+
+
+GSSContext& GSSContext::operator= ( const GSSContext& other )
+{
+  this->context = other.context;
+  this->skipRelease = true;
+  
+  return *this;
+}
+
+void GSSContext::release(GSSBuffer *output)
+{
+  // Variables
+  gss_buffer_desc outputToken;
+  OM_uint32 major, minor;
+  
+  // Error checking
+  if (GSS_C_NO_CONTEXT == context || skipRelease)
+    return;
+  
+  // Setup
+
+  // Main
+  major = gss_delete_sec_context(&minor, &context, &outputToken);
+  if (GSS_ERROR(major))
+  {
+    throw GSSException("Error in releasing a GSS context", major, minor);
+  }
+
+  output->setValue(&outputToken);
+  
+  // Cleanup
+  // Return
+}
+
+
+  // Variables
+  // Error checking
+  // Setup
+  // Main
+  // Cleanup
+  // Return
diff --git a/json_gssapi/src/datamodel/GSSContext.h b/json_gssapi/src/datamodel/GSSContext.h
new file mode 100644 (file)
index 0000000..bbd2f34
--- /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 GSSCONTEXT_H
+#define GSSCONTEXT_H
+
+#include <gssapi/gssapi.h>
+
+#include "datamodel/GSSBuffer.h"
+
+class GSSCreateSecContextTest;
+class GSSContext
+{
+public:
+    GSSContext();
+    GSSContext ( const GSSContext& other );
+    GSSContext ( gss_ctx_id_t ctxt, bool skipRelease = false ) : context(ctxt), skipRelease(skipRelease) {};
+    ~GSSContext();
+    GSSContext& operator= ( const GSSContext& other );
+    
+    void release(GSSBuffer *output);
+    
+    gss_ctx_id_t getContext() { return(context); };
+    void setContext(gss_ctx_id_t ctxt, bool skipRelease = false);
+    
+private:
+    gss_ctx_id_t context;
+    bool skipRelease; 
+};
+
+#endif // GSSCONTEXT_H
index d7e5cfe..7a1b446 100644 (file)
@@ -8,7 +8,7 @@
 #include "GSSName.h"
 #include "../GSSException.h" 
 
-void GSSName::init(const GSSBuffer namestr, GSSOID name_type, gss_imp_name_type fn)
+void GSSName::init(const GSSBuffer namestr, GSSOID name_type, bool skipRelease, gss_imp_name_type fn)
 {
   /* Variables */
   /* Error checking */
@@ -22,57 +22,20 @@ void GSSName::init(const GSSBuffer namestr, GSSOID name_type, gss_imp_name_type
     errMsg += namestr.toString();
     throw GSSException(errMsg.c_str(), this->major_status, this->minor_status, name_type.toGss());
   }
+  this->skipRelease = skipRelease;
   
   /* Cleanup */
   /* Return */
 }
 
 
-
-GSSName::GSSName(std::string namestr, GSSOID name_type, gss_imp_name_type fn)
-{
-  init(namestr, name_type, fn);
-}
-
-GSSName::GSSName(char *namestr,       GSSOID name_type, gss_imp_name_type fn)
-{
-  init(GSSBuffer(namestr, true), name_type, fn); 
-}
-
-GSSName::GSSName(GSSBuffer namestr,   GSSOID name_type, gss_imp_name_type fn)
-{
-  init(GSSBuffer(namestr), name_type, fn); 
-}
-
-GSSName::GSSName(std::string namestr, gss_OID name_type, gss_imp_name_type fn)
-{
-  init(GSSBuffer(namestr, true), GSSOID(name_type), fn); 
-}
-
-GSSName::GSSName(char *namestr,       gss_OID name_type, gss_imp_name_type fn)
-{
-  init(GSSBuffer(namestr, true), GSSOID(name_type), fn); 
-}
-
-GSSName::GSSName(GSSBuffer namestr,   gss_OID name_type, gss_imp_name_type fn)
-{
-  init(namestr, GSSOID(name_type), fn); 
-}
-
-GSSName::GSSName(std::string namestr, std::string name_type, gss_imp_name_type fn)
-{
-  init(GSSBuffer(namestr, true), GSSOID(name_type), fn); 
-}
-
-GSSName::GSSName(char *namestr,       std::string name_type, gss_imp_name_type fn)
-{
-  init(GSSBuffer(namestr, true), GSSOID(name_type), fn); 
-}
-
-GSSName::GSSName(GSSBuffer namestr,   std::string name_type, gss_imp_name_type fn)
-{
-  init(namestr, GSSOID(name_type), fn); 
+GSSName::GSSName ( gss_name_t gss_name, bool skipRelease )
+{ 
+  name = gss_name; 
+  this->skipRelease = skipRelease; 
+  
 }
 
 void GSSName::release()
 {
@@ -80,12 +43,17 @@ void GSSName::release()
   OM_uint32 major, minor;
   
   /* Error checking */
-  if (name == GSS_C_NO_NAME)
+  if (GSS_C_NO_NAME == name || skipRelease)
     return;
   
   /* Setup */
-  /* Main */ 
+  /* Main */
+  //  if (hashKey.length() > 0)
+  //    std::cout << std::endl << "About to release name for key " << hashKey << std::endl;
+  
   major = gss_release_name(&minor, &name);
+  name = GSS_C_NO_NAME;
+  hashKey = "";
   if ( GSS_ERROR(major) && !( major & GSS_S_BAD_NAME ) )
   {
     throw GSSException("Cannot free memory for a GSS name.", major, minor);
@@ -95,11 +63,45 @@ void GSSName::release()
   /* Return */
 }
 
+GSSName::GSSName ( const GSSName& n )
+{
+  this->hashKey = n.hashKey;
+  if (GSS_C_NO_NAME == n.name)
+  {
+    major_status = 0;
+    minor_status = 0;
+    name = GSS_C_NO_NAME;
+  }
+  else
+  {
+    this->major_status = gss_duplicate_name(&minor_status, n.name, &name);
+    if ( GSS_ERROR(major_status) )
+    {
+      throw GSSException("Cannot copy a GSS name.", major_status, minor_status);
+    }
+  }
+  this->skipRelease = false;
+}
+
 GSSName::~GSSName()
 {
   this->release();
 }  
 
+GSSName& GSSName::operator= ( const GSSName& rhs )
+{
+  if (rhs.toGss() != this->toGss())
+  {
+    this->function = rhs.function;
+    this->minor_status = rhs.minor_status;
+    this->major_status = rhs.major_status;
+    this->name = rhs.name;
+    this->hashKey = rhs.hashKey;
+    this->skipRelease = rhs.skipRelease;
+  }
+  return *this;
+}
+
 
 std::string GSSName::toString() const
 {
@@ -122,9 +124,10 @@ std::string GSSName::toString() const
   return buf.toString();
 }
 
-bool GSSName::setValue ( gss_name_t newName )
+bool GSSName::setValue ( gss_name_t newName, bool skipRelease )
 {
   this->release();
   this->name = newName;
+  this->skipRelease = skipRelease;
   return(true);
 }
index 80ef902..f8a4fdd 100644 (file)
@@ -22,46 +22,18 @@ typedef OM_uint32 (*gss_imp_name_type)(
 
 class GSSName {
 public:
-  GSSName() {name = GSS_C_NO_NAME; };
-  GSSName(std::string nameStr, 
-          GSSOID name_type = GSSOID( (gss_OID)GSS_C_NO_OID ), 
-          gss_imp_name_type fn = (gss_imp_name_type)&gss_import_name);
-  GSSName(std::string nameStr, 
-          gss_OID name_type, 
-          gss_imp_name_type fn = (gss_imp_name_type)&gss_import_name);
-  GSSName(std::string nameStr, 
-          std::string name_type, 
-          gss_imp_name_type fn = (gss_imp_name_type)&gss_import_name);
-
-  GSSName(char *namestr,       
-          GSSOID name_type = GSSOID( (gss_OID)GSS_C_NO_OID ), 
-          gss_imp_name_type fn = (gss_imp_name_type)&gss_import_name);
-  GSSName(char *namestr,       
-          gss_OID name_type, 
-          gss_imp_name_type fn = (gss_imp_name_type)&gss_import_name);
-  GSSName(char *namestr,       
-          std::string name_type, 
-          gss_imp_name_type fn = (gss_imp_name_type)&gss_import_name);
-
-  GSSName(GSSBuffer namestr,   
-          GSSOID name_type = GSSOID( (gss_OID)GSS_C_NO_OID ), 
-          gss_imp_name_type fn = (gss_imp_name_type)&gss_import_name);
-  GSSName(GSSBuffer namestr,   
-          gss_OID name_type, 
-          gss_imp_name_type fn = (gss_imp_name_type)&gss_import_name);
-  GSSName(GSSBuffer namestr,   
-          std::string name_type, 
-          gss_imp_name_type fn = (gss_imp_name_type)&gss_import_name);
-
-  GSSName(gss_name_t gss_name) { name = gss_name; }
+  GSSName() { name = GSS_C_NO_NAME; skipRelease = false; };
+  GSSName(const GSSName& n);
+  GSSName(gss_name_t gss_name, bool skipRelease = false);
 
   ~GSSName();
   
+  GSSName& operator=(const GSSName& rhs);
   
   gss_name_t toGss() const { return(name); }
   std::string toString() const;
   
-  bool setValue(gss_name_t newName);
+  bool setValue(gss_name_t newName, bool skipRelease = false);
   void setKey(std::string key) { this->hashKey = key; }
   std::string getKey() const { return this->hashKey; }
   
@@ -73,8 +45,9 @@ private:
   gss_name_t name;
   gss_imp_name_type function;
   std::string hashKey;
+  bool skipRelease;
   
-  void init(const GSSBuffer namestr, GSSOID name_type, gss_imp_name_type fn);
+  void init(const GSSBuffer namestr, GSSOID name_type, bool skipRelease, gss_imp_name_type fn);
   void release();
 };
 
index 55620b6..d883110 100644 (file)
@@ -1,12 +1,20 @@
 include_directories(${CMAKE_SOURCE_DIR}/src)
 include_directories(${CMAKE_SOURCE_DIR}/src/commands)
 
+find_package (PkgConfig)
+pkg_check_modules (GLIB2   glib-2.0)
+if (GLIB2_FOUND)
+  include_directories(${GLIB2_INCLUDE_DIRS})
+endif(GLIB2_FOUND)
+  
+
 add_executable(test GSSExceptionTest.cpp 
                     GSSAcquireCredTest.cpp 
                     GSSGetMicTest.cpp
                     GSSPseudoRandomTest.cpp 
                     GSSWrapTest.cpp 
-                    GSSUnwrapTest.cpp
+                    GSSUnwrapTest.cpp 
+                    NameCacheTest.cpp
                     command_mocks/InitSecContextMock.cpp
                     command_mocks/MockAcquireCred.cpp
                     command_mocks/MockGetMic.cpp
@@ -31,11 +39,15 @@ add_executable(test GSSExceptionTest.cpp
                     ../src/datamodel/GSSName.cpp
                     ../src/datamodel/GSSOID.cpp
                     ../src/datamodel/GSSOIDSet.cpp
+                    ../src/datamodel/GSSContext.cpp
+                    ../src/util/base64.cpp
+                    ../src/cache/GSSContextCache.cpp
+                    ../src/cache/GSSNameCache.cpp
                     datamodel/GSSBufferTest.cpp
                     datamodel/GSSOIDSetTest.cpp
   )
 
-target_link_libraries(test cppunit gssapi_krb5 jansson crypto)
+target_link_libraries(test cppunit gssapi_krb5 jansson crypto ${GLIB2_LIBRARIES})
 
 # install(TARGETS test RUNTIME DESTINATION bin)
 
index b4b552d..358b9f2 100644 (file)
@@ -144,7 +144,7 @@ void GSSAcquireCredTest::testEmptyCall()
   /* Variables */
   GSSAcquireCred cmd = GSSAcquireCred(&mock_acquire_cred);
   OM_uint32 minor;
-  GSSName steve((char *)"steve@local", (gss_OID)GSS_C_NT_USER_NAME);
+  GSSName steve; // ((char *)"steve@local", (gss_OID)GSS_C_NT_USER_NAME);
   GSSOID moonshotOID((char *)"{1 3 6 1 5 5 15 1 1 18}");
   
   /* Error checking */
index 8315f28..572a939 100644 (file)
@@ -13,6 +13,8 @@
 #include <string.h>
 #include <exception>
 #include "util_json.h"
+#include <cache/GSSContextCache.h>
+#include <datamodel/GSSContext.h>
 
 // Registers the fixture into the 'registry'
 CPPUNIT_TEST_SUITE_REGISTRATION( GSSCreateSecContextTest );
@@ -35,6 +37,8 @@ mock_init_sec(
     OM_uint32             *ret_flags,
     OM_uint32             *time_rec)
 {
+  gss_ctx_id_t tmpContext;
+  
   InitSecContextMock::visited = true;
   
   /* Copy in the input to this function */
@@ -57,13 +61,9 @@ mock_init_sec(
   *time_rec = InitSecContextMock::time_rec;
   
   /* Handle the one that's I/O */
-    if (*context_handle == GSS_C_NO_CONTEXT)
-  {
-    *context_handle = InitSecContextMock::context_handle;
-  } else if (*context_handle != InitSecContextMock::context_handle)
-  {
-    InitSecContextMock::invalidContextHandle = true;
-  }
+  tmpContext = *context_handle;
+  *context_handle = InitSecContextMock::context_handle;
+  InitSecContextMock::context_handle = tmpContext;
 
   return InitSecContextMock::retVal;
 }
@@ -89,10 +89,23 @@ GSSCreateSecContextTest::testConstructor()
   
   cmdFn = cmd.getGSSFunction();
   GSSFn = (void *)&gss_init_sec_context;
-  CPPUNIT_ASSERT_MESSAGE("The default constructor for GSSCreateSecContextCommand should assign the function gss_init_sec_context", cmdFn == GSSFn);
+  CPPUNIT_ASSERT_MESSAGE(
+    "The default constructor for GSSCreateSecContextCommand should assign the function gss_init_sec_context", 
+    cmdFn == GSSFn);
 }
 
-
+/* JSON Input:
+ * { 
+ *   "method": "gss_create_sec_context",
+ *   "arguments": 
+ *   {
+ *     "req_flags": "1",
+ *     "time_req": "2",
+ *     "mech_type": "{ 1 2 840 113554 1 2 1 4 }",
+ *     "target_name": "me@my.sha/DOW"
+ *   }
+ * }
+ */
 void GSSCreateSecContextTest::testConstructorWithJSONObject()
 {
   const char* input = "{\"method\": \"gss_create_sec_context\", \
@@ -146,13 +159,15 @@ void GSSCreateSecContextTest::testConstructorWithJSONObject()
 void
 GSSCreateSecContextTest::testEmptyCall()
 {
+  gss_ctx_id_t expectedResult, expectedArgument;
+  
   GSSCreateSecContextCommand cmd ((void *)&mock_init_sec);
   
   /* Set expectations on what the GSS function will be called with */
   cmd.time_req = rand() % 1024;
   cmd.req_flags = rand() % 1024;
   cmd.target_name = NULL;
-  cmd.context_handle = GSS_C_NO_CONTEXT;
+  cmd.context_handle = expectedArgument = (gss_ctx_id_t)rand();
   
   CPPUNIT_ASSERT_MESSAGE(
     "The mech_type values differ.",
@@ -164,7 +179,7 @@ GSSCreateSecContextTest::testEmptyCall()
   /* Set expectations on what the GSS function will produce */
   InitSecContextMock::retVal = rand() % 1024;
   InitSecContextMock::minor_status = rand() % 1024;
-  InitSecContextMock::context_handle = GSS_C_NO_CONTEXT;
+  InitSecContextMock::context_handle = expectedResult = (gss_ctx_id_t)rand();
   InitSecContextMock::actual_mech_type = NULL;
   InitSecContextMock::output_token.value = (void *)"http@project-moonshot.org/PROJECT-MOONSHOT.ORG\0";
   InitSecContextMock::output_token.length = strlen((char *)InitSecContextMock::output_token.value);
@@ -213,10 +228,15 @@ GSSCreateSecContextTest::testEmptyCall()
   );
   CPPUNIT_ASSERT_EQUAL_MESSAGE(
     "context_handle was not copied back to the command.",
-    InitSecContextMock::context_handle,
+    expectedResult,
     cmd.context_handle
   );
   CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "context_handle was not copied back to the command.",
+    expectedArgument,
+    InitSecContextMock::context_handle
+  );
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
     "actual_mech_type was not copied back to the command.",
     InitSecContextMock::actual_mech_type,
     cmd.actual_mech_type
@@ -236,13 +256,37 @@ GSSCreateSecContextTest::testEmptyCall()
     InitSecContextMock::time_rec,
     cmd.time_rec
   );
+  
+  // Set this to no context, or cleanup attempts to free the not-a-real-pointer.
+  InitSecContextMock::context_handle = GSS_C_NO_CONTEXT;
+  
 }
 
+/* Expected JSON output:
+ * 
+ * {
+ *   "command": "gss_init_sec_context", 
+ *   "return_values": 
+ *   {
+ *     "context_handle": "base64_encoded_string", 
+ *     "major_status": ##, 
+ *     "output_token": "http@project-moonshot.org/PROJECT-MOONSHOT.ORG", 
+ *     "actual_mech_type": "{ 1 3 6 1 5 5 13 4 }", 
+ *     "minor_status": ##, 
+ *     ret_flags": ##, 
+ *     "time_rec": ##
+ *   }
+ * }
+ * 
+ */
 void GSSCreateSecContextTest::testJSONMarshal()
 {
   /* Variables */
   GSSCreateSecContextCommand cmd ((void *)&mock_init_sec);
   JSONObject *result;
+  GSSContextCache *cache = GSSContextCache::instance();
+  GSSContext context;
+  gss_ctx_id_t expectedResult;
   
   /* Error checking */
   
@@ -250,7 +294,7 @@ void GSSCreateSecContextTest::testJSONMarshal()
   // Set expectations on what the GSS function will produce
   InitSecContextMock::retVal = GSS_S_BAD_MECH;
   InitSecContextMock::minor_status = 20;
-  InitSecContextMock::context_handle = GSS_C_NO_CONTEXT;
+  InitSecContextMock::context_handle = expectedResult = (gss_ctx_id_t)rand();
   InitSecContextMock::actual_mech_type = (gss_OID)GSS_C_MA_MECH_NEGO;
   InitSecContextMock::output_token.value = (void *)"http@project-moonshot.org/PROJECT-MOONSHOT.ORG\0";
   InitSecContextMock::output_token.length = strlen((char *)InitSecContextMock::output_token.value);
@@ -266,6 +310,8 @@ void GSSCreateSecContextTest::testJSONMarshal()
   /* Main */
   cmd.execute();
   result = cmd.toJSON();
+/*  
+  std::cout << "create sec context json: " << result->dump() << "\n";*/
   
   CPPUNIT_ASSERT_MESSAGE(
     "The command name is incorrect",
@@ -310,6 +356,13 @@ void GSSCreateSecContextTest::testJSONMarshal()
     (int)( (*result)["return_values"]["time_rec"].integer() )
   );
   
+  context = cache->retrieve( (*result)["return_values"]["context_handle"].string() );
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The returned context was reported incorrectly",
+    (long)expectedResult,
+    (long)context.getContext()
+  );
   
   /* Cleanup */
   /* Return */
index 52d7f46..dee46e1 100644 (file)
 // #include <cppunit/TestFixture.h>
 #include <cppunit/extensions/HelperMacros.h>
 
+#include <stdlib.h>
+
 #include <gssapi.h>
-#include "GSSCreateSecContextCommand.h"
 
-#include <stdlib.h>
+#include "commands/GSSCreateSecContextCommand.h"
 
 class GSSCreateSecContextTest :  public CppUnit::TestFixture
 {
@@ -36,6 +37,7 @@ public:
   void testConstructorWithJSONObject();
   void testEmptyCall();
   void testJSONMarshal();
+  void getCache();
   
 private:
   GSSCreateSecContextCommand command;
index 6600be8..1875b36 100644 (file)
@@ -8,6 +8,8 @@
 #include "GSSGetMicTest.h"
 #include "command_mocks/MockGetMic.h"
 #include "GSSGetMic.h"
+#include <datamodel/GSSContext.h>
+#include <cache/GSSContextCache.h>
 #include <gssapi/gssapi.h>
 
 CPPUNIT_TEST_SUITE_REGISTRATION( GSSGetMicTest );
@@ -130,16 +132,19 @@ void GSSGetMicTest::testEmptyCall()
 void GSSGetMicTest::testConstructorWithJSONObject()
 {
   /* Variables */
-  const char* input = "{\"method\": \"gss_get_mic\", \
+  GSSContext context((gss_ctx_id_t)rand(), true);
+  std::string key = GSSContextCache::instance()->store(context);
+
+  std::string input = "{\"method\": \"gss_get_mic\", \
     \"arguments\": \
     { \
-         \"context_handle\": \"#######\", \
+         \"context_handle\": \"" + key + "\", \
          \"qop_req\": \"GSS_C_QOP_DEFAULT\", \
          \"input_message\": \"mary had a little lamb\" \
     }\
   }";
   json_error_t jsonErr;
-  JSONObject json = JSONObject::load(input, 0, &jsonErr);
+  JSONObject json = JSONObject::load(input.c_str(), 0, &jsonErr);
   
   GSSGetMic cmd = GSSGetMic(&json, &mock_get_mic);
   
@@ -159,6 +164,12 @@ void GSSGetMicTest::testConstructorWithJSONObject()
     cmd.getInputMessage().toString()
   );
   
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "GSSGetMic did not retrieve the context handle correctly",
+    context.getContext(),
+    cmd.getContextHandle()
+  );
+  
   /* Cleanup */
   /* Return */
 }
index 2deab3c..a890af6 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "GSSImportNameTest.h"
 #include "GSSImportName.h"
+#include <cache/GSSNameCache.h>
 #include "command_mocks/MockImportName.h"
 
 CPPUNIT_TEST_SUITE_REGISTRATION( GSSImportNameTest );
@@ -160,26 +161,41 @@ void GSSImportNameTest::testConstructorWithJSONObject()
   /* Cleanup */
   /* Return */
 }
+
+
+/* Expected output sample:
+ * 
+ * {
+ *   "command": "gss_import_name",
+ *   "return_values":
+ *   {
+ *     "major_status": 0,
+ *     "minor_status": 0,
+ *     "gss_name": "base64_encoded_string"
+ *   }
+ * }
+ */
 void GSSImportNameTest::testJSONMarshal()
 {
   /* Variables */
   std::string name("dns@google.com");
   std::string type("{ 1 2 840 113554 1 2 1 4 }");
+  std::string key;
+  GSSName gssName;
   JSONObject *result;
-  GSSImportName cmd = GSSImportName(&mock_import_name);
+  GSSImportName cmd;
   
   /* Error checking */
   /* Setup */
   cmd.setInputName(name);
   cmd.setInputNameType(type);
-  MockImportName::minor_status = 0;
-  MockImportName::retVal = 0;
-  MockImportName::output_name.setValue(GSS_C_NO_NAME);
   
   /* Main */
   cmd.execute();
   result = cmd.toJSON();
   
+//   std::cout << "JSON Output:" << std::endl << result->dump(4) << std::endl;
+  
   CPPUNIT_ASSERT_EQUAL_MESSAGE(
     "The command name is incorrect",
     std::string("gss_import_name"),
@@ -199,10 +215,13 @@ void GSSImportNameTest::testJSONMarshal()
     (int)( (*result)["return_values"]["minor_status"].integer() )
   );
   
+  key = (*result)["return_values"]["gss_name"].string();
+  gssName = GSSNameCache::instance()->retrieve(key);
+  
   CPPUNIT_ASSERT_EQUAL_MESSAGE(
     "The gss_name was reported incorrectly",
-    std::string("constant for now"),
-    std::string( (*result)["return_values"]["gss_name"].string() )
+    name,
+    gssName.toString()
   );
   
   
index 12693ad..e38ab49 100644 (file)
@@ -6,14 +6,17 @@
  */
 
 #include <algorithm>
+#include <string>
 
 //#include <cppunit/TestFixture.h>
 //#include <cppunit/extensions/HelperMacros.h>
 #include <openssl/rand.h>
 
+#include "cache/GSSContextCache.h"
+#include "datamodel/GSSContext.h"
+#include "command_mocks/MockPseudoRandom.h"
 #include "GSSPseudoRandom.h"
 #include "GSSPseudoRandomTest.h"
-#include "command_mocks/MockPseudoRandom.h"
 
 // Registers the fixture into the 'registry'
 CPPUNIT_TEST_SUITE_REGISTRATION( GSSPseudoRandomTest );
@@ -173,7 +176,7 @@ void GSSPseudoRandomTest::testEmptyCall()
  * {"method":    "gss_pseudo_random",
  *  "arguments": 
  *   {
- *     "context_handle":     "########",
+ *     "context_handle":     "context handle key",
  *     "prf_key":            ###,
  *     "prf_in":             "la la la input message",
  *     "desired_output_len": ####
@@ -183,17 +186,20 @@ void GSSPseudoRandomTest::testEmptyCall()
 void GSSPseudoRandomTest::testConstructorWithJSONObject()
 {
   /* Variables */
-  const char* input = "{\"method\": \"gss_pseudo_random\", \
+  GSSContext context( (gss_ctx_id_t)rand(), true );
+  std::string key = GSSContextCache::instance()->store(context);
+  
+  std::string input = "{\"method\": \"gss_pseudo_random\", \
     \"arguments\": \
     { \
-         \"context_handle\": \"#######\", \
+         \"context_handle\": \"" + key + "\", \
          \"prf_key\": 1234567890, \
          \"prf_in\": \"mary had a little lamb\", \
          \"desired_output_len\": 256 \
     }\
   }";
   json_error_t jsonErr;
-  JSONObject json = JSONObject::load(input, 0, &jsonErr);
+  JSONObject json = JSONObject::load(input.c_str(), 0, &jsonErr);
   
   GSSPseudoRandom cmd = GSSPseudoRandom(&json, &mock_gss_pseudo_random);
 
@@ -202,6 +208,12 @@ void GSSPseudoRandomTest::testConstructorWithJSONObject()
   /* Main */
   
   CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "GSSWrap did not retrive the GSS context correctly",
+    context.getContext(),
+    cmd.getContextHandle()
+  );
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
     "GSSPseudoRandom did not parse the prf_key argument correctly.",
     1234567890,
     cmd.getKey()
index d807b52..7b26008 100644 (file)
@@ -5,11 +5,16 @@
  *
  */
 
+#include <string>
+
 #include "GSSUnwrapTest.h"
 #include "command_mocks/MockUnwrap.h"
 #include "GSSUnwrap.h"
+#include <datamodel/GSSContext.h>
+#include <cache/GSSContextCache.h>
 #include <gssapi/gssapi.h>
 
+
 CPPUNIT_TEST_SUITE_REGISTRATION( GSSUnwrapTest );
 
 /* 
@@ -138,15 +143,17 @@ void GSSUnwrapTest::testEmptyCall()
 void GSSUnwrapTest::testConstructorWithJSONObject()
 {
   /* Variables */
-  const char* input = "{\"method\": \"gss_wrap\", \
+  GSSContext context((gss_ctx_id_t)rand(), true);
+  std::string key = GSSContextCache::instance()->store(context);
+  std::string input = "{\"method\": \"gss_wrap\", \
     \"arguments\": \
     { \
-         \"context_handle\": \"#######\", \
+         \"context_handle\": \"" + key + "\", \
          \"input_message\": \"mary had a little lamb\" \
     }\
   }";
   json_error_t jsonErr;
-  JSONObject json = JSONObject::load(input, 0, &jsonErr);
+  JSONObject json = JSONObject::load(input.c_str(), 0, &jsonErr);
   
   GSSUnwrap cmd = GSSUnwrap(&json, &mock_unwrap);
   
@@ -155,6 +162,12 @@ void GSSUnwrapTest::testConstructorWithJSONObject()
   /* Main */
   
   CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "GSSUnwrap did not retrieve the GSS context correctly",
+    context.getContext(),
+    cmd.getContextHandle()
+  );
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
     "GSSUnwrap did not parse the input message argument correctly",
     std::string("mary had a little lamb"),
     cmd.getInputMessage().toString()
index 7582722..50dbf2d 100644 (file)
@@ -8,6 +8,8 @@
 #include "GSSWrapTest.h"
 #include "command_mocks/MockWrap.h"
 #include "GSSWrap.h"
+#include <datamodel/GSSContext.h>
+#include <cache/GSSContextCache.h>
 #include <gssapi/gssapi.h>
 
 CPPUNIT_TEST_SUITE_REGISTRATION( GSSWrapTest );
@@ -146,20 +148,36 @@ void GSSWrapTest::testEmptyCall()
   /* Return */
 }
 
+/*
+ * Example JSON input:
+ * {
+ *   "method": "gss_wrap",
+ *   "arguments": {
+ *     "context_handle": "stuff",
+ *     "conf_req": "TRUE",
+ *     "qop_req": "GSS_C_QOP_DEFAULT",
+ *     "input_message": "mary had a little lamb"
+ *   }
+ * }
+ * 
+ */
 void GSSWrapTest::testConstructorWithJSONObject()
 {
   /* Variables */
-  const char* input = "{\"method\": \"gss_wrap\", \
+  GSSContext context( (gss_ctx_id_t)rand(), true );
+  std::string key = GSSContextCache::instance()->store(context);
+  
+  std::string input = "{\"method\": \"gss_wrap\", \
     \"arguments\": \
     { \
-         \"context_handle\": \"#######\", \
+         \"context_handle\": \"" + key + "\", \
          \"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);
+  JSONObject json = JSONObject::load(input.c_str(), 0, &jsonErr);
   
   GSSWrap cmd = GSSWrap(&json, &mock_wrap);
   
@@ -168,6 +186,12 @@ void GSSWrapTest::testConstructorWithJSONObject()
   /* Main */
   
   CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "GSSWrap did not retrive the GSS context correctly",
+    context.getContext(),
+    cmd.getContext()
+  );
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
     "GSSWrap did not parse the conf_req argument correctly",
     1,
     cmd.getConfReq()
@@ -191,7 +215,19 @@ void GSSWrapTest::testConstructorWithJSONObject()
   /* Return */
 }
 
-
+/* Desired JSON output:
+ * 
+ * {
+ *  "command":       "gss_wrap",
+ *  "return_values": 
+ *  {
+ *      "major_status":   0,
+ *      "minor_status":   0,
+ *      "conf_state":     "TRUE",
+ *      "output_message": "asdf"
+ *  }
+ * }
+ */
 void GSSWrapTest::testJSONMarshal()
 {
   /* Variables */
diff --git a/json_gssapi/test/NameCacheTest.cpp b/json_gssapi/test/NameCacheTest.cpp
new file mode 100644 (file)
index 0000000..883a9cb
--- /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.
+ *
+ */
+
+#include <string>
+#include <iostream>
+
+#include "NameCacheTest.h"
+#include "cache/GSSNameCache.h"
+#include "datamodel/GSSName.h"
+#include <GSSImportName.h>
+
+CPPUNIT_TEST_SUITE_REGISTRATION( NameCacheTest );
+
+void NameCacheTest::setUp()
+{
+
+}
+
+void NameCacheTest::tearDown()
+{
+
+}
+
+void NameCacheTest::testStore()
+{
+  /* Variables      */
+  std::string  key;
+  GSSName      source( (gss_name_t)rand(), true), target;
+  
+  /* Error checking */
+  /* Setup          */
+
+  
+  /* Main           */
+  
+  // Store the data
+  key = GSSNameCache::instance()->store(source);
+  
+  // verify that the data can be retrieved.
+  target = GSSNameCache::instance()->retrieve(key);
+  
+  CPPUNIT_ASSERT_EQUAL_MESSAGE(
+    "The name cache did not store and retrieve the same data",
+    source.toGss(),
+    target.toGss()
+  );
+
+  /* Cleanup        */
+  /* Return         */
+  
+}
+
+
+
+  /* Variables      */
+  /* Error checking */
+  /* Setup          */
+  /* Main           */
+  /* Cleanup        */
+  /* Return         */
diff --git a/json_gssapi/test/NameCacheTest.h b/json_gssapi/test/NameCacheTest.h
new file mode 100644 (file)
index 0000000..ffa4f54
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2014 <copyright holder> <email>
+ *
+ * For license details, see the LICENSE file in the root of this project.
+ *
+ */
+
+#ifndef NAMECACHETEST_H
+#define NAMECACHETEST_H
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+class NameCacheTest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( NameCacheTest );
+  CPPUNIT_TEST( testStore );
+//   CPPUNIT_TEST( testStoreWithKey );
+//   CPPUNIT_TEST( testRetrieve );
+  CPPUNIT_TEST_SUITE_END();
+
+public:
+    virtual void setUp();
+    virtual void tearDown();
+    
+    void testStore();
+//     void testStoreWithKey();
+//     void testRetrieve();
+};
+
+#endif // NAMECACHETEST_H
+