Line data Source code
1 : /*
2 : Copyright (c) 2007, Adobe Systems, Incorporated
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
7 : met:
8 :
9 : * Redistributions of source code must retain the above copyright
10 : notice, this list of conditions and the following disclaimer.
11 :
12 : * 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 : * Neither the name of Adobe Systems, Network Resonance nor the names of its
17 : contributors may be used to endorse or promote products derived from
18 : this software 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 FOR
23 : A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 : OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 : SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 : LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 : DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 : THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 : (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 : OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 : */
32 :
33 :
34 : static char *RCSSTRING __UNUSED__="$Id: stun_util.c,v 1.2 2008/04/28 18:21:30 ekr Exp $";
35 :
36 : #include <errno.h>
37 : #include <csi_platform.h>
38 :
39 : #ifdef WIN32
40 : #include <winsock2.h>
41 : #include <stdlib.h>
42 : #include <io.h>
43 : #include <time.h>
44 : #else /* UNIX */
45 : #include <string.h>
46 : #endif /* end UNIX */
47 : #include <assert.h>
48 :
49 : #include "stun.h"
50 : #include "stun_reg.h"
51 : #include "registry.h"
52 : #include "addrs.h"
53 : #include "transport_addr_reg.h"
54 : #include "nr_crypto.h"
55 : #include "hex.h"
56 :
57 :
58 : int NR_LOG_STUN = 0;
59 :
60 : int
61 0 : nr_stun_startup(void)
62 : {
63 : int r,_status;
64 :
65 0 : if ((r=r_log_register("stun", &NR_LOG_STUN)))
66 0 : ABORT(r);
67 :
68 0 : _status=0;
69 : abort:
70 0 : return _status;
71 : }
72 :
73 : int
74 0 : nr_stun_xor_mapped_address(UINT4 magicCookie, UINT12 transactionId, nr_transport_addr *from, nr_transport_addr *to)
75 : {
76 : int _status;
77 :
78 0 : switch (from->ip_version) {
79 : case NR_IPV4:
80 0 : nr_ip4_port_to_transport_addr(
81 0 : (ntohl(from->u.addr4.sin_addr.s_addr) ^ magicCookie),
82 0 : (ntohs(from->u.addr4.sin_port) ^ (magicCookie>>16)),
83 0 : from->protocol, to);
84 0 : break;
85 : case NR_IPV6:
86 : {
87 : union {
88 : unsigned char addr[16];
89 : UINT4 addr32[4];
90 : } maskedAddr;
91 :
92 0 : maskedAddr.addr32[0] = htonl(magicCookie); /* Passed in host byte order */
93 0 : memcpy(&maskedAddr.addr32[1], transactionId.octet, sizeof(transactionId));
94 :
95 : /* We now have the mask in network byte order */
96 : /* Xor the address in network byte order */
97 0 : for (int i = 0; i < sizeof(maskedAddr); ++i) {
98 0 : maskedAddr.addr[i] ^= from->u.addr6.sin6_addr.s6_addr[i];
99 : }
100 :
101 0 : nr_ip6_port_to_transport_addr(
102 : (struct in6_addr*)&maskedAddr,
103 0 : (ntohs(from->u.addr6.sin6_port) ^ (magicCookie>>16)),
104 0 : from->protocol, to);
105 : }
106 0 : break;
107 : default:
108 0 : assert(0);
109 : ABORT(R_INTERNAL);
110 : break;
111 : }
112 :
113 0 : _status = 0;
114 : abort:
115 0 : return _status;
116 : }
117 :
118 : int
119 0 : nr_stun_filter_local_addresses(nr_local_addr addrs[], int *count)
120 : {
121 : int r,_status;
122 0 : char allow_loopback = 0;
123 0 : char allow_link_local = 0;
124 :
125 0 : if ((r=NR_reg_get_char(NR_STUN_REG_PREF_ALLOW_LOOPBACK_ADDRS,
126 : &allow_loopback))) {
127 0 : if (r != R_NOT_FOUND) {
128 0 : ABORT(r);
129 : }
130 : }
131 :
132 0 : if ((r=NR_reg_get_char(NR_STUN_REG_PREF_ALLOW_LINK_LOCAL_ADDRS,
133 : &allow_link_local))) {
134 0 : if (r != R_NOT_FOUND) {
135 0 : ABORT(r);
136 : }
137 : }
138 :
139 0 : if ((r=nr_stun_remove_duplicate_addrs(addrs,
140 : !allow_loopback,
141 : !allow_link_local,
142 : count))) {
143 0 : ABORT(r);
144 : }
145 :
146 0 : _status=0;
147 : abort:
148 0 : return _status;
149 : }
150 :
151 : int
152 0 : nr_stun_find_local_addresses(nr_local_addr addrs[], int maxaddrs, int *count)
153 : {
154 : int r,_status;
155 : //NR_registry *children = 0;
156 :
157 0 : *count = 0;
158 :
159 : #if 0
160 : // this really goes with the code commented out below. (mjf)
161 : if ((r=NR_reg_get_child_count(NR_STUN_REG_PREF_ADDRESS_PRFX, (unsigned int*)count)))
162 : if (r != R_NOT_FOUND)
163 : ABORT(r);
164 : #endif
165 :
166 0 : if (*count == 0) {
167 0 : if ((r=nr_stun_get_addrs(addrs, maxaddrs, count)))
168 0 : ABORT(r);
169 :
170 0 : goto done;
171 : }
172 :
173 0 : if (*count >= maxaddrs) {
174 0 : r_log(NR_LOG_STUN, LOG_INFO, "Address list truncated from %d to %d", *count, maxaddrs);
175 0 : *count = maxaddrs;
176 : }
177 :
178 : #if 0
179 : if (*count > 0) {
180 : /* TODO(ekr@rtfm.com): Commented out 2012-07-26.
181 :
182 : This code is currently not used in Firefox and needs to be
183 : ported to 64-bit */
184 : children = RCALLOC((*count + 10) * sizeof(*children));
185 : if (!children)
186 : ABORT(R_NO_MEMORY);
187 :
188 : assert(sizeof(size_t) == sizeof(*count));
189 :
190 : if ((r=NR_reg_get_children(NR_STUN_REG_PREF_ADDRESS_PRFX, children, (size_t)(*count + 10), (size_t*)count)))
191 : ABORT(r);
192 :
193 : for (i = 0; i < *count; ++i) {
194 : if ((r=nr_reg_get_transport_addr(children[i], 0, &addrs[i].addr)))
195 : ABORT(r);
196 : }
197 : }
198 : #endif
199 :
200 : done:
201 :
202 0 : _status=0;
203 : abort:
204 : //RFREE(children);
205 0 : return _status;
206 : }
207 :
208 : int
209 0 : nr_stun_different_transaction(UCHAR *msg, int len, nr_stun_message *req)
210 : {
211 : int _status;
212 : nr_stun_message_header header;
213 : char reqid[44];
214 : char msgid[44];
215 : int len2;
216 :
217 0 : if (sizeof(header) > len)
218 0 : ABORT(R_FAILED);
219 :
220 : assert(sizeof(header.id) == sizeof(UINT12));
221 :
222 0 : memcpy(&header, msg, sizeof(header));
223 :
224 0 : if (memcmp(&req->header.id, &header.id, sizeof(header.id))) {
225 0 : nr_nbin2hex((UCHAR*)&req->header.id, sizeof(req->header.id), reqid, sizeof(reqid), &len2);
226 0 : nr_nbin2hex((UCHAR*)&header.id, sizeof(header.id), msgid, sizeof(msgid), &len2);
227 0 : r_log(NR_LOG_STUN, LOG_DEBUG, "Mismatched message IDs %s/%s", reqid, msgid);
228 0 : ABORT(R_NOT_FOUND);
229 : }
230 :
231 0 : _status=0;
232 : abort:
233 0 : return _status;
234 : }
235 :
236 : char*
237 0 : nr_stun_msg_type(int type)
238 : {
239 0 : char *ret = 0;
240 :
241 0 : switch (type) {
242 : case NR_STUN_MSG_BINDING_REQUEST:
243 0 : ret = "BINDING-REQUEST";
244 0 : break;
245 : case NR_STUN_MSG_BINDING_INDICATION:
246 0 : ret = "BINDING-INDICATION";
247 0 : break;
248 : case NR_STUN_MSG_BINDING_RESPONSE:
249 0 : ret = "BINDING-RESPONSE";
250 0 : break;
251 : case NR_STUN_MSG_BINDING_ERROR_RESPONSE:
252 0 : ret = "BINDING-ERROR-RESPONSE";
253 0 : break;
254 :
255 : #ifdef USE_TURN
256 : case NR_STUN_MSG_ALLOCATE_REQUEST:
257 0 : ret = "ALLOCATE-REQUEST";
258 0 : break;
259 : case NR_STUN_MSG_ALLOCATE_RESPONSE:
260 0 : ret = "ALLOCATE-RESPONSE";
261 0 : break;
262 : case NR_STUN_MSG_ALLOCATE_ERROR_RESPONSE:
263 0 : ret = "ALLOCATE-ERROR-RESPONSE";
264 0 : break;
265 : case NR_STUN_MSG_REFRESH_REQUEST:
266 0 : ret = "REFRESH-REQUEST";
267 0 : break;
268 : case NR_STUN_MSG_REFRESH_RESPONSE:
269 0 : ret = "REFRESH-RESPONSE";
270 0 : break;
271 : case NR_STUN_MSG_REFRESH_ERROR_RESPONSE:
272 0 : ret = "REFRESH-ERROR-RESPONSE";
273 0 : break;
274 : case NR_STUN_MSG_SEND_INDICATION:
275 0 : ret = "SEND-INDICATION";
276 0 : break;
277 : case NR_STUN_MSG_DATA_INDICATION:
278 0 : ret = "DATA-INDICATION";
279 0 : break;
280 : case NR_STUN_MSG_PERMISSION_REQUEST:
281 0 : ret = "PERMISSION-REQUEST";
282 0 : break;
283 : case NR_STUN_MSG_PERMISSION_RESPONSE:
284 0 : ret = "PERMISSION-RESPONSE";
285 0 : break;
286 : case NR_STUN_MSG_PERMISSION_ERROR_RESPONSE:
287 0 : ret = "PERMISSION-ERROR-RESPONSE";
288 0 : break;
289 : #endif /* USE_TURN */
290 :
291 : default:
292 : /* ret remains 0 */
293 0 : break;
294 : }
295 :
296 0 : return ret;
297 : }
298 :
299 : int
300 0 : nr_random_alphanum(char *alphanum, int size)
301 : {
302 : static char alphanums[256] = {
303 : 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
304 : 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
305 : 'U', 'V', 'W', 'X', 'Y', 'Z',
306 : 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
307 : 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
308 : 'u', 'v', 'w', 'x', 'y', 'z',
309 : '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
310 : 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
311 : 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
312 : 'U', 'V', 'W', 'X', 'Y', 'Z',
313 : 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
314 : 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
315 : 'u', 'v', 'w', 'x', 'y', 'z',
316 : '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
317 : 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
318 : 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
319 : 'U', 'V', 'W', 'X', 'Y', 'Z',
320 : 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
321 : 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
322 : 'u', 'v', 'w', 'x', 'y', 'z',
323 : '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
324 : 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
325 : 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
326 : 'U', 'V', 'W', 'X', 'Y', 'Z',
327 : 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
328 : 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
329 : 'u', 'v', 'w', 'x', 'y', 'z',
330 : '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
331 : 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' };
332 : int i;
333 :
334 0 : nr_crypto_random_bytes((UCHAR*)alphanum, size);
335 :
336 : /* now convert from binary to alphanumeric */
337 0 : for (i = 0; i < size; ++i)
338 0 : alphanum[i] = alphanums[(UCHAR)alphanum[i]];
339 :
340 0 : return 0;
341 : }
|