summaryrefslogtreecommitdiff
path: root/lib/radius/parse.c
diff options
context:
space:
mode:
authorLinus Nordberg <linus@nordberg.se>2013-01-21 11:02:17 +0100
committerLinus Nordberg <linus@nordberg.se>2013-01-21 11:02:17 +0100
commit35311406413e0418112f7c295fee054a3506cbe8 (patch)
treef463a573a83951fb229a358425e08d9c7484268b /lib/radius/parse.c
parentdc61b6b2c2dd3d7b47d83dc6d574bd65dffeadd6 (diff)
parentb8260ee68d9bc60f3204f860cc6919964a6e9464 (diff)
Merge branch 'libradsec-new-client' into libradsec
Diffstat (limited to 'lib/radius/parse.c')
-rw-r--r--lib/radius/parse.c149
1 files changed, 149 insertions, 0 deletions
diff --git a/lib/radius/parse.c b/lib/radius/parse.c
new file mode 100644
index 0000000..8446306
--- /dev/null
+++ b/lib/radius/parse.c
@@ -0,0 +1,149 @@
+/*
+Copyright (c) 2011, Network RADIUS SARL
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * 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.
+ * Neither the name of the <organization> 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 <COPYRIGHT HOLDER> 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.
+ */
+
+/** \file parse.c
+ * \brief Routines to parse strings into internal data structures
+ */
+
+#include "client.h"
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+ssize_t nr_vp_sscanf_value(VALUE_PAIR *vp, const char *value)
+{
+ char *end;
+
+ switch (vp->da->type) {
+ case RS_TYPE_STRING: {
+ size_t len = strlen(value);
+
+ if (len >= RS_MAX_STRING_LEN)
+ return -RSE_ATTR_TOO_LARGE;
+
+ memcpy(vp->vp_strvalue, value, len + 1);
+ return (vp->length = len);
+ }
+ case RS_TYPE_DATE:
+ case RS_TYPE_INTEGER:
+ vp->vp_integer = strtoul(value, &end, 10);
+ if ((value == end) || (*end != '\0')) {
+ nr_debug_error("Invalid value");
+ return -RSE_ATTR_VALUE_MALFORMED;
+ }
+ return (end - value);
+
+ case RS_TYPE_IPADDR:
+ if (inet_pton(AF_INET, value, &vp->vp_ipaddr) < 0) {
+ return -RSE_NOSYS;
+ }
+ return strlen(value);
+
+#ifdef RS_TYPE_IPV6ADDR
+ case RS_TYPE_IPV6ADDR:
+ if (inet_pton(AF_INET6, value, &vp-vp>ipv6addr) < 0) {
+ return -RSE_NOSYS;
+ }
+ return strlen(value);
+#endif
+
+#ifdef RS_TYPE_IFID
+ case RS_TYPE_IFID:
+ {
+ int i, array[8];
+
+ if (sscanf(value, "%02x%02x%02x%02x%02x%02x%02x%02x",
+ &array[0], &array[1], &array[2], &array[3],
+ &array[4], &array[5], &array[6], &array[7]) != 8) {
+ return -RSE_SYSTEM;
+ }
+
+ for (i = 0; i < 8; i++) vp->vp_ifid[i] = array[i] & 0xff;
+
+ }
+ break;
+#endif
+
+ default:
+ nr_debug_error("Invalid type");
+ return -RSE_ATTR_TYPE_UNKNOWN;
+ }
+
+ return 0;
+}
+
+int nr_vp_sscanf(const char *string, VALUE_PAIR **pvp)
+{
+ int rcode;
+ const char *p;
+ char *q;
+ const DICT_ATTR *da;
+ VALUE_PAIR *vp;
+ char buffer[256];
+
+ if (!string || !pvp) return -RSE_INVAL;
+
+ p = string;
+ q = buffer;
+ while (*p && (*p != ' ') && (*p != '=')) {
+ *(q++) = *(p++);
+ }
+ *q = '\0';
+
+ if (q == buffer) {
+ nr_debug_error("No Attribute name");
+ return -RSE_ATTR_BAD_NAME;
+ }
+
+ da = nr_dict_attr_byname(buffer);
+ if (!da) {
+ nr_debug_error("Unknown attribute \"%s\"", buffer);
+ return -RSE_ATTR_UNKNOWN;
+ }
+
+ while (*p == ' ') p++;
+ if (*p != '=') {
+ nr_debug_error("Unexpected text after attribute name");
+ return -RSE_ATTR_BAD_NAME;
+ }
+
+ p++;
+ while (*p == ' ') p++;
+
+ vp = nr_vp_alloc(da);
+ if (!vp) return -RSE_NOMEM;
+
+ rcode = nr_vp_sscanf_value(vp, p);
+ if (rcode < 0) {
+ nr_vp_free(&vp);
+ return rcode;
+ }
+
+ *pvp = vp;
+ return 0;
+}