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  | }