1 | /*
2 | * Layer Two Tunnelling Protocol Daemon
3 | * Copyright (C) 1998 Adtran, Inc.
4 | *
5 | * Mark Spencer
6 | *
7 | * This software is distributed under the terms
8 | * of the GPL, which you should have received
9 | * along with this source.
10 | *
11 | * Authorization, Accounting, and Access control
12 | *
13 | */
14 |
15 | #include <stdio.h>
16 | #include <stdlib.h>
17 | #include <netinet/in.h>
18 | #include <arpa/inet.h>
19 | #include <string.h>
20 | #include <errno.h>
21 | #include "l2tp.h"
22 |
23 | extern void bufferDump (char *, int);
24 |
25 | /* FIXME: Accounting? */
26 |
27 | static struct addr_ent *uaddr[ADDR_HASH_SIZE];
28 |
29 | void init_addr ()
30 | {
31 | int x;
32 | for (x = 0; x < ADDR_HASH_SIZE; x++)
33 | uaddr[x] = NULL;
34 | }
35 |
36 | static int ip_used (unsigned int addr)
37 | {
38 | struct addr_ent *tmp;
39 | tmp = uaddr[addr % ADDR_HASH_SIZE];
40 | while (tmp)
41 | {
42 | if (tmp->addr == addr)
43 | return -1;
44 | tmp = tmp->next;
45 | }
46 | return 0;
47 | }
48 |
49 | void mk_challenge (char *c, int length)
50 | {
51 | int x;
52 | int *s = (int *) c;
53 | for (x = 0; x < length / sizeof (int); x++)
54 | s[x] = rand ();
55 | }
56 |
57 | void reserve_addr (unsigned int addr)
58 | {
59 | /* Mark this address as in use */
60 | struct addr_ent *tmp, *tmp2;
61 | addr = ntohl (addr);
62 | if (ip_used (addr))
63 | return;
64 | tmp = uaddr[addr % ADDR_HASH_SIZE];
65 | tmp2 = (struct addr_ent *) malloc (sizeof (struct addr_ent));
66 | uaddr[addr % ADDR_HASH_SIZE] = tmp2;
67 | tmp2->next = tmp;
68 | tmp2->addr = addr;
69 | }
70 |
71 | void unreserve_addr (unsigned int addr)
72 | {
73 | struct addr_ent *tmp, *last = NULL, *z;
74 | addr = ntohl (addr);
75 | tmp = uaddr[addr % ADDR_HASH_SIZE];
76 | while (tmp)
77 | {
78 | if (tmp->addr == addr)
79 | {
80 | if (last)
81 | {
82 | last->next = tmp->next;
83 | }
84 | else
85 | {
86 | uaddr[addr % ADDR_HASH_SIZE] = tmp->next;
87 | }
88 | z = tmp;
89 | tmp = tmp->next;
90 | free (z);
91 | }
92 | else
93 | {
94 | last = tmp;
95 | tmp = tmp->next;
96 | }
97 | }
98 | }
99 |
100 | unsigned int get_addr (struct iprange *ipr)
101 | {
102 | unsigned int x, y;
103 | int status;
104 | struct iprange *ipr2;
105 | while (ipr)
106 | {
107 | if (ipr->sense == SENSE_ALLOW)
108 | for (x = ntohl (ipr->start); x <= ntohl (ipr->end); x++)
109 | {
110 | /* Found an IP in an ALLOW range, check to be sure it is
111 | consistant through the remaining regions */
112 | if (!ip_used (x))
113 | {
114 | status = SENSE_ALLOW;
115 | ipr2 = ipr->next;
116 | while (ipr2)
117 | {
118 | if ((x >= ntohl (ipr2->start))
119 | && (x <= ntohl (ipr2->end)))
120 | status = ipr2->sense;
121 | ipr2 = ipr2->next;
122 | }
123 | y = htonl (x);
124 | if (status == SENSE_ALLOW)
125 | return y;
126 | }
127 | };
128 | ipr = ipr->next;
129 | }
130 | return 0;
131 | }
132 |
133 | int get_secret (char *us, char *them, char *secret, int size)
134 | {
135 | FILE *f;
136 | char buf[STRLEN];
137 | char *u, *t, *s;
138 | int num = 0;
139 | f = fopen (gconfig.authfile, "r");
140 | if (!f)
141 | {
142 | log (LOG_WARN, "%s : Unable to open '%s' for authentication\n",
143 | __FUNCTION__, gconfig.authfile);
144 | return 0;
145 | }
146 | while (!feof (f))
147 | {
148 | num++;
149 | fgets (buf, sizeof (buf), f);
150 | if (feof (f))
151 | break;
152 | /* Strip comments */
153 | for (t = buf; *t; t++)
154 | *t = ((*t == '#') || (*t == ';')) ? 0 : *t;
155 | /* Strip trailing whitespace */
156 | for (t = buf + strlen (buf) - 1; (t >= buf) && (*t < 33); t--)
157 | *t = 0;
158 | if (!strlen (buf))
159 | continue; /* Empty line */
160 | u = buf;
161 | while (*u && (*u < 33))
162 | u++;
163 | /* us */
164 | if (!*u)
165 | {
166 | log (LOG_WARN,
167 | "%s: Invalid authentication info (no us), line %d\n",
168 | __FUNCTION__, num);
169 | continue;
170 | }
171 | t = u;
172 | while (*t > 32)
173 | t++;
174 | *(t++) = 0;
175 | while (*t && (*t < 33))
176 | t++;
177 | /* them */
178 | if (!*t)
179 | {
180 | log (LOG_WARN,
181 | "%s: Invalid authentication info (nothem), line %d\n",
182 | __FUNCTION__, num);
183 | continue;
184 | }
185 | s = t;
186 | while (*s > 33)
187 | s++;
188 | *(s++) = 0;
189 | while (*s && (*s < 33))
190 | s++;
191 | if (!*s)
192 | {
193 | log (LOG_WARN,
194 | "%s: Invalid authentication info (no secret), line %d\n",
195 | __FUNCTION__, num);
196 | continue;
197 | }
198 | if ((!strcasecmp (u, us) || !strcasecmp (u, "*")) &&
199 | (!strcasecmp (t, them) || !strcasecmp (t, "*")))
200 | {
201 | #ifdef DEBUG_AUTH
202 | log (LOG_DEBUG,
203 | "%s: we are '%s', they are '%s', secret is '%s'\n",
204 | __FUNCTION__, u, t, s);
205 | #endif
206 | strncpy (secret, s, size);
207 | return -1;
208 | }
209 | }
210 | return 0;
211 | }
212 |
213 | int handle_challenge (struct tunnel *t, struct challenge *chal)
214 | {
215 | char *us;
216 | char *them;
217 | if (!t->lns && !t->lac)
218 | {
219 | log (LOG_DEBUG, "%s: No LNS or LAC to handle challenge!\n",
220 | __FUNCTION__);
221 | return -1;
222 | }
223 | #ifdef DEBUG_AUTH
224 | log (LOG_DEBUG, "%s: making response for tunnel%d\n", __FUNCTION__,
225 | t->ourtid);
226 | #endif
227 | if (t->lns)
228 | {
229 | if (t->lns->hostname[0])
230 | us = t->lns->hostname;
231 | else
232 | us = hostname;
233 | if (t->lns->peername[0])
234 | them = t->lns->peername;
235 | else
236 | them = t->hostname;
237 | }
238 | else
239 | {
240 | if (t->lac->hostname[0])
241 | us = t->lac->hostname;
242 | else
243 | us = hostname;
244 | if (t->lac->peername[0])
245 | them = t->lac->peername;
246 | else
247 | them = t->hostname;
248 | }
249 | if (!get_secret (us, them, chal->secret, sizeof (chal->secret)))
250 | {
251 | log (LOG_DEBUG, "%s: no secret found for us='%s' and them='%s'\n",
252 | __FUNCTION__, us, them);
253 | return -1;
254 | }
255 |
256 | #if DEBUG_AUTH
257 | log (LOG_DEBUG, "*%s: Here comes the chal->ss:\n", __FUNCTION__);
258 | bufferDump (&chal->ss, 1);
259 |
260 | log (LOG_DEBUG, "%s: Here comes the secret\n", __FUNCTION__);
261 | bufferDump (chal->secret, strlen (chal->secret));
262 |
263 | log (LOG_DEBUG, "%s: Here comes the challenge\n", __FUNCTION__);
264 | bufferDump (chal->challenge, MD_SIG_SIZE);
265 | #endif
266 |
267 | memset (chal->response, 0, MD_SIG_SIZE);
268 | MD5Init (&chal->md5);
269 | MD5Update (&chal->md5, &chal->ss, 1);
270 | MD5Update (&chal->md5, chal->secret, strlen (chal->secret));
271 | MD5Update (&chal->md5, chal->challenge, MD_SIG_SIZE);
272 | MD5Final (chal->response, &chal->md5);
273 | #ifdef DEBUG_AUTH
274 | log (LOG_DEBUG, "response is %X%X%X%X to '%s' and %X%X%X%X, %d\n",
275 | *((int *) &chal->response[0]),
276 | *((int *) &chal->response[4]),
277 | *((int *) &chal->response[8]),
278 | *((int *) &chal->response[12]),
279 | chal->secret,
280 | *((int *) &chal->challenge[0]),
281 | *((int *) &chal->challenge[4]),
282 | *((int *) &chal->challenge[8]),
283 | *((int *) &chal->challenge[12]), chal->ss);
284 | #endif
285 | chal->state = STATE_CHALLENGED;
286 | return 0;
287 | }
288 |
289 | struct lns *get_lns (struct tunnel *t)
290 | {
291 | /*
292 | * Look through our list of LNS's and
293 | * find a reasonable LNS for this call
294 | * if one is available
295 | */
296 | struct lns *lns;
297 | struct iprange *ipr;
298 | int allow, checkdefault = 0;
299 | /* If access control is disabled, we give the default
300 | otherwise, we give nothing */
301 | allow = 0;
302 | lns = lnslist;
303 | if (!lns)
304 | {
305 | lns = deflns;
306 | checkdefault = -1;
307 | }
308 | while (lns)
309 | {
310 | ipr = lns->lacs;
311 | while (ipr)
312 | {
313 | if ((ntohl (t->peer.sin_addr.s_addr) >= ntohl (ipr->start)) &&
314 | (ntohl (t->peer.sin_addr.s_addr) <= ntohl (ipr->end)))
315 | {
316 | #ifdef DEBUG_AAA
317 | log (LOG_DEBUG,
318 | "get_lns: Rule %s to %s, sense %s matched %s\n",
319 | IPADDY (ipr->start), IPADDY (ipr->end),
320 | (ipr->sense ? "allow" : "deny"), IPADDY (t->addr));
321 | #endif
322 | allow = ipr->sense;
323 | }
324 | ipr = ipr->next;
325 | }
326 | if (allow)
327 | return lns;
328 | lns = lns->next;
329 | if (!lns && !checkdefault)
330 | {
331 | lns = deflns;
332 | checkdefault = -1;
333 | }
334 | }
335 | if (gconfig.accesscontrol)
336 | return NULL;
337 | else
338 | return deflns;
339 | }
340 |
341 | #ifdef DEBUG_HIDDEN
342 | void print_md5 (void *md5)
343 | {
344 | int *i = (int *) md5;
345 | log (LOG_DEBUG, "%X%X%X%X\n", i[0], i[1], i[2], i[3], i[4]);
346 | }
347 |
348 | inline void print_challenge (struct challenge *chal)
349 | {
350 | log (LOG_DEBUG, "vector: ");
351 | print_md5 (chal->vector);
352 | log (LOG_DEBUG, "secret: %s\n", chal->secret);
353 | }
354 | #endif
355 | void encrypt_avp (struct buffer *buf, _u16 len, struct tunnel *t)
356 | {
357 | /* Encrypts an AVP of len, at data. We assume there
358 | are two "spare bytes" before the data pointer,l but otherwise
359 | this is just a normal AVP that is about to be returned from
360 | an avpsend routine */
361 | struct avp_hdr *new_hdr =
362 | (struct avp_hdr *) (buf->start + buf->len - len);
363 | struct avp_hdr *old_hdr =
364 | (struct avp_hdr *) (buf->start + buf->len - len + 2);
365 | _u16 length, flags, attr; /* New length, old flags */
366 | char *ptr, *end;
367 | int cnt;
368 | unsigned char digest[MD_SIG_SIZE];
369 | unsigned char *previous_segment;
370 |
371 | /* FIXME: Should I pad more randomly? Right now I pad to nearest 16 bytes */
372 | length =
373 | ((len - sizeof (struct avp_hdr) + 1) / 16 + 1) * 16 +
374 | sizeof (struct avp_hdr);
375 | flags = htons (old_hdr->length) & 0xF000;
376 | new_hdr->length = htons (length | flags | HBIT);
377 | new_hdr->vendorid = old_hdr->vendorid;
378 | new_hdr->attr = attr = old_hdr->attr;
379 | /* This is really the length field of the hidden sub-format */
380 | old_hdr->attr = htons (len - sizeof (struct avp_hdr));
381 | /* Okay, now we've rewritten the header, as it should be. Let's start
382 | encrypting the actual data now */
383 | buf->len -= len;
384 | buf->len += length;
385 | /* Back to the beginning of real data, including the original length AVP */
386 |
387 | MD5Init (&t->chal_them.md5);
388 | MD5Update (&t->chal_them.md5, (void *) &attr, 2);
389 | MD5Update (&t->chal_them.md5, t->chal_them.secret,
390 | strlen (t->chal_them.secret));
391 | MD5Update (&t->chal_them.md5, t->chal_them.vector, VECTOR_SIZE);
392 | MD5Final (digest, &t->chal_them.md5);
393 |
394 | /* Though not a "MUST" in the spec, our subformat length is always a multiple of 16 */
395 | ptr = ((char *) new_hdr) + sizeof (struct avp_hdr);
396 | end = ((char *) new_hdr) + length;
397 | previous_segment = ptr;
398 | while (ptr < end)
399 | {
400 | #if DEBUG_HIDDEN
401 | log (LOG_DEBUG, "%s: The digest to be XOR'ed\n", __FUNCTION__);
402 | bufferDump (digest, MD_SIG_SIZE);
403 | log (LOG_DEBUG, "%s: The plaintext to be XOR'ed\n", __FUNCTION__);
404 | bufferDump (ptr, MD_SIG_SIZE);
405 | #endif
406 | for (cnt = 0; cnt < MD_SIG_SIZE; cnt++, ptr++)
407 | {
408 | *ptr = *ptr ^ digest[cnt];
409 | }
410 | #if DEBUG_HIDDEN
411 | log (LOG_DEBUG, "%s: The result of XOR\n", __FUNCTION__);
412 | bufferDump (previous_segment, MD_SIG_SIZE);
413 | #endif
414 | if (ptr < end)
415 | {
416 | MD5Init (&t->chal_them.md5);
417 | MD5Update (&t->chal_them.md5, t->chal_them.secret,
418 | strlen (t->chal_them.secret));
419 | MD5Update (&t->chal_them.md5, previous_segment, MD_SIG_SIZE);
420 | MD5Final (digest, &t->chal_them.md5);
421 | }
422 | previous_segment = ptr;
423 | }
424 | }
425 |
426 | int decrypt_avp (char *buf, struct tunnel *t)
427 | {
428 | /* Decrypts a hidden AVP pointed to by buf. The
429 | new header will be exptected to be two characters
430 | offset from the old */
431 | int cnt = 0;
432 | int len, olen, flags;
433 | char digest[MD_SIG_SIZE];
434 | char *ptr, *end;
435 | _u16 attr;
436 | struct avp_hdr *old_hdr = (struct avp_hdr *) buf;
437 | struct avp_hdr *new_hdr = (struct avp_hdr *) (buf + 2);
438 | int saved_segment_len; /* maybe less 16; may be used if the cipher is longer than 16 octets */
439 | char saved_segment[MD_SIG_SIZE];
440 | ptr = ((char *) old_hdr) + sizeof (struct avp_hdr);
441 | olen = old_hdr->length & 0x0FFF;
442 | end = buf + olen;
443 | if (!t->chal_us.vector)
444 | {
445 | log (LOG_DEBUG,
446 | "decrypt_avp: Hidden bit set, but no random vector specified!\n");
447 | return -EINVAL;
448 | }
449 | /* First, let's decrypt all the data. We're not guaranteed
450 | that it will be padded to a 16 byte boundary, so we
451 | have to be more careful than when encrypting */
452 | attr = ntohs (old_hdr->attr);
453 | MD5Init (&t->chal_us.md5);
454 | MD5Update (&t->chal_us.md5, (void *) &attr, 2);
455 | MD5Update (&t->chal_us.md5, t->chal_us.secret,
456 | strlen (t->chal_us.secret));
457 | MD5Update (&t->chal_us.md5, t->chal_us.vector, t->chal_us.vector_len);
458 | MD5Final (digest, &t->chal_us.md5);
459 | #ifdef DEBUG_HIDDEN
460 | log (LOG_DEBUG, "attribute is %d and challenge is: ", attr);
461 | print_challenge (&t->chal_us);
462 | log (LOG_DEBUG, "md5 is: ");
463 | print_md5 (digest);
464 | #endif
465 | while (ptr < end)
466 | {
467 | if (cnt >= MD_SIG_SIZE)
468 | {
469 | MD5Init (&t->chal_us.md5);
470 | MD5Update (&t->chal_us.md5, t->chal_us.secret,
471 | strlen (t->chal_us.secret));
472 | MD5Update (&t->chal_us.md5, saved_segment, MD_SIG_SIZE);
473 | MD5Final (digest, &t->chal_us.md5);
474 | cnt = 0;
475 | }
476 | /* at the beginning of each segment, we save the current segment (16 octets or less) of cipher
477 | * so that the next round of MD5 (if there is a next round) hash could use it
478 | */
479 | if (cnt == 0)
480 | {
481 | saved_segment_len =
482 | (end - ptr < MD_SIG_SIZE) ? (end - ptr) : MD_SIG_SIZE;
483 | memcpy (saved_segment, ptr, saved_segment_len);
484 | }
485 | *ptr = *ptr ^ digest[cnt++];
486 | ptr++;
487 | }
488 | /* Hopefully we're all nice and decrypted now. Let's rewrite the header.
489 | First save the old flags, and get the new stuff */
490 | flags = old_hdr->length & 0xF000 & ~HBIT;
491 | len = ntohs (new_hdr->attr) + sizeof (struct avp_hdr);
492 | if (len > olen - 2)
493 | {
494 | log (LOG_DEBUG,
495 | "decrypt_avp: Decrypted length is too long (%d > %d)\n", len,
496 | olen - 2);
497 | return -EINVAL;
498 | }
499 | new_hdr->attr = old_hdr->attr;
500 | new_hdr->vendorid = old_hdr->vendorid;
501 | new_hdr->length = len | flags;
502 | return 0;
503 | }