From 46a4871443c10f883be9822b5975d9d70d71f7fc Mon Sep 17 00:00:00 2001 From: Mark Donnelly Date: Tue, 30 Jun 2015 14:50:46 -0400 Subject: [PATCH] GSSAcquireCred works. * Add a cache of acquired credentials * Implement the Acquire Cred * Serialize credentials appropriately --- json_gssapi/CMakeLists.txt | 1 + json_gssapi/src/cache/GSSCredentialCache.cpp | 138 +++++++++++++++++++++++++++ json_gssapi/src/cache/GSSCredentialCache.h | 67 +++++++++++++ json_gssapi/src/commands/GSSAcquireCred.cpp | 32 ++++--- json_gssapi/src/commands/GSSAcquireCred.h | 2 + json_gssapi/src/datamodel/GSSCredential.cpp | 2 + json_gssapi/src/datamodel/GSSCredential.h | 3 + json_gssapi/src/datamodel/GSSOIDSet.cpp | 9 +- json_gssapi/test/CMakeLists.txt | 1 + 9 files changed, 238 insertions(+), 17 deletions(-) create mode 100644 json_gssapi/src/cache/GSSCredentialCache.cpp create mode 100644 json_gssapi/src/cache/GSSCredentialCache.h diff --git a/json_gssapi/CMakeLists.txt b/json_gssapi/CMakeLists.txt index 29c8d11..2568286 100644 --- a/json_gssapi/CMakeLists.txt +++ b/json_gssapi/CMakeLists.txt @@ -58,6 +58,7 @@ add_library(jsongssapi SHARED src/utils/util_json.cpp src/utils/util_random.cpp src/cache/GSSContextCache.cpp + src/cache/GSSCredentialCache.cpp src/cache/GSSNameCache.cpp src/datamodel/GSSContext.cpp ) diff --git a/json_gssapi/src/cache/GSSCredentialCache.cpp b/json_gssapi/src/cache/GSSCredentialCache.cpp new file mode 100644 index 0000000..1799107 --- /dev/null +++ b/json_gssapi/src/cache/GSSCredentialCache.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2014, 2015 JANET(UK) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of JANET(UK) nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include "GSSCredentialCache.h" +#include "utils/util_base64.h" +#include "utils/util_random.h" + +#define KEYLEN 128 + +GSSCredentialCache* GSSCredentialCache::_instance = 0; + +GSSCredentialCache::GSSCredentialCache() +{ + +} + +GSSCredentialCache::GSSCredentialCache ( const GSSCredentialCache& other ) +{ + credentials = other.credentials; +} + +GSSCredentialCache::~GSSCredentialCache() +{ + +} + +GSSCredentialCache& GSSCredentialCache::operator= ( const GSSCredentialCache& other ) +{ + credentials = other.credentials; + + return *this; +} + + +std::string GSSCredentialCache::store ( GSSCredential& 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 + credentials[key] = &data; + + /* Cleanup */ + /* Return */ + // Return the key for future reference + return(key); +} + +/************************************* + * Generate random bytes, and base64 * + * encode them to be JSONable keys * + *************************************/ +bool GSSCredentialCache::generateKey(std::string &key) +{ + /* Variables */ + unsigned char theKey[KEYLEN]; + + /* Setup */ + /* Main */ + // Generate random byte string + if (!randGenPseudoRandom(theKey, KEYLEN)) + return(false); + + // Encode the binary string + base64EncodeStr(theKey, KEYLEN, key); + /* Cleanup */ + /* Return */ + return(true); +} + +GSSCredential& GSSCredentialCache::retrieve ( std::string key ) +{ + /* Variables */ + //GSSCredential data; + + /* Error checking */ + /* Setup */ + /* Main */ + + /* Cleanup */ + /* Return */ + return *(credentials[key]); +} + +GSSCredentialCache* GSSCredentialCache::instance() +{ + if (_instance == 0) + _instance = new GSSCredentialCache; + + return _instance; +} + diff --git a/json_gssapi/src/cache/GSSCredentialCache.h b/json_gssapi/src/cache/GSSCredentialCache.h new file mode 100644 index 0000000..b92c5d5 --- /dev/null +++ b/json_gssapi/src/cache/GSSCredentialCache.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014, 2015 JANET(UK) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of JANET(UK) nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GSSCREDENTIALCACHE_H +#define GSSCREDENTIALCACHE_H + +#include +#include + +#include "datamodel/GSSCredential.h" + +typedef std::map CredentialMap; + +class GSSCredentialCache +{ +public: + static GSSCredentialCache* instance(); + ~GSSCredentialCache(); + GSSCredentialCache& operator= ( const GSSCredentialCache& other ); + + std::string store(GSSCredential &data, const std::string key = ""); + GSSCredential &retrieve(std::string key); + CredentialMap getCredentials() { return(credentials); }; + +protected: + GSSCredentialCache(); + GSSCredentialCache ( const GSSCredentialCache& other ); + +private: + CredentialMap credentials; + + bool generateKey(std::string &key); + static GSSCredentialCache* _instance; +}; + +#endif // GSSCREDENTIALCACHE_H diff --git a/json_gssapi/src/commands/GSSAcquireCred.cpp b/json_gssapi/src/commands/GSSAcquireCred.cpp index 086a4a2..06da60d 100644 --- a/json_gssapi/src/commands/GSSAcquireCred.cpp +++ b/json_gssapi/src/commands/GSSAcquireCred.cpp @@ -34,15 +34,15 @@ #include "GSSAcquireCred.h" #include "GSSException.h" +#include #include +#include #include GSSAcquireCred::GSSAcquireCred(gss_acq_cred_type fn) : function(fn) { desired_name = GSS_C_NO_NAME; - // Use OID for eap-aes128 by default - desiredMechs.addOID( GSSOID((char *)"{ 1 3 6 1 5 5 15 1 1 17 }") ); } GSSAcquireCred::GSSAcquireCred ( const GSSAcquireCred& other ) @@ -66,6 +66,8 @@ GSSAcquireCred::GSSAcquireCred ( /* Main */ loadParameters(params); function = fn; + values = new JSONObject(); + /* Cleanup */ /* Return */ } @@ -123,6 +125,9 @@ bool GSSAcquireCred::loadParameters(JSONObject *params) } } else throw std::invalid_argument("Unrecognized desired_mechs array."); + } else { + // Use OID for eap-aes128 by default + desiredMechs.addOID( GSSOID((char *)"{ 1 3 6 1 5 5 15 1 1 17 }") ); } /**************** @@ -147,6 +152,8 @@ void GSSAcquireCred::execute() /* Variables */ gss_cred_id_t output_cred_handle; gss_OID_set actual_mechs; + JSONObject errors; + std::string key; /* Error checking */ /* Setup */ @@ -161,16 +168,15 @@ void GSSAcquireCred::execute() &actual_mechs, &this->time_rec ); - - if (GSS_ERROR(this->retVal) ) - { - std::string err("Error acquiring credential for user '"); - err += desired_name.toString(); - err += "'."; - throw GSSException(err, this->retVal, this->minor_status); - } + + GSSDisplayStatus ds(retVal, minor_status, NULL); + errors.set("major_status_message", ds.getMajorMessage().c_str()); + errors.set("minor_status_message", ds.getMinorMessage().c_str()); + values->set("errors", errors); this->cred.setValue(output_cred_handle); + key = GSSCredentialCache::instance()->store(this->cred); + this->cred.setKey(key); this->actualMechs = actual_mechs; /* Cleanup */ @@ -193,7 +199,6 @@ void GSSAcquireCred::execute() JSONObject *GSSAcquireCred::toJSON() { /* Variables */ - JSONObject *values = new JSONObject(); JSONObject *temp; /* Error checking */ @@ -207,10 +212,9 @@ JSONObject *GSSAcquireCred::toJSON() values->set("minor_status", this->minor_status); values->set("time_rec", (int)this->time_rec ); - // Objects that generate their own JSONObject - temp = this->cred.toJSONValue(); - values->set("output_cred_handle", *temp ); + values->set("output_cred_handle", this->cred.getKey().c_str() ); + // Objects that generate their own JSONObject temp = this->actualMechs.toJSONValue(); values->set("actual_mechs", *temp); diff --git a/json_gssapi/src/commands/GSSAcquireCred.h b/json_gssapi/src/commands/GSSAcquireCred.h index a01acf5..326eb11 100644 --- a/json_gssapi/src/commands/GSSAcquireCred.h +++ b/json_gssapi/src/commands/GSSAcquireCred.h @@ -84,6 +84,8 @@ private: OM_uint32 retVal, minor_status; gss_acq_cred_type function; + + JSONObject *values; }; diff --git a/json_gssapi/src/datamodel/GSSCredential.cpp b/json_gssapi/src/datamodel/GSSCredential.cpp index 8fcc202..7914a6e 100644 --- a/json_gssapi/src/datamodel/GSSCredential.cpp +++ b/json_gssapi/src/datamodel/GSSCredential.cpp @@ -43,11 +43,13 @@ GSSCredential::GSSCredential() GSSCredential::GSSCredential ( const GSSCredential& other ) { this->credential = other.credential; + this->hashKey = other.hashKey; } GSSCredential& GSSCredential::operator= ( const GSSCredential& gsscred ) { this->credential = gsscred.credential; + this->hashKey = ""; return(*this); } diff --git a/json_gssapi/src/datamodel/GSSCredential.h b/json_gssapi/src/datamodel/GSSCredential.h index ddef596..2e8971f 100644 --- a/json_gssapi/src/datamodel/GSSCredential.h +++ b/json_gssapi/src/datamodel/GSSCredential.h @@ -65,9 +65,12 @@ public: void setValue(gss_cred_id_t cred) { this->credential = cred; } JSONObject *toJSONValue() { return( new JSONObject("not now") ); } + void setKey(std::string key) { this->hashKey = key; } + std::string getKey() const { return this->hashKey; } private: gss_cred_id_t credential; + std::string hashKey; }; diff --git a/json_gssapi/src/datamodel/GSSOIDSet.cpp b/json_gssapi/src/datamodel/GSSOIDSet.cpp index 1c8d49b..fdd60a5 100644 --- a/json_gssapi/src/datamodel/GSSOIDSet.cpp +++ b/json_gssapi/src/datamodel/GSSOIDSet.cpp @@ -91,10 +91,13 @@ GSSOIDSet& GSSOIDSet::operator= ( const gss_OID_set other ) /* Main */ this->releaseOIDSet(); this->init(); - for(i = 0; i < other->count; i++) + if (NULL != other) { - element = other->elements + i; - this->addOID(element); + for(i = 0; i < other->count; i++) + { + element = other->elements + i; + this->addOID(element); + } } /* Cleanup */ diff --git a/json_gssapi/test/CMakeLists.txt b/json_gssapi/test/CMakeLists.txt index 5c69627..2c71d2c 100644 --- a/json_gssapi/test/CMakeLists.txt +++ b/json_gssapi/test/CMakeLists.txt @@ -76,6 +76,7 @@ add_executable(test GSSExceptionTest.cpp ../src/datamodel/GSSOIDSet.cpp ../src/datamodel/GSSContext.cpp ../src/cache/GSSContextCache.cpp + ../src/cache/GSSCredentialCache.cpp ../src/cache/GSSNameCache.cpp datamodel/GSSBufferTest.cpp datamodel/GSSOIDSetTest.cpp -- 2.1.4