return -1;
}
-int
+ssize_t
base64Encode(const void *data, int size, char **str)
{
char *s, *p;
}
*p = 0;
*str = s;
- return (int) strlen(s);
+ return strlen(s);
}
#define DECODE_ERROR 0xffffffff
return (marker << 24) | val;
}
-int
+ssize_t
base64Decode(const char *str, void *data)
{
const char *p;
}
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;
+}
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
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();
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;
}
}