Merge branch 'master' into tlv-mic
authorLuke Howard <lukeh@padl.com>
Tue, 29 Mar 2011 14:59:33 +0000 (01:59 +1100)
committerLuke Howard <lukeh@padl.com>
Tue, 29 Mar 2011 14:59:33 +0000 (01:59 +1100)
mech_eap/util_attr.cpp
mech_eap/util_json.cpp
mech_eap/util_json.h
mech_eap/util_radius.cpp
mech_eap/util_shib.cpp
shibboleth/resolver

index 1fe754e..77f6759 100644 (file)
@@ -636,7 +636,7 @@ gss_eap_attr_ctx::exportToBuffer(gss_buffer_t buffer) const
     JSONObject obj = jsonRepresentation();
 
 #if 0
-    obj.dump(stdout, JSON_INDENT(3));
+    obj.dump(stdout);
 #endif
 
     s = obj.dump(JSON_COMPACT);
@@ -679,8 +679,6 @@ gss_eap_attr_ctx::mapException(OM_uint32 *minor, std::exception &e) const
     OM_uint32 major;
 
     /* Errors we handle ourselves */
-    major = GSS_S_FAILURE;
-
     if (typeid(e) == typeid(std::bad_alloc)) {
         *minor = ENOMEM;
         goto cleanup;
@@ -688,6 +686,9 @@ gss_eap_attr_ctx::mapException(OM_uint32 *minor, std::exception &e) const
         major = GSS_S_BAD_NAME;
         *minor = GSSEAP_BAD_ATTR_TOKEN;
         goto cleanup;
+    } else if (this == NULL) {
+        major = GSS_S_FAILURE;
+        goto cleanup;
     }
 
     /* Errors we delegate to providers */
@@ -884,8 +885,10 @@ gssEapGetNameAttribute(OM_uint32 *minor,
                        gss_buffer_t display_value,
                        int *more)
 {
-    *authenticated = 0;
-    *complete = 0;
+    if (authenticated != NULL)
+        *authenticated = 0;
+    if (complete != NULL)
+        *complete = 0;
 
     if (value != NULL) {
         value->length = 0;
index 76cf31c..64e6541 100644 (file)
@@ -330,36 +330,41 @@ JSONObject::isnull(void) const
     return json_is_null(m_obj);
 }
 
-JSONObject::JSONObject(DDF &ddf)
+JSONObject
+JSONObject::ddf(DDF &ddf)
 {
     if (ddf.isstruct()) {
         DDF elem = ddf.first();
-        JSONObject jobj = JSONObject::array();
+        JSONObject jobj = JSONObject::object();
 
         while (!elem.isnull()) {
-            JSONObject jtmp(elem);
-            jobj.append(jtmp);
+            JSONObject jtmp = JSONObject::ddf(elem);
+            jobj.set(elem.name(), jtmp);
             elem = ddf.next();
         }
+
+        return jobj;
     } else if (ddf.islist()) {
         DDF elem = ddf.first();
-        JSONObject jobj = JSONObject::object();
+        JSONObject jobj = JSONObject::array();
 
         while (!elem.isnull()) {
-            JSONObject jtmp(elem);
-            jobj.set(elem.name(), jtmp);
+            JSONObject jtmp = JSONObject::ddf(elem);
+            jobj.append(jtmp);
             elem = ddf.next();
         }
+
+        return jobj;
     } else if (ddf.isstring()) {
-        JSONObject(ddf.string());
+        return JSONObject(ddf.string());
     } else if (ddf.isint()) {
-        JSONObject((json_int_t)ddf.integer());
+        return JSONObject((json_int_t)ddf.integer());
     } else if (ddf.isfloat()) {
-        JSONObject(ddf.floating());
+        return JSONObject(ddf.floating());
     } else if (ddf.isempty() || ddf.ispointer()) {
-        JSONObject::object();
+        return JSONObject::object();
     } else if (ddf.isnull()) {
-        JSONObject::null();
+        return JSONObject::null();
     }
 
     std::string s("Unbridgeable DDF object");
@@ -378,7 +383,7 @@ JSONObject::ddf(void) const
         do {
             const char *key = iter.key();
             DDF value = iter.value().ddf();
-            ddf.add(value.name(key));
+            ddf.addmember(key).swap(value);
         } while (iter.next());
         break;
     }
@@ -410,7 +415,7 @@ JSONObject::ddf(void) const
         break;
     }
 
-    return DDF(NULL);
+    return ddf;
 }
 
 JSONIterator::JSONIterator(const JSONObject &obj)
index f987d34..322d03e 100644 (file)
@@ -70,15 +70,15 @@ namespace gss_eap_util {
         static JSONObject object(void);
         static JSONObject array(void);
         static JSONObject null(void);
+        static JSONObject ddf(DDF &value);
 
         char *dump(size_t flags = 0) const;
-        void dump(FILE *fp, size_t flags = 0) const;
+        void dump(FILE *fp, size_t flags = JSON_INDENT(4)) const;
 
         json_type type(void) const { return json_typeof(m_obj); }
         size_t size(void) const;
 
         JSONObject(void);
-        JSONObject(DDF &value);
         JSONObject(const char *value);
         JSONObject(json_int_t value);
         JSONObject(double value);
@@ -140,7 +140,7 @@ namespace gss_eap_util {
             }
         }
 
-        JSONObject(json_t *obj, bool retain);
+        JSONObject(json_t *obj, bool retain = true);
 
         json_t *m_obj;
     };
index fe43135..1d5efab 100644 (file)
@@ -754,6 +754,8 @@ gss_eap_radius_attr_provider::initWithJsonObject(const gss_eap_attr_ctx *ctx,
         pNext = &vp->next;
     }
 
+    m_authenticated = obj["authenticated"].integer();
+
     return true;
 }
 
@@ -775,6 +777,8 @@ gss_eap_radius_attr_provider::jsonRepresentation(void) const
 
     obj.set("attributes", attrs);
 
+    obj.set("authenticated", m_authenticated);
+
     return obj;
 }
 
index 27e8b8f..7ddd843 100644 (file)
@@ -105,13 +105,49 @@ gss_eap_shib_attr_provider::initFromExistingContext(const gss_eap_attr_ctx *mana
     return true;
 }
 
+static OM_uint32
+exportMechSecContext(OM_uint32 *minor,
+                     gss_ctx_id_t gssCtx,
+                     gss_buffer_t mechContext)
+{
+    OM_uint32 major;
+    gss_buffer_desc exportedCtx;
+    unsigned char *p;
+
+    assert(gssCtx->mechanismUsed != GSS_C_NO_OID);
+
+    major = gssEapExportSecContext(minor, gssCtx, &exportedCtx);
+    if (GSS_ERROR(major))
+        return major;
+
+    /*
+     * gss_import_sec_context expects the exported security context token
+     * to be tagged with the mechanism OID; in Heimdal and MIT, this is
+     * done by the mechglue, so if we are subverting the mechglue we need
+     * to add it ourselves.
+     */
+    mechContext->length = 4 + gssCtx->mechanismUsed->length + exportedCtx.length;
+    mechContext->value = p = (unsigned char *)GSSEAP_MALLOC(mechContext->length);
+    if (mechContext->value == NULL) {
+        gss_release_buffer(minor, &exportedCtx);
+        throw new std::bad_alloc;
+    }
+
+    p = store_oid(gssCtx->mechanismUsed, p);
+    memcpy(p, exportedCtx.value, exportedCtx.length);
+
+    gss_release_buffer(minor, &exportedCtx);
+
+    return GSS_S_COMPLETE;
+}
+
 bool
 gss_eap_shib_attr_provider::initFromGssContext(const gss_eap_attr_ctx *manager,
                                                const gss_cred_id_t gssCred,
                                                const gss_ctx_id_t gssCtx)
 {
     const gss_eap_saml_assertion_provider *saml;
-    gss_buffer_desc exportedCtx = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc mechContext = GSS_C_EMPTY_BUFFER;
     OM_uint32 major, minor;
 #if 0
     gss_buffer_desc nameBuf = GSS_C_EMPTY_BUFFER;
@@ -139,10 +175,10 @@ gss_eap_shib_attr_provider::initFromGssContext(const gss_eap_attr_ctx *manager,
     }
 #endif
 
-    major = gssEapExportSecContext(&minor, gssCtx, &exportedCtx);
+    major = exportMechSecContext(&minor, gssCtx, &mechContext);
     if (major == GSS_S_COMPLETE) {
-        resolver->addToken(&exportedCtx);
-        gss_release_buffer(&minor, &exportedCtx);
+        resolver->addToken(&mechContext);
+        gss_release_buffer(&minor, &mechContext);
     }
 
     if (saml != NULL && saml->getAssertion() != NULL) {
@@ -371,16 +407,20 @@ gss_eap_shib_attr_provider::jsonRepresentation(void) const
     if (m_initialized == false)
         return obj; /* don't export incomplete context */
 
-    JSONObject attrs = JSONObject::array();
+    JSONObject jattrs = JSONObject::array();
 
     for (vector<Attribute*>::const_iterator a = m_attributes.begin();
          a != m_attributes.end(); ++a) {
-        DDF attr = (*a)->marshall();
-        JSONObject jobj(attr);
-        attrs.append(jobj);
+        try {
+            DDF attr = (*a)->marshall();
+            JSONObject jattr = JSONObject::ddf(attr);
+            jattrs.append(jattr);
+        } catch (AttributeException &e) {
+            /* XXX FIXME ignore attribute exceptions? */
+        }
     }
 
-    obj.set("attributes", attrs);
+    obj.set("attributes", jattrs);
 
     obj.set("authenticated", m_authenticated);
 
@@ -397,13 +437,19 @@ gss_eap_shib_attr_provider::initWithJsonObject(const gss_eap_attr_ctx *ctx,
     assert(m_authenticated == false);
     assert(m_attributes.size() == 0);
 
-    JSONObject attrs = obj["attributes"];
-    size_t nelems = attrs.size();
+    JSONObject jattrs = obj["attributes"];
+    size_t nelems = jattrs.size();
 
     for (size_t i = 0; i < nelems; i++) {
-        DDF attr = attrs.get(i).ddf();
-        Attribute *attribute = Attribute::unmarshall(attr);
-        m_attributes.push_back(attribute);
+        JSONObject jattr = jattrs.get(i);
+
+        try {
+            DDF attr = jattr.ddf();
+            Attribute *attribute = Attribute::unmarshall(attr);
+            m_attributes.push_back(attribute);
+        } catch (AttributeException &e) {
+            return false;
+        }
     }
 
     m_authenticated = obj["authenticated"].integer();
index f06b674..6a4fc22 160000 (submodule)
@@ -1 +1 @@
-Subproject commit f06b67451a4af8ed2206094f0dba496e9a53f21d
+Subproject commit 6a4fc22608ecd1cfcded534a0a04982c11eeca33