Fix typo, reorder methods in tr_aaa_server.c
[trust_router.git] / common / tr_aaa_server.c
1 /*
2  * Copyright (c) 2012-2018, JANET(UK)
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
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * 3. Neither the name of JANET(UK) nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31  * OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  */
34
35
36 #include <talloc.h>
37
38 #include <tr_name_internal.h>
39 #include <tr_aaa_server.h>
40 #include <trust_router/tid.h>
41
42 static int tr_aaa_server_destructor(void *obj)
43 {
44   TR_AAA_SERVER *aaa=talloc_get_type_abort(obj, TR_AAA_SERVER);
45   if (aaa->hostname!=NULL)
46     tr_free_name(aaa->hostname);
47   return 0;
48 }
49
50 TR_AAA_SERVER *tr_aaa_server_new(TALLOC_CTX *mem_ctx)
51 {
52   TR_AAA_SERVER *aaa=talloc(mem_ctx, TR_AAA_SERVER);
53   if (aaa!=NULL) {
54     aaa->next=NULL;
55     aaa->hostname = NULL;
56     tr_aaa_server_set_port(aaa, 0); /* go through setter to guarantee consistent default */
57     talloc_set_destructor((void *)aaa, tr_aaa_server_destructor);
58   }
59   return aaa;
60 }
61
62 void tr_aaa_server_free(TR_AAA_SERVER *aaa)
63 {
64   talloc_free(aaa);
65 }
66
67 TR_NAME *tr_aaa_server_get_hostname(TR_AAA_SERVER *aaa)
68 {
69   return aaa->hostname;
70 }
71
72 /**
73  * Set the hostname for a AAA server
74  *
75  * Takes ownership of the TR_NAME. Does nothing if aaa is null.
76  *
77  * @param aaa
78  * @param hostname
79  */
80 void tr_aaa_server_set_hostname(TR_AAA_SERVER *aaa, TR_NAME *hostname)
81 {
82   if (aaa == NULL)
83     return;
84
85   if (aaa->hostname != NULL) {
86     tr_free_name(aaa->hostname);
87   }
88
89   aaa->hostname = hostname;
90 }
91
92 int tr_aaa_server_get_port(TR_AAA_SERVER *aaa)
93 {
94   return aaa->port;
95 }
96
97 /**
98  * Set the port for a AAA server
99  *
100  * If port is 0, uses the standard TID port (12309). Other invalid values are stored
101  * as-is.
102  *
103  * Does nothing if aaa is null.
104  *
105  * @param aaa
106  * @param port
107  */
108 void tr_aaa_server_set_port(TR_AAA_SERVER *aaa, int port)
109 {
110   if (aaa == NULL)
111     return;
112
113   if (port == 0)
114     port = TID_PORT;
115
116   aaa->port = port;
117 }
118
119 /**
120  * Parse the port from a hostname:port string
121  *
122  * @param s string to parse
123  * @return the specified port, 0 if none specified, -1 if invalid
124  */
125 static int tr_aaa_server_parse_port(const char *s)
126 {
127   const char *s_port;
128   char *end_of_conversion;
129   long int port; /* long instead of int because we use strtol */
130
131   /* Find the first colon */
132   s_port = strchr(s, ':'); /* port starts at s_port + 1 */
133   if (s_port == NULL)
134     return 0; /* no port */
135
136   /* Check that the last colon is the same as the first */
137   if (strrchr(s, ':') != s_port)
138     return -1; /* multiple colons are invalid*/
139
140   s_port += 1; /* port now starts at s_port */
141
142   /* Parse the port number */
143   port = strtol(s, &end_of_conversion, /* base */ 10);
144
145   /* validate */
146   if ((end_of_conversion == s_port) /* there was no port, just a colon */
147       || (*end_of_conversion != '\0') /* did not reach the end of the string */
148       || (port <= 0) || (port > 65535)) {
149     return -1;
150   }
151
152   return (int) port;
153 }
154
155 /**
156  * Parse a hostname out of a hostname:port string
157  *
158  * The ":port" section is optional. Ignores the string after the first colon.
159  * Does not validate the port section of the name.
160  *
161  * An empty hostname is allowed (but s must not be null)
162  *
163  * @param s
164  * @return TR_NAME or null on error (i.e., out-of-memory)
165  */
166 static TR_NAME *tr_aaa_server_parse_hostname(const char *s)
167 {
168   const char *colon;
169   char *hostname;
170   size_t hostname_len;
171   TR_NAME *retval;
172
173   if (s == NULL)
174     return NULL;
175
176   /* find the colon */
177   colon = strchr(s, ':');
178   if (colon == NULL)
179     return tr_new_name(s); /* there was no colon, take the whole string */
180
181   /* make a copy of the hostname portion of the string */
182   hostname_len = colon - s;
183   hostname = malloc(hostname_len + 1); /* +1 for the null termination */
184   if (hostname == NULL)
185     return NULL;
186
187   /* copy up to the colon, add a null termination, and make a TR_NAME */
188   strncpy(hostname, s, hostname_len);
189   hostname[hostname_len] = '\0';
190   retval = tr_new_name(hostname);
191
192   /* clean up and return */
193   free(hostname);
194   return retval;
195 }
196
197 /**
198  * Allocate a AAA server record and fill it in by parsing a hostname:port string
199  *
200  * Does not validate hostname or port values. The port will be -1 if the port
201  * could not be parsed properly.
202  *
203  * @return newly allocated TR_AAA_SERVER in the mem_ctx context, or NULL on error
204  */
205 TR_AAA_SERVER *tr_aaa_server_from_string(TALLOC_CTX *mem_ctx, const char *s)
206 {
207   TALLOC_CTX *tmp_ctx = talloc_new(NULL);
208   TR_AAA_SERVER *aaa = tr_aaa_server_new(tmp_ctx);
209
210   if (aaa == NULL)
211     goto failed;
212
213   tr_aaa_server_set_hostname(aaa, tr_aaa_server_parse_hostname(s));
214   if (tr_aaa_server_get_hostname(aaa) == NULL)
215     goto failed;
216
217   tr_aaa_server_set_port(aaa, tr_aaa_server_parse_port(s));
218   talloc_steal(mem_ctx, aaa); /*put this in the caller's context */
219   goto succeeded;
220
221 failed:
222   aaa = NULL; /* talloc will free the memory if it was allocated */
223
224 succeeded:
225   talloc_free(tmp_ctx);
226   return aaa;
227 }
228
229
230 /**
231  * Allocate a AAA server record and fill it in by parsing a hostname:port TR_NAME
232  *
233  * Does not validate hostname or port values. The port will be -1 if the port
234  * could not be parsed properly.
235  *
236  * @return newly allocated TR_AAA_SERVER in the mem_ctx context, or NULL on error
237  */
238 TR_AAA_SERVER *tr_aaa_server_from_name(TALLOC_CTX *mem_ctx, TR_NAME *n)
239 {
240   TR_AAA_SERVER *aaa = NULL;
241   char *s = tr_name_strdup(n);
242   if (s != NULL) {
243     aaa = tr_aaa_server_from_string(mem_ctx, s);
244     free(s);
245   }
246   return aaa;
247 }
248
249 TR_AAA_SERVER_ITER *tr_aaa_server_iter_new(TALLOC_CTX *mem_ctx)
250 {
251   return talloc(mem_ctx, TR_AAA_SERVER_ITER);
252 }
253
254 void tr_aaa_server_iter_free(TR_AAA_SERVER_ITER *iter)
255 {
256   talloc_free(iter);
257 }
258
259 TR_AAA_SERVER *tr_aaa_server_iter_first(TR_AAA_SERVER_ITER *iter, TR_AAA_SERVER *aaa)
260 {
261   iter->this=aaa;
262   return iter->this;
263 }
264
265 TR_AAA_SERVER *tr_aaa_server_iter_next(TR_AAA_SERVER_ITER *iter)
266 {
267   if (iter->this!=NULL) {
268     iter->this=iter->this->next;
269   }
270   return iter->this;
271 }