From: Luke Howard Date: Mon, 28 Mar 2011 06:07:43 +0000 (+1100) Subject: add JSON utility class X-Git-Tag: 0.9.2~270 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=mech_eap.git;a=commitdiff_plain;h=f12a2be8e6409006eaf326c204ea5c99b78b3b2b add JSON utility class --- diff --git a/Makefile.am b/Makefile.am index d2c8583..163b9e0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -76,6 +76,7 @@ mech_eap_la_SOURCES = \ util_cksum.c \ util_cred.c \ util_crypt.c \ + util_json.cpp \ util_krb.c \ util_lucid.c \ util_mech.c \ diff --git a/util.h b/util.h index 31c89f2..5687d52 100644 --- a/util.h +++ b/util.h @@ -845,6 +845,7 @@ gssBufferToKrbData(gss_buffer_t buffer, krb5_data *data) } #endif +#include "util_json.h" #include "util_attr.h" #include "util_base64.h" #ifdef GSSEAP_ENABLE_REAUTH diff --git a/util_attr.cpp b/util_attr.cpp index 28e6356..d9c4614 100644 --- a/util_attr.cpp +++ b/util_attr.cpp @@ -276,28 +276,26 @@ gss_eap_attr_ctx::initFromGssContext(const gss_cred_id_t cred, } bool -gss_eap_attr_ctx::initWithJsonObject(json_t *obj) +gss_eap_attr_ctx::initWithJsonObject(JSONObject &obj) { bool ret = false; bool foundSource[ATTR_TYPE_MAX + 1]; unsigned int type; - json_t *sources; for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) foundSource[type] = false; - if (json_integer_value(json_object_get(obj, "version")) != 1) + if (obj["version"].integer() != 1) return false; - m_flags = json_integer_value(json_object_get(obj, "flags")); + m_flags = obj["flags"].integer(); - sources = json_object_get(obj, "sources"); + JSONObject sources = obj["sources"]; /* Initialize providers from serialized state */ for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) { gss_eap_attr_provider *provider; const char *key; - json_t *source; if (!providerEnabled(type)) { releaseProvider(type); @@ -309,8 +307,8 @@ gss_eap_attr_ctx::initWithJsonObject(json_t *obj) if (key == NULL) continue; - source = json_object_get(sources, key); - if (source != NULL && + JSONObject source = sources.get(key); + if (!source.isnull() && !provider->initWithJsonObject(this, source)) { releaseProvider(type); return false; @@ -340,26 +338,14 @@ gss_eap_attr_ctx::initWithJsonObject(json_t *obj) return true; } -json_t * +JSONObject gss_eap_attr_ctx::jsonRepresentation(void) const { - json_t *obj, *sources; + JSONObject obj, sources; unsigned int i; - obj = json_object(); - if (obj == NULL) { - throw new std::bad_alloc; - } - - /* FIXME check json_object_set_new return value */ - json_object_set_new(obj, "version", json_integer(1)); - json_object_set_new(obj, "flags", json_integer(m_flags)); - - sources = json_object(); - if (sources == NULL) { - json_decref(obj); - throw new std::bad_alloc; - } + obj.set("version", 1); + obj.set("flags", m_flags); for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) { gss_eap_attr_provider *provider; @@ -373,11 +359,11 @@ gss_eap_attr_ctx::jsonRepresentation(void) const if (key == NULL) continue; /* provider does not have state */ - json_t *source = provider->jsonRepresentation(); - json_object_set_new(sources, key, source); + JSONObject source = provider->jsonRepresentation(); + sources.set(key, source); } - json_object_set_new(obj, "sources", sources); + obj.set("sources", sources); return obj; } @@ -392,16 +378,14 @@ gss_eap_attr_ctx::initFromBuffer(const gss_buffer_t buffer) bool ret; char *s; json_error_t error; - json_t *obj; major = bufferToString(&minor, buffer, &s); if (GSS_ERROR(major)) return false; - obj = json_loads(s, 0, &error); - if (obj != NULL) { + JSONObject obj = JSONObject::load(s, 0, &error); + if (!obj.isnull()) { ret = initWithJsonObject(obj); - json_decref(obj); } else ret = false; @@ -641,32 +625,16 @@ void gss_eap_attr_ctx::exportToBuffer(gss_buffer_t buffer) const { OM_uint32 minor; - json_t *obj; char *s; - obj = jsonRepresentation(); - if (obj == NULL) { - std::string error("gss_eap_attr_ctx::exportToBuffer::jsonRepresentation"); - throw new std::runtime_error(error); /* XXX */ - } + JSONObject obj = jsonRepresentation(); -#if 0 - json_dumpf(obj, stdout, JSON_INDENT(3)); -#endif + obj.dump(stdout, JSON_INDENT(3)); - s = json_dumps(obj, JSON_COMPACT); - if (s == NULL) { - json_decref(obj); - std::string error("gss_eap_attr_ctx::exportToBuffer: json_dumps"); - throw new std::runtime_error(error); /* XXX */ - } + s = obj.dump(JSON_COMPACT); - if (GSS_ERROR(makeStringBuffer(&minor, s, buffer))) { - json_decref(obj); + if (GSS_ERROR(makeStringBuffer(&minor, s, buffer))) throw new std::bad_alloc; - } - - json_decref(obj); } /* diff --git a/util_attr.h b/util_attr.h index 1a427f7..05da947 100644 --- a/util_attr.h +++ b/util_attr.h @@ -41,7 +41,7 @@ #include #include -#include +using namespace gss_eap; struct gss_eap_attr_provider; struct gss_eap_attr_ctx; @@ -142,15 +142,15 @@ public: } virtual bool initWithJsonObject(const gss_eap_attr_ctx *manager, - json_t *object GSSEAP_UNUSED) + JSONObject &object GSSEAP_UNUSED) { return initWithManager(manager); } - virtual json_t *jsonRepresentation(void) const + virtual JSONObject jsonRepresentation(void) const { - return NULL; + return JSONObject::null(); } virtual time_t getExpiryTime(void) const { return 0; } @@ -254,8 +254,8 @@ private: unsigned int attributePrefixToType(const gss_buffer_t prefix) const; gss_buffer_desc attributeTypeToPrefix(unsigned int type) const; - bool initWithJsonObject(json_t *object); - json_t *jsonRepresentation(void) const; + bool initWithJsonObject(JSONObject &object); + JSONObject jsonRepresentation(void) const; gss_eap_attr_provider *getPrimaryProvider(void) const; diff --git a/util_json.cpp b/util_json.cpp new file mode 100644 index 0000000..9b4b9d1 --- /dev/null +++ b/util_json.cpp @@ -0,0 +1,443 @@ +/* + * Copyright (c) 2011, 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. + */ + +/* + * JSONObject utilities. + */ + +#include "gssapiP_eap.h" + +#include +#include +#include +#include +#include +#include + +#define JSON_INIT(obj) do { \ + if ((obj) == NULL) \ + throw new std::bad_alloc; \ + m_obj = (obj); \ + } while (0) + +#define JSON_CHECK_CONTAINER() do { \ + if (!json_is_object(m_obj) && !json_is_array(m_obj)) { \ + std::string s("JSONObject object is not a container"); \ + throw new std::runtime_error(s); \ + } \ + } while (0) +#define JSON_CHECK_OBJECT() do { \ + if (!json_is_object(m_obj)) { \ + std::string s("JSONObject object is not a dictionary"); \ + throw new std::runtime_error(s); \ + } \ + } while (0) + +#define JSON_CHECK_ARRAY() do { \ + if (!json_is_array(m_obj)) { \ + std::string s("JSONObject object is not an array"); \ + throw new std::runtime_error(s); \ + } \ + } while (0) + +#define JSON_CHECK(s) do { \ + if ((s) != 0) \ + throw new std::bad_alloc; \ + } while (0) + +JSONObject +JSONObject::load(const char *input, size_t flags, json_error_t *error) +{ + json_t *obj; + + obj = json_loads(input, flags, error); + + return JSONObject(obj, false); +} + +JSONObject +JSONObject::load(FILE *fp, size_t flags, json_error_t *error) +{ + json_t *obj; + + obj = json_loadf(fp, flags, error); + + return JSONObject(obj, false); +} + +char * +JSONObject::dump(size_t flags) const +{ + char *s = json_dumps(m_obj, flags); + + if (s == NULL) + throw new std::bad_alloc; + + return s; +} + +void +JSONObject::dump(FILE *fp, size_t flags) const +{ + int r = json_dumpf(m_obj, fp, flags); + + if (r != 0) + throw new std::bad_alloc; +} + +size_t +JSONObject::size(void) const +{ + if (json_is_object(m_obj)) + return json_object_size(m_obj); + else if (json_is_array(m_obj)) + return json_array_size(m_obj); + else + return 0; +} + +JSONObject::JSONObject(json_t *obj, bool retain) +{ + if (retain) + json_incref(obj); + JSON_INIT(obj); +} + +JSONObject::JSONObject(const char *value) +{ + json_t *obj = json_string(value); + + JSON_INIT(obj); +} + +JSONObject::JSONObject(json_int_t value) +{ + json_t *obj = json_integer(value); + + JSON_INIT(obj); +} + +JSONObject::JSONObject(double value) +{ + json_t *obj = json_real(value); + + JSON_INIT(obj); +} + +JSONObject::JSONObject(bool value) +{ + json_t *obj = value ? json_true() : json_false(); + + JSON_INIT(obj); +} + +JSONObject::JSONObject(void) +{ + json_t *obj = json_object(); + + JSON_INIT(obj); +} + +JSONObject +JSONObject::object(void) +{ + return JSONObject(); +} + +JSONObject +JSONObject::null(void) +{ + return JSONObject(json_null(), false); +} + +JSONObject +JSONObject::array(void) +{ + return JSONObject(json_array(), false); +} + +void +JSONObject::set(const char *key, JSONObject &value) +{ + JSON_CHECK_OBJECT(); + JSON_CHECK(json_object_set_new(m_obj, key, value.get())); +} + +void +JSONObject::set(const char *key, const char *value) +{ + JSONObject jobj(value); + set(key, jobj); +} + +void +JSONObject::set(const char *key, json_int_t value) +{ + JSONObject jobj(value); + set(key, jobj); +} + +void +JSONObject::del(const char *key) +{ + json_object_del(m_obj, key); +} + +JSONObject +JSONObject::get(const char *key) const +{ + json_t *obj; + + obj = json_object_get(m_obj, key); + if (obj == NULL) + return JSONObject::null(); + + return JSONObject(obj, true); +} + +JSONObject +JSONObject::get(size_t index) const +{ + json_t *obj; + + obj = json_array_get(m_obj, index); + if (obj == NULL) + return JSONObject::null(); + + return JSONObject(obj, true); +} + +void +JSONObject::update(JSONObject &value) +{ + JSON_CHECK_OBJECT(); + json_t *other = value.get(); + JSON_CHECK(json_object_update(m_obj, other)); + json_decref(other); +} + +JSONObject +JSONObject::operator[](size_t index) const +{ + return get(index); +} + +JSONObject +JSONObject::operator[](const char *key) const +{ + return get(key); +} + +void +JSONObject::append(JSONObject &value) +{ + JSON_CHECK_ARRAY(); + JSON_CHECK(json_array_append_new(m_obj, value.get())); +} + +void +JSONObject::insert(size_t index, JSONObject &value) +{ + JSON_CHECK_ARRAY(); + JSON_CHECK(json_array_insert_new(m_obj, index, value.get())); +} + +void +JSONObject::remove(size_t index) +{ + JSON_CHECK_ARRAY(); + JSON_CHECK(json_array_remove(m_obj, index)); +} + +void +JSONObject::clear(void) +{ + JSON_CHECK_CONTAINER(); + + if (json_is_object(m_obj)) { + JSON_CHECK(json_object_clear(m_obj)); + } else if (json_is_array(m_obj)) { + JSON_CHECK(json_array_clear(m_obj)); + } +} + +void +JSONObject::extend(JSONObject &value) +{ + JSON_CHECK_ARRAY(); + json_t *other = value.get(); + JSON_CHECK(json_array_extend(m_obj, other)); + json_decref(other); +} + +const char * +JSONObject::string(void) const +{ + return json_string_value(m_obj); +} + +json_int_t +JSONObject::integer(void) const +{ + return json_integer_value(m_obj); +} + +double +JSONObject::real(void) const +{ + return json_real_value(m_obj); +} + +double +JSONObject::number(void) const +{ + return json_number_value(m_obj); +} + +bool +JSONObject::isnull(void) const +{ + return json_is_null(m_obj); +} + +JSONObject::JSONObject(DDF &ddf) +{ + if (ddf.isstruct()) { + DDF elem = ddf.first(); + JSONObject jobj = JSONObject::array(); + + while (!elem.isnull()) { + JSONObject jtmp(elem); + jobj.append(jtmp); + elem = ddf.next(); + } + } else if (ddf.islist()) { + DDF elem = ddf.first(); + JSONObject jobj = JSONObject::object(); + + while (!elem.isnull()) { + JSONObject jtmp(elem); + jobj.set(elem.name(), jtmp); + elem = ddf.next(); + } + } else if (ddf.isstring()) { + JSONObject(ddf.string()); + } else if (ddf.isint()) { + JSONObject((json_int_t)ddf.integer()); + } else if (ddf.isfloat()) { + JSONObject(ddf.floating()); + } else if (ddf.isempty() || ddf.ispointer()) { + JSONObject::object(); + } else if (ddf.isnull()) { + JSONObject::null(); + } + + std::string s("Unbridgeable DDF object"); + throw new std::runtime_error(s); +} + +DDF +JSONObject::ddf(void) const +{ + DDF ddf(NULL); + + switch (type()) { + case JSON_OBJECT: { + JSONIterator iter = iterator(); + + do { + const char *key = iter.key(); + DDF value = iter.value().ddf(); + ddf.add(value.name(key)); + } while (iter.next()); + break; + } + case JSON_ARRAY: { + size_t i, nelems = size(); + + for (i = 0; i < nelems; i++) { + DDF value = get(i).ddf(); + ddf.add(value); + } + break; + } + case JSON_STRING: + ddf.string(string()); + break; + case JSON_INTEGER: + ddf.integer(integer()); + break; + case JSON_REAL: + ddf.floating(real()); + break; + case JSON_TRUE: + ddf.integer(1L); + break; + case JSON_FALSE: + ddf.integer(0L); + break; + case JSON_NULL: + break; + } + + return DDF(NULL); +} + +JSONIterator::JSONIterator(const JSONObject &obj) +{ + m_obj = obj.get(); + m_iter = json_object_iter(m_obj); +} + +JSONIterator::~JSONIterator(void) +{ + json_decref(m_obj); +} + +const char * +JSONIterator::key(void) const +{ + return json_object_iter_key(m_iter); +} + +JSONObject +JSONIterator::value(void) const +{ + return JSONObject(json_object_iter_value(m_iter)); +} + +bool +JSONIterator::next(void) +{ + m_iter = json_object_iter_next(m_obj, m_iter); + return m_iter != NULL; +} diff --git a/util_json.h b/util_json.h new file mode 100644 index 0000000..639e7b0 --- /dev/null +++ b/util_json.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2011, 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. + */ + +/* + * JSON object wrapper with toll-free DDF bridging. + */ + +#ifndef _UTIL_JSON_H_ +#define _UTIL_JSON_H_ 1 + +#ifdef __cplusplus +#include +#include + +#include +#include + +using namespace shibsp; + +namespace gss_eap { + class JSONObject; + + class JSONIterator { + public: + JSONIterator(const JSONObject &obj); + ~JSONIterator(void); + const char *key(void) const; + JSONObject value(void) const; + bool next(void); + + private: + json_t *m_obj; + void *m_iter; + }; + + class JSONObject { + public: + static JSONObject load(const char *input, size_t flags, json_error_t *error); + static JSONObject load(FILE *, size_t flags, json_error_t *error); + + static JSONObject object(void); + static JSONObject array(void); + static JSONObject null(void); + + char *dump(size_t flags = 0) const; + void dump(FILE *fp, size_t flags = 0) 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); + JSONObject(bool value); + + void set(const char *key, JSONObject &value); + void set(const char *key, const char *value); + void set(const char *key, json_int_t value); + void del(const char *key); + void update(JSONObject &value); + JSONIterator iterator(void) const { return JSONIterator(*this); } + JSONObject get(const char *key) const; + JSONObject operator[](const char *key) const; + + JSONObject get(size_t index) const; + JSONObject operator[](size_t index) const; + void append(JSONObject &value); + void insert(size_t index, JSONObject &value); + void remove(size_t index); + void clear(void); + void extend(JSONObject &value); + + const char *string(void) const; + json_int_t integer(void) const; + double real(void) const; + double number(void) const; + bool isnull(void) const; + DDF ddf(void) const; + + ~JSONObject(void) + { + if (m_obj != NULL) + json_decref(m_obj); + } + + JSONObject(const JSONObject &obj) + { + m_obj = json_incref(obj.m_obj); + } + + JSONObject& operator=(const JSONObject &obj) + { + if (this != &obj) + set(obj.m_obj); + return *this; + } + + private: + friend class JSONIterator; + + json_t *get(void) const { + return m_obj ? json_incref(m_obj) : json_null(); + } + + void set(json_t *obj) { + if (m_obj != obj) { + json_decref(m_obj); + m_obj = json_incref(m_obj); + } + } + + JSONObject(json_t *obj, bool retain); + + json_t *m_obj; + }; + +} + +#endif /* __cplusplus */ + +#endif /* _UTIL_JSON_H_ */ diff --git a/util_radius.cpp b/util_radius.cpp index 4e2f6e0..fe43135 100644 --- a/util_radius.cpp +++ b/util_radius.cpp @@ -619,18 +619,10 @@ gssEapRadiusAttrProviderFinalize(OM_uint32 *minor) return GSS_S_COMPLETE; } -static json_t * +static JSONObject avpToJson(const VALUE_PAIR *vp) { - json_t *obj = json_object(); - - if (obj == NULL) { - throw new std::bad_alloc; - return NULL; - } - - /* FIXME check json_object_set_new return value */ - json_object_set_new(obj, "type", json_integer(vp->attribute)); + JSONObject obj; assert(vp->length <= MAX_STRING_LEN); @@ -638,42 +630,41 @@ avpToJson(const VALUE_PAIR *vp) case PW_TYPE_INTEGER: case PW_TYPE_IPADDR: case PW_TYPE_DATE: - json_object_set_new(obj, "value", json_integer(vp->lvalue)); + obj.set("value", vp->lvalue); break; case PW_TYPE_STRING: - json_object_set_new(obj, "value", json_string(vp->vp_strvalue)); + obj.set("value", vp->vp_strvalue); break; default: { char *b64; - if (base64Encode(vp->vp_octets, vp->length, &b64) < 0) { - json_decref(obj); + if (base64Encode(vp->vp_octets, vp->length, &b64) < 0) throw new std::bad_alloc; - } - json_object_set_new(obj, "value", json_string(b64)); + obj.set("value", b64); GSSEAP_FREE(b64); break; } } + obj.set("type", vp->attribute); + return obj; } static bool -jsonToAvp(VALUE_PAIR **pVp, json_t *obj) +jsonToAvp(VALUE_PAIR **pVp, JSONObject &obj) { VALUE_PAIR *vp = NULL; DICT_ATTR *da; uint32_t attrid; - json_t *type, *value; - type = json_object_get(obj, "type"); - value = json_object_get(obj, "value"); - if (type == NULL || value == NULL) + JSONObject type = obj["type"]; + JSONObject value = obj["value"]; + if (type.isnull() || value.isnull()) goto fail; - attrid = json_integer_value(type); + attrid = type.integer(); da = dict_attrbyvalue(attrid); if (da != NULL) { vp = pairalloc(da); @@ -690,10 +681,10 @@ jsonToAvp(VALUE_PAIR **pVp, json_t *obj) case PW_TYPE_IPADDR: case PW_TYPE_DATE: vp->length = 4; - vp->lvalue = json_integer_value(value); + vp->lvalue = value.integer(); break; case PW_TYPE_STRING: { - const char *str = json_string_value(value); + const char *str = value.string(); size_t len; if (str == NULL || (len = strlen(str)) >= MAX_STRING_LEN) @@ -705,7 +696,7 @@ jsonToAvp(VALUE_PAIR **pVp, json_t *obj) } case PW_TYPE_OCTETS: default: { - const char *str = json_string_value(value); + const char *str = value.string(); int len; /* this optimization requires base64Decode only understand packed encoding */ @@ -742,19 +733,18 @@ gss_eap_radius_attr_provider::name(void) const bool gss_eap_radius_attr_provider::initWithJsonObject(const gss_eap_attr_ctx *ctx, - json_t *obj) + JSONObject &obj) { VALUE_PAIR **pNext = &m_vps; - json_t *attrs; - size_t i; if (!gss_eap_attr_provider::initWithJsonObject(ctx, obj)) return false; - attrs = json_object_get(obj, "attributes"); + JSONObject attrs = obj["attributes"]; + size_t nelems = attrs.size(); - for (i = 0; i < json_array_size(attrs); i++) { - json_t *attr = json_array_get(attrs, i); + for (size_t i = 0; i < nelems; i++) { + JSONObject attr = attrs[i]; VALUE_PAIR *vp; if (!jsonToAvp(&vp, attr)) @@ -773,27 +763,17 @@ gss_eap_radius_attr_provider::prefix(void) const return "urn:ietf:params:gss-eap:radius-avp"; } -json_t * +JSONObject gss_eap_radius_attr_provider::jsonRepresentation(void) const { - json_t *obj, *attrs; - - attrs = json_array(); - if (attrs == NULL) - throw new std::bad_alloc; + JSONObject obj, attrs = JSONObject::array(); for (VALUE_PAIR *vp = m_vps; vp != NULL; vp = vp->next) { - json_t *attr = avpToJson(vp); - json_array_append_new(attrs, attr); - } - - obj = json_object(); - if (obj == NULL) { - json_decref(attrs); - throw new std::bad_alloc; + JSONObject attr = avpToJson(vp); + attrs.append(attr); } - json_object_set_new(obj, "attributes", attrs); + obj.set("attributes", attrs); return obj; } diff --git a/util_radius.h b/util_radius.h index 656f1b7..a7878df 100644 --- a/util_radius.h +++ b/util_radius.h @@ -69,8 +69,8 @@ public: const char *prefix(void) const; const char *name(void) const; bool initWithJsonObject(const gss_eap_attr_ctx *manager, - json_t *obj); - json_t *jsonRepresentation(void) const; + JSONObject &obj); + JSONObject jsonRepresentation(void) const; bool getAttribute(uint32_t attribute, int *authenticated, diff --git a/util_saml.h b/util_saml.h index 0a14d3e..eeb17e3 100644 --- a/util_saml.h +++ b/util_saml.h @@ -77,11 +77,11 @@ public: const char *prefix(void) const; const char *name(void) const { return NULL; } bool initWithJsonObject(const gss_eap_attr_ctx *manager GSSEAP_UNUSED, - json_t *object GSSEAP_UNUSED) { + JSONObject &object GSSEAP_UNUSED) { return false; } - json_t *jsonRepresentation(void) const { - return NULL; + JSONObject jsonRepresentation(void) const { + return JSONObject::null(); } opensaml::saml2::Assertion *initAssertion(void); @@ -140,11 +140,11 @@ public: return NULL; } bool initWithJsonObject(const gss_eap_attr_ctx *manager GSSEAP_UNUSED, - json_t *object GSSEAP_UNUSED) { + JSONObject &object GSSEAP_UNUSED) { return false; } - json_t *jsonRepresentation(void) const { - return NULL; + JSONObject jsonRepresentation(void) const { + return JSONObject::null(); } bool getAttribute(const gss_buffer_t attr, diff --git a/util_shib.cpp b/util_shib.cpp index 14757d1..27b03e2 100644 --- a/util_shib.cpp +++ b/util_shib.cpp @@ -396,156 +396,44 @@ gss_eap_shib_attr_provider::name(void) const return "local"; } -static json_t * -ddfToJson(DDF &ddf) -{ - json_t *json; - - if (ddf.isstruct()) { - DDF elem = ddf.first(); - json = json_array(); - if (json == NULL) - throw new std::bad_alloc; - - while (!elem.isnull()) { - if (json_array_append_new(json, ddfToJson(elem)) != 0) { - json_decref(json); - throw new std::bad_alloc; - } - - elem = ddf.next(); - } - } else if (ddf.islist()) { - DDF elem = ddf.first(); - json = json_object(); - if (json == NULL) - throw new std::bad_alloc; - - while (!elem.isnull()) { - if (json_object_set(json, elem.name(), ddfToJson(elem)) != 0) { - json_decref(json); - throw new std::bad_alloc; - } - - elem = ddf.next(); - } - } else if (ddf.isstring()) { - json = json_string(ddf.string()); - } else if (ddf.isint()) { - json = json_integer(ddf.integer()); - } else if (ddf.isfloat()) { - json = json_real(ddf.floating()); - } else if (ddf.isempty() || ddf.ispointer()) { - json = json_object(); - } else if (ddf.isnull()) { - json = json_null(); - } else { - assert(0 && "Invalid DDF object"); - } - - if (json == NULL) - throw new std::bad_alloc; - - return json; -} - -static DDF -jsonToDdf(json_t *json) -{ - DDF ddf(NULL); - - switch (json_typeof(json)) { - case JSON_OBJECT: { - void *iter = json_object_iter(json); - - while (iter != NULL) { - const char *key = json_object_iter_key(iter); - json_t *value = json_object_iter_value(iter); - ddf.add(jsonToDdf(value).name(key)); - iter = json_object_iter_next(json, iter); - } - break; - } - case JSON_ARRAY: { - size_t i; - - for (i = 0; i < json_array_size(json); i++) { - DDF value = jsonToDdf(json_array_get(json, i)); - ddf.add(value); - } - break; - } - case JSON_STRING: - ddf.string(json_string_value(json)); - break; - case JSON_INTEGER: - ddf.integer(json_integer_value(json)); - break; - case JSON_REAL: - ddf.floating(json_real_value(json)); - break; - case JSON_TRUE: - ddf.integer(1L); - break; - case JSON_FALSE: - ddf.integer(0L); - break; - case JSON_NULL: - break; - } - - return ddf; -} - -json_t * +JSONObject gss_eap_shib_attr_provider::jsonRepresentation(void) const { - json_t *obj, *attrs; + JSONObject obj; - obj = json_object(); - if (obj == NULL) - throw new std::bad_alloc; + obj.set("authenticated", m_authenticated); - /* FIXME check json_object_set_new return value */ - json_object_set_new(obj, "authenticated", json_integer(m_authenticated)); - - attrs = json_array(); - if (attrs == NULL) { - json_decref(obj); - throw new std::bad_alloc; - } + JSONObject attrs = JSONObject::array(); for (vector::const_iterator a = m_attributes.begin(); a != m_attributes.end(); ++a) { DDF attr = (*a)->marshall(); - /* FIXME check json_array_append_new return value */ - json_array_append_new(attrs, ddfToJson(attr)); + JSONObject jobj(attr); + attrs.append(jobj); } - json_object_set_new(obj, "attributes", attrs); + obj.set("attributes", attrs); return obj; } bool gss_eap_shib_attr_provider::initWithJsonObject(const gss_eap_attr_ctx *ctx, - json_t *obj) + JSONObject &obj) { - size_t i; - json_t *attrs; - if (!gss_eap_attr_provider::initWithJsonObject(ctx, obj)) return false; assert(m_authenticated == false); assert(m_attributes.size() == 0); - m_authenticated = json_integer_value(json_object_get(obj, "authenticated")); + m_authenticated = obj["authenticated"].integer(); - attrs = json_object_get(obj, "attributes"); + JSONObject attrs = obj["attributes"]; + size_t nelems = attrs.size(); - for (i = 0; i < json_array_size(attrs); i++) { - DDF attr = jsonToDdf(json_array_get(attrs, i)); + for (size_t i = 0; i < nelems; i++) { + DDF attr = attrs.get(i).ddf(); Attribute *attribute = Attribute::unmarshall(attr); m_attributes.push_back(attribute); } diff --git a/util_shib.h b/util_shib.h index 7cacd66..7fc9e6d 100644 --- a/util_shib.h +++ b/util_shib.h @@ -79,8 +79,8 @@ public: const char *prefix(void) const; const char *name(void) const; bool initWithJsonObject(const gss_eap_attr_ctx *manager, - json_t *obj); - json_t *jsonRepresentation(void) const; + JSONObject &obj); + JSONObject jsonRepresentation(void) const; static bool init(void); static void finalize(void);