From 1362e293dfa2caa348b55aed5861efdb483ef813 Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Sun, 3 Apr 2011 19:07:14 +1000 Subject: [PATCH] refactor unknown attribute syntax detection --- mech_eap/util_base64.c | 22 +++++++++++++++++++--- mech_eap/util_base64.h | 7 +++++-- mech_eap/util_radius.cpp | 31 ++++++++++--------------------- 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/mech_eap/util_base64.c b/mech_eap/util_base64.c index 8d13aaf..5d5241d 100644 --- a/mech_eap/util_base64.c +++ b/mech_eap/util_base64.c @@ -46,7 +46,7 @@ pos(char c) return -1; } -int +ssize_t base64Encode(const void *data, int size, char **str) { char *s, *p; @@ -88,7 +88,7 @@ base64Encode(const void *data, int size, char **str) } *p = 0; *str = s; - return (int) strlen(s); + return strlen(s); } #define DECODE_ERROR 0xffffffff @@ -115,7 +115,7 @@ token_decode(const char *token) return (marker << 24) | val; } -int +ssize_t base64Decode(const char *str, void *data) { const char *p; @@ -135,3 +135,19 @@ base64Decode(const char *str, void *data) } return q - (unsigned char *) data; } + +int +base64Valid(const char *str) +{ + const char *p; + int valid = 1; + + for (p = str; *p && (*p == '=' || strchr(base64_chars, *p)); p += 4) { + unsigned int val = token_decode(p); + if (val == DECODE_ERROR) { + valid = 0; + break; + } + } + return valid; +} diff --git a/mech_eap/util_base64.h b/mech_eap/util_base64.h index 84313e4..d015efe 100644 --- a/mech_eap/util_base64.h +++ b/mech_eap/util_base64.h @@ -40,12 +40,15 @@ extern "C" { #endif -int +ssize_t base64Encode(const void *, int, char **); -int +ssize_t base64Decode(const char *, void *); +int +base64Valid(const char *str); + #define BASE64_EXPAND(n) (n * 4 / 3 + 4) #ifdef __cplusplus diff --git a/mech_eap/util_radius.cpp b/mech_eap/util_radius.cpp index 5a109fe..5462acc 100644 --- a/mech_eap/util_radius.cpp +++ b/mech_eap/util_radius.cpp @@ -669,8 +669,9 @@ jsonToAvp(VALUE_PAIR **pVp, JSONObject &obj) if (da != NULL) { vp = pairalloc(da); } else { - /* Assume unknown attributes are octet strings */ - vp = paircreate(attrid, PW_TYPE_OCTETS); + int type = base64Valid(value.string()) ? + PW_TYPE_OCTETS : PW_TYPE_STRING; + vp = paircreate(attrid, type); } if (vp == NULL) throw std::bad_alloc(); @@ -705,29 +706,17 @@ jsonToAvp(VALUE_PAIR **pVp, JSONObject &obj) goto fail; const char *str = value.string(); - size_t stringLen = strlen(str); + ssize_t len = strlen(str); /* this optimization requires base64Decode only understand packed encoding */ - if (stringLen >= BASE64_EXPAND(MAX_STRING_LEN)) + if (len >= BASE64_EXPAND(MAX_STRING_LEN)) goto fail; - /* - * If the attribute is unknown, we don't know its syntax; assume - * it is an octet string and, if that fails to decode and will - * fit, a string. - */ - size_t valueLen = base64Decode(str, vp->vp_octets); - if (valueLen < 0) { - if (da == NULL && stringLen < MAX_STRING_LEN) { - vp->type = PW_TYPE_STRING; - vp->length = stringLen; - memcpy(vp->vp_strvalue, str, stringLen + 1); - } else - goto fail; - } else { - vp->length = valueLen; - vp->vp_octets[valueLen] = '\0'; - } + len = base64Decode(str, vp->vp_octets); + if (len < 0) + goto fail; + + vp->length = len; break; } } -- 2.1.4