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 * File format handling
13 *
14 */
15
16#include <stdio.h>
17#include <string.h>
18#include <unistd.h>
19#include <stdlib.h>
20#include <netdb.h>
21#include <netinet/in.h>
22#include <time.h>
23#include <sys/types.h>
24#include <sys/socket.h>
25
26#include "l2tp.h"
27
28struct lns *lnslist;
29struct lac *laclist;
30struct lns *deflns;
31struct lac *deflac;
32struct global gconfig;
33char filerr[STRLEN];
34
35int parse_config (FILE *);
36struct keyword words[];
37
38int init_config ()
39{
40    FILE *f;
41    int returnedValue;
42
43    gconfig.port = UDP_LISTEN_PORT;
44    lnslist = NULL;
45    laclist = NULL;
46    deflac = (struct lac *) malloc (sizeof (struct lac));
47
48    f = fopen (gconfig.configfile, "r");
49    if (!f)
50    {
51        f = fopen (gconfig.altconfigfile, "r");
52        if (f)
53        {
54            strncpy (gconfig.authfile, gconfig.altauthfile,
55            	sizeof (gconfig.authfile));
56        }
57        else
58        {
59            log (LOG_CRIT, "%s: Unable to open config file %s or %s\n",
60                 __FUNCTION__, gconfig.configfile, gconfig.altconfigfile);
61            return -1;
62        }
63
64    }
65    returnedValue = parse_config (f);
66    fclose (f);
67    return (returnedValue);
68    filerr[0] = 0;
69}
70
71struct lns *new_lns ()
72{
73    struct lns *tmp;
74    tmp = (struct lns *) malloc (sizeof (struct lns));
75    if (!tmp)
76    {
77        log (LOG_CRIT, "%s: Unable to allocate memory for new LNS\n",
78             __FUNCTION__);
79        return NULL;
80    }
81    tmp->next = NULL;
82    tmp->exclusive = 0;
83    tmp->localaddr = 0;
84    tmp->tun_rws = DEFAULT_RWS_SIZE;
85    tmp->call_rws = DEFAULT_RWS_SIZE;
86    tmp->hbit = 0;
87    tmp->lbit = 0;
88    tmp->authpeer = 0;
89    tmp->authself = -1;
90    tmp->authname[0] = 0;
91    tmp->peername[0] = 0;
92    tmp->hostname[0] = 0;
93    tmp->entname[0] = 0;
94    tmp->range = NULL;
95    tmp->lacs = NULL;
96    tmp->passwdauth = 0;
97    tmp->pap_require = 0;
98    tmp->pap_refuse = 0;
99    tmp->chap_require = 0;
100    tmp->chap_refuse = 0;
101    tmp->idle = 0;
102    tmp->pridns = 0;
103    tmp->secdns = 0;
104    tmp->priwins = 0;
105    tmp->secwins = 0;
106    tmp->proxyarp = 0;
107    tmp->proxyauth = 0;
108    tmp->challenge = 0;
109    tmp->debug = 0;
110    tmp->pppoptfile[0] = 0;
111    tmp->t = NULL;
112    return tmp;
113}
114
115struct lac *new_lac ()
116{
117    struct lac *tmp;
118    tmp = (struct lac *) malloc (sizeof (struct lac));
119    if (!tmp)
120    {
121        log (LOG_CRIT, "%s: Unable to allocate memory for lac entry!\n",
122             __FUNCTION__);
123        return NULL;
124    }
125    tmp->next = NULL;
126    tmp->rsched = NULL;
127    tmp->localaddr = 0;
128    tmp->remoteaddr = 0;
129    tmp->lns = 0;
130    tmp->tun_rws = DEFAULT_RWS_SIZE;
131    tmp->call_rws = DEFAULT_RWS_SIZE;
132    tmp->hbit = 0;
133    tmp->lbit = 0;
134    tmp->authpeer = 0;
135    tmp->authself = -1;
136    tmp->authname[0] = 0;
137    tmp->peername[0] = 0;
138    tmp->hostname[0] = 0;
139    tmp->entname[0] = 0;
140    tmp->pap_require = 0;
141    tmp->pap_refuse = 0;
142    tmp->chap_require = 0;
143    tmp->chap_refuse = 0;
144    tmp->t = NULL;
145    tmp->redial = 0;
146    tmp->rtries = 0;
147    tmp->rmax = 0;
148    tmp->challenge = 0;
149    tmp->autodial = 0;
150    tmp->rtimeout = 30;
151    tmp->active = 0;
152    tmp->debug = 0;
153    tmp->pppoptfile[0] = 0;
154    tmp->defaultroute = 0;
155    return tmp;
156}
157
158int yesno (char *value)
159{
160    if (!strcasecmp (value, "yes") || !strcasecmp (value, "y") ||
161        !strcasecmp (value, "true"))
162        return 1;
163    else if (!strcasecmp (value, "no") || !strcasecmp (value, "n") ||
164             !strcasecmp (value, "false"))
165        return 0;
166    else
167        return -1;
168}
169
170int set_boolean (char *word, char *value, int *ptr)
171{
172    int val;
173#ifdef DEBUG_FILE
174    log (LOG_DEBUG, "set_%s: %s  flag to '%s'\n", word, word, value);
175#endif /* ; */
176    if ((val = yesno (value)) < 0)
177    {
178        snprintf (filerr, sizeof (filerr), "%s must be 'yes' or 'no'\n",
179                  word);
180        return -1;
181    }
182    *ptr = val;
183    return 0;
184}
185
186int set_int (char *word, char *value, int *ptr)
187{
188    int val;
189#ifdef DEBUG_FILE
190    log (LOG_DEBUG, "set_%s: %s  flag to '%s'\n", word, word, value);
191#endif /* ; */
192    if ((val = atoi (value)) < 0)
193    {
194        snprintf (filerr, sizeof (filerr), "%s must be a number\n", word);
195        return -1;
196    }
197    *ptr = val;
198    return 0;
199}
200
201int set_string (char *word, char *value, char *ptr, int len)
202{
203#ifdef DEBUG_FILE
204    log (LOG_DEBUG, "set_%s: %s  flag to '%s'\n", word, word, value);
205#endif /* ; */
206    strncpy (ptr, value, len);
207    return 0;
208}
209
210int set_port (char *word, char *value, int context, void *item)
211{
212    switch (context & ~CONTEXT_DEFAULT)
213    {
214    case CONTEXT_GLOBAL:
215#ifdef DEBUG_FILE
216        log (LOG_DEBUG, "set_port: Setting global port number to %s\n",
217             value);
218#endif
219        set_int (word, value, &(((struct global *) item)->port));
220        break;
221    default:
222        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
223                  word);
224        return -1;
225    }
226    return 0;
227}
228
229int set_rtimeout (char *word, char *value, int context, void *item)
230{
231    if (atoi (value) < 1)
232    {
233        snprintf (filerr, sizeof (filerr),
234                  "rtimeout value must be at least 1\n");
235        return -1;
236    }
237    switch (context & ~CONTEXT_DEFAULT)
238    {
239    case CONTEXT_LAC:
240#ifdef DEBUG_FILE
241        log (LOG_DEBUG, "set_rtimeout: Setting redial timeout to %s\n",
242             value);
243#endif
244        set_int (word, value, &(((struct lac *) item)->rtimeout));
245        break;
246    default:
247        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
248                  word);
249        return -1;
250    }
251    return 0;
252}
253
254int set_rws (char *word, char *value, int context, void *item)
255{
256    if (atoi (value) < -1)
257    {
258        snprintf (filerr, sizeof (filerr),
259                  "receive window size must be at least -1\n");
260        return -1;
261    }
262    switch (context & ~CONTEXT_DEFAULT)
263    {
264    case CONTEXT_LAC:
265        if (word[0] == 'c')
266            set_int (word, value, &(((struct lac *) item)->call_rws));
267        if (word[0] == 't')
268        {
269            set_int (word, value, &(((struct lac *) item)->tun_rws));
270            if (((struct lac *) item)->tun_rws < 1)
271            {
272                snprintf (filerr, sizeof (filerr),
273                          "receive window size for tunnels must be at least 1\n");
274                return -1;
275            }
276        }
277        break;
278    case CONTEXT_LNS:
279        if (word[0] == 'c')
280            set_int (word, value, &(((struct lns *) item)->call_rws));
281        if (word[0] == 't')
282        {
283            set_int (word, value, &(((struct lns *) item)->tun_rws));
284            if (((struct lns *) item)->tun_rws < 1)
285            {
286                snprintf (filerr, sizeof (filerr),
287                          "receive window size for tunnels must be at least 1\n");
288                return -1;
289            }
290        }
291        break;
292    default:
293        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
294                  word);
295        return -1;
296    }
297    return 0;
298}
299
300int set_rmax (char *word, char *value, int context, void *item)
301{
302    if (atoi (value) < 1)
303    {
304        snprintf (filerr, sizeof (filerr), "rmax value must be at least 1\n");
305        return -1;
306    }
307    switch (context & ~CONTEXT_DEFAULT)
308    {
309    case CONTEXT_LAC:
310#ifdef DEBUG_FILE
311        log (LOG_DEBUG, "set_rmax: Setting max redials to %s\n", value);
312#endif
313        set_int (word, value, &(((struct lac *) item)->rmax));
314        break;
315    default:
316        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
317                  word);
318        return -1;
319    }
320    return 0;
321}
322
323int set_authfile (char *word, char *value, int context, void *item)
324{
325    if (!strlen (value))
326    {
327        snprintf (filerr, sizeof (filerr),
328                  "no filename specified for authentication\n");
329        return -1;
330    }
331    switch (context & ~CONTEXT_DEFAULT)
332    {
333    case CONTEXT_GLOBAL:
334#ifdef DEBUG_FILE
335        log (LOG_DEBUG, "set_authfile: Setting global auth file to '%s'\n",
336             value);
337#endif /* ; */
338        strncpy (((struct global *) item)->authfile, value,
339                 sizeof (((struct global *)item)->authfile));
340        break;
341    default:
342        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
343                  word);
344        return -1;
345    }
346    return 0;
347}
348
349int set_autodial (char *word, char *value, int context, void *item)
350{
351    switch (context & ~CONTEXT_DEFAULT)
352    {
353    case CONTEXT_LAC:
354        if (set_boolean (word, value, &(((struct lac *) item)->autodial)))
355            return -1;
356        break;
357    default:
358        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
359                  word);
360        return -1;
361    }
362    return 0;
363}
364
365int set_flow (char *word, char *value, int context, void *item)
366{
367    int v;
368    set_boolean (word, value, &v);
369    if (v < 0)
370        return -1;
371    switch (context & ~CONTEXT_DEFAULT)
372    {
373    case CONTEXT_LAC:
374        if (v)
375        {
376            if (((struct lac *) item)->call_rws < 0)
377                ((struct lac *) item)->call_rws = 0;
378        }
379        else
380        {
381            ((struct lac *) item)->call_rws = -1;
382        }
383        break;
384    case CONTEXT_LNS:
385        if (v)
386        {
387            if (((struct lns *) item)->call_rws < 0)
388                ((struct lns *) item)->call_rws = 0;
389        }
390        else
391        {
392            ((struct lns *) item)->call_rws = -1;
393        }
394        break;
395    default:
396        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
397                  word);
398        return -1;
399    }
400    return 0;
401}
402
403int set_defaultroute (char *word, char *value, int context, void *item)
404{
405    switch (context & ~CONTEXT_DEFAULT)
406    {
407    case CONTEXT_LAC:
408        if (set_boolean (word, value, &(((struct lac *) item)->defaultroute)))
409            return -1;
410        break;
411    default:
412        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
413                  word);
414        return -1;
415    }
416    return 0;
417}
418
419int set_authname (char *word, char *value, int context, void *item)
420{
421    struct lac *l = (struct lac *) item;
422    struct lns *n = (struct lns *) item;
423    switch (context & ~CONTEXT_DEFAULT)
424    {
425    case CONTEXT_LNS:
426        if (set_string (word, value, n->authname, sizeof (n->authname)))
427            return -1;
428        break;
429    case CONTEXT_LAC:
430        if (set_string (word, value, l->authname, sizeof (l->authname)))
431            return -1;
432        break;
433    default:
434        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
435                  word);
436        return -1;
437    }
438    return 0;
439}
440
441int set_hostname (char *word, char *value, int context, void *item)
442{
443    struct lac *l = (struct lac *) item;
444    struct lns *n = (struct lns *) item;
445    switch (context & ~CONTEXT_DEFAULT)
446    {
447    case CONTEXT_LNS:
448        if (set_string (word, value, n->hostname, sizeof (n->hostname)))
449            return -1;
450        break;
451    case CONTEXT_LAC:
452        if (set_string (word, value, l->hostname, sizeof (l->hostname)))
453            return -1;
454        break;
455    default:
456        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
457                  word);
458        return -1;
459    }
460    return 0;
461}
462
463int set_passwdauth (char *word, char *value, int context, void *item)
464{
465    switch (context & ~CONTEXT_DEFAULT)
466    {
467    case CONTEXT_LNS:
468        if (set_boolean (word, value, &(((struct lns *) item)->passwdauth)))
469            return -1;
470        break;
471    default:
472        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
473                  word);
474        return -1;
475    }
476    return 0;
477}
478
479int set_hbit (char *word, char *value, int context, void *item)
480{
481    switch (context & ~CONTEXT_DEFAULT)
482    {
483    case CONTEXT_LAC:
484        if (set_boolean (word, value, &(((struct lac *) item)->hbit)))
485            return -1;
486        break;
487    case CONTEXT_LNS:
488        if (set_boolean (word, value, &(((struct lns *) item)->hbit)))
489            return -1;
490        break;
491    default:
492        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
493                  word);
494        return -1;
495    }
496    return 0;
497}
498
499int set_challenge (char *word, char *value, int context, void *item)
500{
501    switch (context & ~CONTEXT_DEFAULT)
502    {
503    case CONTEXT_LAC:
504        if (set_boolean (word, value, &(((struct lac *) item)->challenge)))
505            return -1;
506        break;
507    case CONTEXT_LNS:
508        if (set_boolean (word, value, &(((struct lns *) item)->challenge)))
509            return -1;
510        break;
511    default:
512        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
513                  word);
514        return -1;
515    }
516    return 0;
517}
518
519int set_lbit (char *word, char *value, int context, void *item)
520{
521    switch (context & ~CONTEXT_DEFAULT)
522    {
523    case CONTEXT_LAC:
524        if (set_boolean (word, value, &(((struct lac *) item)->lbit)))
525            return -1;
526        break;
527    case CONTEXT_LNS:
528        if (set_boolean (word, value, &(((struct lns *) item)->lbit)))
529            return -1;
530        break;
531    default:
532        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
533                  word);
534        return -1;
535    }
536    return 0;
537}
538
539
540int set_debug (char *word, char *value, int context, void *item)
541{
542    switch (context & ~CONTEXT_DEFAULT)
543    {
544    case CONTEXT_LAC:
545        if (set_boolean (word, value, &(((struct lac *) item)->debug)))
546            return -1;
547        break;
548    case CONTEXT_LNS:
549        if (set_boolean (word, value, &(((struct lns *) item)->debug)))
550            return -1;
551        break;
552    default:
553        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
554                  word);
555        return -1;
556    }
557    return 0;
558}
559
560int set_pppoptfile (char *word, char *value, int context, void *item)
561{
562    struct lac *l = (struct lac *) item;
563    struct lns *n = (struct lns *) item;
564    switch (context & ~CONTEXT_DEFAULT)
565    {
566    case CONTEXT_LNS:
567        if (set_string (word, value, n->pppoptfile, sizeof (n->pppoptfile)))
568            return -1;
569        break;
570    case CONTEXT_LAC:
571        if (set_string (word, value, l->pppoptfile, sizeof (l->pppoptfile)))
572            return -1;
573        break;
574    default:
575        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
576                  word);
577        return -1;
578    }
579    return 0;
580}
581
582int set_papchap (char *word, char *value, int context, void *item)
583{
584    int result;
585    char *c;
586    struct lac *l = (struct lac *) item;
587    struct lns *n = (struct lns *) item;
588    if (set_boolean (word, value, &result))
589        return -1;
590    c = strchr (word, ' ');
591    c++;
592    switch (context & ~CONTEXT_DEFAULT)
593    {
594    case CONTEXT_LAC:
595        if (c[0] == 'p')        /* PAP */
596            if (word[2] == 'f')
597                l->pap_refuse = result;
598            else
599                l->pap_require = result;
600        else if (c[0] == 'a')   /* Authentication */
601            if (word[2] == 'f')
602                l->authself = result;
603            else
604                l->authpeer = result;
605        else /* CHAP */ if (word[2] == 'f')
606            l->chap_refuse = result;
607        else
608            l->chap_require = result;
609        break;
610    case CONTEXT_LNS:
611        if (c[0] == 'p')        /* PAP */
612            if (word[2] == 'f')
613                n->pap_refuse = result;
614            else
615                n->pap_require = result;
616        else if (c[0] == 'a')   /* Authentication */
617            if (word[2] == 'f')
618                n->authself = !result;
619            else
620                n->authpeer = result;
621        else /* CHAP */ if (word[2] == 'f')
622            n->chap_refuse = result;
623        else
624            n->chap_require = result;
625        break;
626    default:
627        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
628                  word);
629        return -1;
630    }
631    return 0;
632}
633
634int set_redial (char *word, char *value, int context, void *item)
635{
636    switch (context & ~CONTEXT_DEFAULT)
637    {
638    case CONTEXT_LAC:
639        if (set_boolean (word, value, &(((struct lac *) item)->redial)))
640            return -1;
641        break;
642    default:
643        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
644                  word);
645        return -1;
646    }
647    return 0;
648}
649
650int set_accesscontrol (char *word, char *value, int context, void *item)
651{
652    switch (context & ~CONTEXT_DEFAULT)
653    {
654    case CONTEXT_GLOBAL:
655        if (set_boolean
656            (word, value, &(((struct global *) item)->accesscontrol)))
657            return -1;
658        break;
659    default:
660        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
661                  word);
662        return -1;
663    }
664    return 0;
665}
666
667int set_userspace (char *word, char *value, int context, void *item)
668{
669    switch (context & ~CONTEXT_DEFAULT)
670    {
671    case CONTEXT_GLOBAL:
672        if (set_boolean
673            (word, value, &(((struct global *) item)->forceuserspace)))
674            return -1;
675        break;
676    default:
677        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
678                  word);
679        return -1;
680    }
681    return 0;
682}
683
684struct iprange *set_range (char *word, char *value, struct iprange *in)
685{
686    char *c, *d = NULL;
687    struct iprange *ipr, *p;
688    struct hostent *hp;
689    c = strchr (value, '-');
690    if (c)
691    {
692        d = c + 1;
693        *c = 0;
694        while ((c >= value) && (*c < 33))
695            *(c--) = 0;
696        while (*d && (*d < 33))
697            d++;
698    }
699    if (!strlen (value) || (c && !strlen (d)))
700    {
701        snprintf (filerr, sizeof (filerr),
702                  "format is '%s <host or ip> - <host or ip>'\n", word);
703        return NULL;
704    }
705    ipr = (struct iprange *) malloc (sizeof (struct iprange));
706    ipr->next = NULL;
707    hp = gethostbyname (value);
708    if (!hp)
709    {
710        snprintf (filerr, sizeof (filerr), "Unknown host %s\n", value);
711        free (ipr);
712        return NULL;
713    }
714    bcopy (hp->h_addr, &ipr->start, sizeof (unsigned int));
715    if (c)
716    {
717        hp = gethostbyname (d);
718        if (!hp)
719        {
720            snprintf (filerr, sizeof (filerr), "Unknown host %s\n", d);
721            free (ipr);
722            return NULL;
723        }
724        bcopy (hp->h_addr, &ipr->end, sizeof (unsigned int));
725    }
726    else
727        ipr->end = ipr->start;
728    if (ntohl (ipr->start) > ntohl (ipr->end))
729    {
730        snprintf (filerr, sizeof (filerr), "start is greater than end!\n");
731        free (ipr);
732        return NULL;
733    }
734    if (word[0] == 'n')
735        ipr->sense = SENSE_DENY;
736    else
737        ipr->sense = SENSE_ALLOW;
738    p = in;
739    if (p)
740    {
741        while (p->next)
742            p = p->next;
743        p->next = ipr;
744        return in;
745    }
746    else
747        return ipr;
748}
749
750int set_iprange (char *word, char *value, int context, void *item)
751{
752    struct lns *lns = (struct lns *) item;
753    switch (context & ~CONTEXT_DEFAULT)
754    {
755    case CONTEXT_LNS:
756        break;
757    default:
758        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
759                  word);
760        return -1;
761    }
762    lns->range = set_range (word, value, lns->range);
763    if (!lns->range)
764        return -1;
765#ifdef DEBUG_FILE
766    log (LOG_DEBUG, "range start = %x, end = %x, sense=%ud\n",
767         ntohl (ipr->start), ntohl (ipr->end), ipr->sense);
768#endif
769    return 0;
770}
771
772int set_lac (char *word, char *value, int context, void *item)
773{
774    struct lns *lns = (struct lns *) item;
775    switch (context & ~CONTEXT_DEFAULT)
776    {
777    case CONTEXT_LNS:
778        break;
779    default:
780        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
781                  word);
782        return -1;
783    }
784    lns->lacs = set_range (word, value, lns->lacs);
785    if (!lns->lacs)
786        return -1;
787#ifdef DEBUG_FILE
788    log (LOG_DEBUG, "lac start = %x, end = %x, sense=%ud\n",
789         ntohl (ipr->start), ntohl (ipr->end), ipr->sense);
790#endif
791    return 0;
792}
793
794int set_exclusive (char *word, char *value, int context, void *item)
795{
796    switch (context & ~CONTEXT_DEFAULT)
797    {
798    case CONTEXT_LNS:
799        if (set_boolean (word, value, &(((struct lns *) item)->exclusive)))
800            return -1;
801        break;
802    default:
803        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
804                  word);
805        return -1;
806    }
807    return 0;
808}
809
810int set_ip (char *word, char *value, unsigned int *addr)
811{
812    struct hostent *hp;
813    hp = gethostbyname (value);
814    if (!hp)
815    {
816        snprintf (filerr, sizeof (filerr), "%s: host '%s' not found\n",
817                  __FUNCTION__, value);
818        return -1;
819    }
820    bcopy (hp->h_addr, addr, sizeof (unsigned int));
821    return 0;
822}
823
824int set_localaddr (char *word, char *value, int context, void *item)
825{
826    struct lac *l;
827    struct lns *n;
828    switch (context & ~CONTEXT_DEFAULT)
829    {
830    case CONTEXT_LAC:
831        l = (struct lac *) item;
832        return set_ip (word, value, &(l->localaddr));
833    case CONTEXT_LNS:
834        n = (struct lns *) item;
835        return set_ip (word, value, &(n->localaddr));
836    default:
837        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
838                  word);
839        return -1;
840    }
841    return 0;
842}
843
844int set_remoteaddr (char *word, char *value, int context, void *item)
845{
846    struct lac *l;
847    switch (context & ~CONTEXT_DEFAULT)
848    {
849    case CONTEXT_LAC:
850        l = (struct lac *) item;
851        return set_ip (word, value, &(l->remoteaddr));
852    default:
853        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
854                  word);
855        return -1;
856    }
857    return 0;
858}
859
860int set_lns (char *word, char *value, int context, void *item)
861{
862    struct hostent *hp;
863    struct lac *l;
864    struct host *ipr, *pos;
865    char *d;
866    switch (context & ~CONTEXT_DEFAULT)
867    {
868    case CONTEXT_LAC:
869#ifdef DEBUG_FILE
870        log (LOG_DEBUG, "set_lns: setting LNS to '%s'\n", value);
871#endif
872        l = (struct lac *) item;
873        d = strchr (value, ':');
874        if (d)
875        {
876            d[0] = 0;
877            d++;
878        }
879        hp = gethostbyname (value);
880        if (!hp)
881        {
882            snprintf (filerr, sizeof (filerr), "no such host '%s'\n", value);
883            return -1;
884        }
885        ipr = malloc (sizeof (struct host));
886        ipr->next = NULL;
887        pos = l->lns;
888        if (!pos)
889        {
890            l->lns = ipr;
891        }
892        else
893        {
894            while (pos->next)
895                pos = pos->next;
896            pos->next = ipr;
897        }
898        strncpy (ipr->hostname, value, sizeof (ipr->hostname));
899        if (d)
900            ipr->port = atoi (d);
901        else
902            ipr->port = UDP_LISTEN_PORT;
903        break;
904    default:
905        snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
906                  word);
907        return -1;
908    }
909    return 0;
910}
911
912int set_rand_sys ()
913{
914    log(LOG_WARN, "The \"rand()\" function call is not a very good source"
915            "of randomness\n");
916   rand_source = RAND_SYS;
917    return 0;
918}
919
920int set_rand_dev ()
921{
922    rand_source = RAND_DEV;
923    return 0;
924}
925
926int set_rand_egd (char *value)
927{
928    log(LOG_WARN, "%s: not yet implemented!\n", __FUNCTION__);
929    rand_source = RAND_EGD;
930    return -1;
931}
932
933int set_rand_source (char *word, char *value, int context, void *item)
934{
935    time_t seconds;
936    /*
937     * We're going to go ahead and seed the rand() function with srand()
938     * because even if we set the randomness source to dev or egd, they
939     * can fall back to sys if they fail, so we want to make sure we at
940     * least have *some* semblance of randomness available from the
941     * rand() function
942     */
943    /*
944     * This is a sucky random number seed...just the result from the
945     * time() call...but...the user requested to use the rand()
946     * function, which is a pretty sucky source of randomness
947     * regardless...at least we can get a almost sorta decent seed.  If
948     * you have any better suggestions for creating a seed...lemme know
949     * :/
950     */
951    seconds = time(NULL);
952    srand(seconds);
953
954    if (context != CONTEXT_GLOBAL)
955    {
956        log(LOG_WARN, "%s: %s not valid in context %d\n",
957                __FUNCTION__, word, context);
958        return -1;
959    }
960    /* WORKING HERE */
961    if (strlen(value) == 0)
962    {
963        snprintf(filerr, sizeof (filerr), "no randomness source specified\n");
964        return -1;
965    }
966    if (strncmp(value, "egd", 3) == 0)
967    {
968        return set_rand_egd(value);
969    }
970    else if (strncmp(value, "dev", 3) == 0)
971    {
972        return set_rand_dev();
973    }
974    else if (strncmp(value, "sys", 3) == 0)
975    {
976        return set_rand_sys();
977    }
978    else
979    {
980        log(LOG_WARN, "%s: %s is not a valid randomness source\n",
981                __FUNCTION__, value);
982        return -1;
983
984    }
985}
986
987int parse_config (FILE * f)
988{
989    /* Read in the configuration file handed to us */
990    /* FIXME: I should check for incompatible options */
991    int context = 0;
992    char buf[STRLEN];
993    char *s, *d, *t;
994    int linenum = 0;
995    int def = 0;
996    struct keyword *kw;
997    void *data = NULL;
998    struct lns *tl;
999    struct lac *tc;
1000    while (!feof (f))
1001    {
1002        fgets (buf, sizeof (buf), f);
1003        if (feof (f))
1004            break;
1005        linenum++;
1006        s = buf;
1007        /* Strip comments */
1008        while (*s && *s != ';')
1009            s++;
1010        *s = 0;
1011        s = buf;
1012        if (!strlen (buf))
1013            continue;
1014        while ((*s < 33) && *s)
1015            s++;                /* Skip over beginning white space */
1016        t = s + strlen (s);
1017        while ((t >= s) && (*t < 33))
1018            *(t--) = 0;         /* Ditch trailing white space */
1019        if (!strlen (s))
1020            continue;
1021        if (s[0] == '[')
1022        {
1023            /* We've got a context description */
1024            if (!(t = strchr (s, ']')))
1025            {
1026                log (LOG_CRIT, "parse_config: line %d: No closing bracket\n",
1027                     linenum);
1028                return -1;
1029            }
1030            t[0] = 0;
1031            s++;
1032            if ((d = strchr (s, ' ')))
1033            {
1034                /* There's a parameter */
1035                d[0] = 0;
1036                d++;
1037            }
1038            if (d && !strcasecmp (d, "default"))
1039                def = CONTEXT_DEFAULT;
1040            else
1041                def = 0;
1042            if (!strcasecmp (s, "global"))
1043            {
1044                context = CONTEXT_GLOBAL;
1045#ifdef DEBUG_FILE
1046                log (LOG_DEBUG,
1047                     "parse_config: global context descriptor %s\n",
1048                     d ? d : "");
1049#endif
1050                data = &gconfig;
1051            }
1052            else if (!strcasecmp (s, "lns"))
1053            {
1054                context = CONTEXT_LNS;
1055                if (def)
1056                {
1057                    if (!deflns)
1058                    {
1059                        deflns = new_lns ();
1060                        strncpy (deflns->entname, "default",
1061                                 sizeof (deflns->entname));
1062                    }
1063                    data = deflns;
1064                    continue;
1065                }
1066                data = NULL;
1067                tl = lnslist;
1068                if (d)
1069                {
1070                    while (tl)
1071                    {
1072                        if (!strcasecmp (d, tl->entname))
1073                            break;
1074                        tl = tl->next;
1075                    }
1076                    if (tl)
1077                        data = tl;
1078                }
1079                if (!data)
1080                {
1081                    data = new_lns ();
1082                    if (!data)
1083                        return -1;
1084                    ((struct lns *) data)->next = lnslist;
1085                    lnslist = (struct lns *) data;
1086                }
1087                if (d)
1088                    strncpy (((struct lns *) data)->entname,
1089                             d, sizeof (((struct lns *) data)->entname));
1090#ifdef DEBUG_FILE
1091                log (LOG_DEBUG, "parse_config: lns context descriptor %s\n",
1092                     d ? d : "");
1093#endif
1094            }
1095            else if (!strcasecmp (s, "lac"))
1096            {
1097                context = CONTEXT_LAC;
1098                if (def)
1099                {
1100                    if (!deflac)
1101                    {
1102                        deflac = new_lac ();
1103                        strncpy (deflac->entname, "default",
1104                                 sizeof (deflac->entname));
1105                    }
1106                    data = deflac;
1107                    continue;
1108                }
1109                data = NULL;
1110                tc = laclist;
1111                if (d)
1112                {
1113                    while (tc)
1114                    {
1115                        if (!strcasecmp (d, tc->entname))
1116                            break;
1117                        tc = tc->next;
1118                    }
1119                    if (tc)
1120                        data = tc;
1121                }
1122                if (!data)
1123                {
1124                    data = new_lac ();
1125                    if (!data)
1126                        return -1;
1127                    ((struct lac *) data)->next = laclist;
1128                    laclist = (struct lac *) data;
1129                }
1130                if (d)
1131                    strncpy (((struct lac *) data)->entname,
1132                             d, sizeof (((struct lac *) data)->entname));
1133#ifdef DEBUG_FILE
1134                log (LOG_DEBUG, "parse_config: lac context descriptor %s\n",
1135                     d ? d : "");
1136#endif
1137            }
1138            else
1139            {
1140                log (LOG_WARN,
1141                     "parse_config: line %d: unknown context '%s'\n", linenum,
1142                     s);
1143                return -1;
1144            }
1145        }
1146        else
1147        {
1148            if (!context)
1149            {
1150                log (LOG_WARN,
1151                     "parse_config: line %d: data '%s' occurs with no context\n",
1152                     linenum, s);
1153                return -1;
1154            }
1155            if (!(t = strchr (s, '=')))
1156            {
1157                log (LOG_WARN, "parse_config: line %d: no '=' in data\n",
1158                     linenum);
1159                return -1;
1160            }
1161            d = t;
1162            d--;
1163            t++;
1164            while ((d >= s) && (*d < 33))
1165                d--;
1166            d++;
1167            *d = 0;
1168            while (*t && (*t < 33))
1169                t++;
1170#ifdef DEBUG_FILE
1171            log (LOG_DEBUG, "parse_config: field is %s, value is %s\n", s, t);
1172#endif
1173            /* Okay, bit twidling is done.  Let's handle this */
1174            for (kw = words; kw->keyword; kw++)
1175            {
1176                if (!strcasecmp (s, kw->keyword))
1177                {
1178                    if (kw->handler (s, t, context | def, data))
1179                    {
1180                        log (LOG_WARN, "parse_config: line %d: %s", linenum,
1181                             filerr);
1182                        return -1;
1183                    }
1184                    break;
1185                }
1186            }
1187            if (!kw->keyword)
1188            {
1189                log (LOG_CRIT, "parse_config: line %d: Unknown field '%s'\n",
1190                     linenum, s);
1191                return -1;
1192            }
1193        }
1194    }
1195    return 0;
1196}
1197
1198struct keyword words[] = {
1199    {"port", &set_port},
1200    {"rand source", &set_rand_source},
1201    {"auth file", &set_authfile},
1202    {"exclusive", &set_exclusive},
1203    {"autodial", &set_autodial},
1204    {"redial", &set_redial},
1205    {"redial timeout", &set_rtimeout},
1206    {"lns", &set_lns},
1207    {"max redials", &set_rmax},
1208    {"access control", &set_accesscontrol},
1209    {"force userspace", &set_userspace},
1210    {"ip range", &set_iprange},
1211    {"no ip range", &set_iprange},
1212    {"lac", &set_lac},
1213    {"no lac", &set_lac},
1214    {"local ip", &set_localaddr},
1215    {"remote ip", &set_remoteaddr},
1216    {"defaultroute", &set_defaultroute},
1217    {"length bit", &set_lbit},
1218    {"hidden bit", &set_hbit},
1219    {"require pap", &set_papchap},
1220    {"require chap", &set_papchap},
1221    {"require authentication", &set_papchap},
1222    {"require auth", &set_papchap},
1223    {"refuse pap", &set_papchap},
1224    {"refuse chap", &set_papchap},
1225    {"refuse authentication", &set_papchap},
1226    {"refuse auth", &set_papchap},
1227    {"unix authentication", &set_passwdauth},
1228    {"unix auth", &set_passwdauth},
1229    {"name", &set_authname},
1230    {"hostname", &set_hostname},
1231    {"ppp debug", &set_debug},
1232    {"pppoptfile", &set_pppoptfile},
1233    {"call rws", &set_rws},
1234    {"tunnel rws", &set_rws},
1235    {"flow bit", &set_flow},
1236    {"challenge", &set_challenge},
1237    {NULL, NULL}
1238};
1239