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