Enable tls psk
[libradsec.git] / radius / parse.c
1 /*
2 Copyright (c) 2011, Network RADIUS SARL
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7     * Redistributions of source code must retain the above copyright
8       notice, this list of conditions and the following disclaimer.
9     * Redistributions in binary form must reproduce the above copyright
10       notice, this list of conditions and the following disclaimer in the
11       documentation and/or other materials provided with the distribution.
12     * Neither the name of the <organization> nor the
13       names of its contributors may be used to endorse or promote products
14       derived from this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 /** \file parse.c
29  *  \brief Routines to parse strings into internal data structures
30  */
31
32 #include "client.h"
33
34 #ifdef HAVE_ARPA_INET_H
35 #include <arpa/inet.h>
36 #endif
37
38 ssize_t nr_vp_sscanf_value(VALUE_PAIR *vp, const char *value)
39 {
40         char *end;
41
42         switch (vp->da->type) {
43         case RS_TYPE_STRING: {
44                 size_t len = strlen(value);
45
46                 if (len >= RS_MAX_STRING_LEN)
47                         return -RSE_ATTR_TOO_LARGE;
48
49                 memcpy(vp->vp_strvalue, value, len + 1);
50                 return (vp->length = len);
51         }
52         case RS_TYPE_DATE:
53         case RS_TYPE_INTEGER:
54                 vp->vp_integer = strtoul(value, &end, 10);
55                 if ((value == end) || (*end != '\0')) {
56                         nr_debug_error("Invalid value");
57                         return -RSE_ATTR_VALUE_MALFORMED;
58                 }
59                 return (end - value);
60
61         case RS_TYPE_IPADDR:
62                 if (inet_pton(AF_INET, value, &vp->vp_ipaddr) < 0) {
63                         return -RSE_NOSYS;
64                 }
65                 return strlen(value);
66                 
67 #ifdef RS_TYPE_IPV6ADDR
68         case RS_TYPE_IPV6ADDR:
69                 if (inet_pton(AF_INET6, value, &vp-vp>ipv6addr) < 0) {
70                         return -RSE_NOSYS;
71                 }
72                 return strlen(value);
73 #endif
74
75 #ifdef RS_TYPE_IFID
76         case RS_TYPE_IFID:
77         {
78                 int i, array[8];
79
80                 if (sscanf(value, "%02x%02x%02x%02x%02x%02x%02x%02x",
81                            &array[0], &array[1], &array[2], &array[3],
82                            &array[4], &array[5], &array[6], &array[7]) != 8) {
83                         return -RSE_SYSTEM;
84                 }
85
86                 for (i = 0; i < 8; i++) vp->vp_ifid[i] = array[i] & 0xff;
87
88         }
89                 break;
90 #endif
91
92         default:
93                 nr_debug_error("Invalid type");
94                 return -RSE_ATTR_TYPE_UNKNOWN;
95         }
96
97         return 0;
98 }
99
100 int nr_vp_sscanf(const char *string, VALUE_PAIR **pvp)
101 {
102         int rcode;
103         const char *p;
104         char *q;
105         const DICT_ATTR *da;
106         VALUE_PAIR *vp;
107         char buffer[256];
108
109         if (!string || !pvp) return -RSE_INVAL;
110
111         p = string;
112         q = buffer;
113         while (*p && (*p != ' ') && (*p != '=')) {
114                 *(q++) = *(p++);
115         }
116         *q = '\0';
117
118         if (q == buffer) {
119                 nr_debug_error("No Attribute name");
120                 return -RSE_ATTR_BAD_NAME;
121         }
122
123         da = nr_dict_attr_byname(buffer);
124         if (!da) {
125                 nr_debug_error("Unknown attribute \"%s\"", buffer);
126                 return -RSE_ATTR_UNKNOWN;
127         }
128
129         while (*p == ' ') p++;
130         if (*p != '=') {
131                 nr_debug_error("Unexpected text after attribute name");
132                 return -RSE_ATTR_BAD_NAME;
133         }
134
135         p++;
136         while (*p == ' ') p++;
137
138         vp = nr_vp_alloc(da);
139         if (!vp) return -RSE_NOMEM;
140
141         rcode = nr_vp_sscanf_value(vp, p);
142         if (rcode < 0) {
143                 nr_vp_free(&vp);
144                 return rcode;
145         }
146
147         *pvp = vp;
148         return 0;
149 }