source: rtems/cpukit/pppd/auth.c @ 6a8e52d

4.104.114.84.95
Last change on this file since 6a8e52d was 48cdb95a, checked in by Joel Sherrill <joel.sherrill@…>, on 04/10/03 at 16:20:38

2003-04-10 Joel Sherrill <joel@…>

PR 371/pppd

  • pppd/auth.c, pppd/chat.c, pppd/demand.c, pppd/fsm.c, pppd/lcp.c, pppd/options.c, pppd/pppd.h, pppd/rtemsmain.c, pppd/rtemspppd.c: Change many symbols to static. There are still global symbols in rtemspppd.h which might need to be changed or converted into member of a structure which is dereferenced with a pointer that is managed as a per task variable. But this patch should avoid many conflicts.
  • Property mode set to 100644
File size: 27.3 KB
Line 
1/*
2 * auth.c - PPP authentication and phase control.
3 *
4 * Copyright (c) 1993 The Australian National University.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms are permitted
8 * provided that the above copyright notice and this paragraph are
9 * duplicated in all such forms and that any documentation,
10 * advertising materials, and other materials related to such
11 * distribution and use acknowledge that the software was developed
12 * by the Australian National University.  The name of the University
13 * may not be used to endorse or promote products derived from this
14 * software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18 *
19 * Copyright (c) 1989 Carnegie Mellon University.
20 * All rights reserved.
21 *
22 * Redistribution and use in source and binary forms are permitted
23 * provided that the above copyright notice and this paragraph are
24 * duplicated in all such forms and that any documentation,
25 * advertising materials, and other materials related to such
26 * distribution and use acknowledge that the software was developed
27 * by Carnegie Mellon University.  The name of the
28 * University may not be used to endorse or promote products derived
29 * from this software without specific prior written permission.
30 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
31 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
32 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
33 */
34
35#define RCSID   "$Id$"
36
37#include <stdio.h>
38#include <stddef.h>
39#include <stdlib.h>
40#include <unistd.h>
41#include <pwd.h>
42#include <grp.h>
43#include <string.h>
44#include <sys/types.h>
45#include <sys/stat.h>
46#include <sys/socket.h>
47#include <fcntl.h>
48#if defined(_PATH_LASTLOG) && defined(_linux_)
49#include <lastlog.h>
50#endif
51
52#include <netdb.h>
53#include <netinet/in.h>
54#include <arpa/inet.h>
55
56#ifdef USE_PAM
57#include <security/pam_appl.h>
58#endif
59
60#ifdef HAS_SHADOW
61#include <shadow.h>
62#ifndef PW_PPP
63#define PW_PPP PW_LOGIN
64#endif
65#endif
66
67#include "pppd.h"
68#include "fsm.h"
69#include "lcp.h"
70#include "ipcp.h"
71#include "upap.h"
72#include "chap.h"
73#ifdef CBCP_SUPPORT
74#include "cbcp.h"
75#endif
76#include "pathnames.h"
77
78static const char rcsid[] = RCSID;
79
80/* The name by which the peer authenticated itself to us. */
81char peer_authname[MAXNAMELEN];
82
83/* Records which authentication operations haven't completed yet. */
84static int auth_pending[NUM_PPP];
85
86/* List of addresses which the peer may use. */
87static struct permitted_ip *addresses[NUM_PPP];
88
89/* Wordlist giving addresses which the peer may use
90   without authenticating itself. */
91static struct wordlist *noauth_addrs;
92
93/* Extra options to apply, from the secrets file entry for the peer. */
94static struct wordlist *extra_options;
95
96/* Number of network protocols which we have opened. */
97static int num_np_open;
98
99/* Number of network protocols which have come up. */
100static int num_np_up;
101
102/* Set if we got the contents of passwd[] from the pap-secrets file. */
103static int passwd_from_file;
104
105/* Set if we require authentication only because we have a default route. */
106static bool default_auth;
107
108/* Hook for a link status */
109void (*auth_linkup_hook)__P((void)) = NULL;
110void (*auth_linkdown_hook)__P((void)) = NULL;
111
112/* Hook to enable a plugin to control the idle time limit */
113int (*idle_time_hook) __P((struct ppp_idle *)) = NULL;
114
115/* Hook for a plugin to say whether we can possibly authenticate any peer */
116int (*pap_check_hook) __P((void)) = NULL;
117
118/* Hook for a plugin to check the PAP user and password */
119int (*pap_auth_hook) __P((char *user, char *passwd/*, char **msgp,
120                          struct wordlist **paddrs,
121                          struct wordlist **popts*/)) = NULL;
122
123/* Hook for a plugin to know about the PAP user logout */
124void (*pap_logout_hook) __P((void)) = NULL;
125
126/* Hook for a plugin to get the PAP password for authenticating us */
127int (*pap_passwd_hook) __P((char *user, char *passwd)) = NULL;
128
129/*
130 * This is used to ensure that we don't start an auth-up/down
131 * script while one is already running.
132 */
133enum script_state {
134    s_down,
135    s_up
136};
137
138static enum script_state auth_state = s_down;
139static enum script_state auth_script_state = s_down;
140
141/*
142 * Option variables.
143 */
144bool uselogin = 0;              /* Use /etc/passwd for checking PAP */
145bool cryptpap = 0;              /* Passwords in pap-secrets are encrypted */
146bool refuse_pap = 0;            /* Don't wanna auth. ourselves with PAP */
147bool refuse_chap = 0;           /* Don't wanna auth. ourselves with CHAP */
148bool usehostname = 0;           /* Use hostname for our_name */
149bool auth_required = 0;         /* Always require authentication from peer */
150bool allow_any_ip = 0;          /* Allow peer to use any IP address */
151bool explicit_remote = 0;       /* User specified explicit remote name */
152char remote_name[MAXNAMELEN];   /* Peer's name for authentication */
153
154/* Bits in auth_pending[] */
155#define PAP_WITHPEER    1
156#define PAP_PEER        2
157#define CHAP_WITHPEER   4
158#define CHAP_PEER       8
159
160extern char *crypt __P((const char *, const char *));
161
162/* Prototypes for procedures local to this file. */
163
164static void network_phase __P((int));
165static void check_idle __P((void *));
166static void connect_time_expired __P((void *));
167static int  null_login __P((int));
168static int  get_pap_passwd __P((char *));
169static int  have_pap_secret __P((int *));
170static int  have_chap_secret __P((char *, char *, int, int *));
171#if 0
172static int  ip_addr_check __P((u_int32_t, struct permitted_ip *));
173#endif
174static void free_wordlist __P((struct wordlist *));
175static void auth_script __P((enum script_state s));
176static void set_allowed_addrs __P((int, struct wordlist *, struct wordlist *));
177
178
179/*
180 * Authentication-related options.
181 */
182option_t auth_options[] = {
183    { "require-pap", o_bool, &lcp_wantoptions[0].neg_upap,
184      "Require PAP authentication from peer", 1, &auth_required },
185    { "+pap", o_bool, &lcp_wantoptions[0].neg_upap,
186      "Require PAP authentication from peer", 1, &auth_required },
187    { "refuse-pap", o_bool, &refuse_pap,
188      "Don't agree to auth to peer with PAP", 1 },
189    { "-pap", o_bool, &refuse_pap,
190      "Don't allow PAP authentication with peer", 1 },
191    { "require-chap", o_bool, &lcp_wantoptions[0].neg_chap,
192      "Require CHAP authentication from peer", 1, &auth_required },
193    { "+chap", o_bool, &lcp_wantoptions[0].neg_chap,
194      "Require CHAP authentication from peer", 1, &auth_required },
195    { "refuse-chap", o_bool, &refuse_chap,
196      "Don't agree to auth to peer with CHAP", 1 },
197    { "-chap", o_bool, &refuse_chap,
198      "Don't allow CHAP authentication with peer", 1 },
199    { "name", o_string, our_name,
200      "Set local name for authentication",
201      OPT_PRIV|OPT_STATIC, NULL, MAXNAMELEN },
202    { "user", o_string, user,
203      "Set name for auth with peer", OPT_STATIC, NULL, MAXNAMELEN },
204    { "usehostname", o_bool, &usehostname,
205      "Must use hostname for authentication", 1 },
206    { "remotename", o_string, remote_name,
207      "Set remote name for authentication", OPT_STATIC,
208      &explicit_remote, MAXNAMELEN },
209    { "auth", o_bool, &auth_required,
210      "Require authentication from peer", 1 },
211    { "noauth", o_bool, &auth_required,
212      "Don't require peer to authenticate", OPT_PRIV, &allow_any_ip },
213    {  "login", o_bool, &uselogin,
214      "Use system password database for PAP", 1 },
215    { "papcrypt", o_bool, &cryptpap,
216      "PAP passwords are encrypted", 1 },
217/* Removed for RTEMS PORT
218    { "+ua", o_special, setupapfile,
219      "Get PAP user and password from file" },
220*/
221    { "password", o_string, passwd,
222      "Password for authenticating us to the peer", OPT_STATIC,
223      NULL, MAXSECRETLEN },
224/* Removed for RTEMS_PORT
225    { "privgroup", o_special, privgroup,
226      "Allow group members to use privileged options", OPT_PRIV },
227    { "allow-ip", o_special, set_noauth_addr,
228      "Set IP address(es) which can be used without authentication",
229      OPT_PRIV },
230*/
231    { NULL }
232};
233
234/*
235 * An Open on LCP has requested a change from Dead to Establish phase.
236 * Do what's necessary to bring the physical layer up.
237 */
238void
239link_required(unit)
240    int unit;
241{
242}
243
244/*
245 * LCP has terminated the link; go to the Dead phase and take the
246 * physical layer down.
247 */
248void
249link_terminated(unit)
250    int unit;
251{
252    if (pppd_phase == PHASE_DEAD)
253        return;
254    if (pap_logout_hook) {
255        pap_logout_hook();
256    }
257    new_phase(PHASE_DEAD);
258    notice("Connection terminated.");
259}
260
261/*
262 * LCP has gone down; it will either die or try to re-establish.
263 */
264void
265link_down(unit)
266    int unit;
267{
268    int i;
269    struct protent *protp;
270
271    auth_state = s_down;
272    if (auth_script_state == s_up) {
273        update_link_stats(unit);
274        auth_script(s_down);
275    }
276    for (i = 0; (protp = protocols[i]) != NULL; ++i) {
277        if (!protp->enabled_flag)
278            continue;
279        if (protp->protocol != PPP_LCP && protp->lowerdown != NULL)
280            (*protp->lowerdown)(unit);
281        if (protp->protocol < 0xC000 && protp->close != NULL)
282            (*protp->close)(unit, "LCP down");
283    }
284    num_np_open = 0;
285    num_np_up = 0;
286    if (pppd_phase != PHASE_DEAD)
287        new_phase(PHASE_TERMINATE);
288}
289
290/*
291 * The link is established.
292 * Proceed to the Dead, Authenticate or Network phase as appropriate.
293 */
294void
295link_established(unit)
296    int unit;
297{
298    int auth;
299    lcp_options *wo = &lcp_wantoptions[unit];
300    lcp_options *go = &lcp_gotoptions[unit];
301    lcp_options *ho = &lcp_hisoptions[unit];
302    int i;
303    struct protent *protp;
304
305    /*
306     * Tell higher-level protocols that LCP is up.
307     */
308    for (i = 0; (protp = protocols[i]) != NULL; ++i)
309        if (protp->protocol != PPP_LCP && protp->enabled_flag
310            && protp->lowerup != NULL)
311            (*protp->lowerup)(unit);
312
313    if (auth_required && !(go->neg_chap || go->neg_upap)) {
314        /*
315         * We wanted the peer to authenticate itself, and it refused:
316         * if we have some address(es) it can use without auth, fine,
317         * otherwise treat it as though it authenticated with PAP using
318         * a username * of "" and a password of "".  If that's not OK,
319         * boot it out.
320         */
321        if (noauth_addrs != NULL) {
322            set_allowed_addrs(unit, noauth_addrs, NULL);
323        } else if (!wo->neg_upap || !null_login(unit)) {
324            warn("peer refused to authenticate: terminating link");
325            lcp_close(unit, "peer refused to authenticate");
326            pppd_status = EXIT_PEER_AUTH_FAILED;
327            return;
328        }
329    }
330
331    new_phase(PHASE_AUTHENTICATE);
332    auth = 0;
333    if (go->neg_chap) {
334        ChapAuthPeer(unit, our_name, go->chap_mdtype);
335        auth |= CHAP_PEER;
336    } else if (go->neg_upap) {
337        upap_authpeer(unit);
338        auth |= PAP_PEER;
339    }
340    if (ho->neg_chap) {
341        ChapAuthWithPeer(unit, user, ho->chap_mdtype);
342        auth |= CHAP_WITHPEER;
343    } else if (ho->neg_upap) {
344        if (passwd[0] == 0) {
345            passwd_from_file = 1;
346            if (!get_pap_passwd(passwd))
347                error("No secret found for PAP login");
348        }
349        upap_authwithpeer(unit, user, passwd);
350        auth |= PAP_WITHPEER;
351    }
352    auth_pending[unit] = auth;
353
354    if (!auth)
355        network_phase(unit);
356}
357
358/*
359 * Proceed to the network phase.
360 */
361static void
362network_phase(unit)
363    int unit;
364{
365#ifdef CBCP_SUPPORT
366    lcp_options *go = &lcp_gotoptions[unit];
367#endif
368
369    /* always run the auth-up script */
370    auth_state = s_up;
371    if (auth_script_state == s_down) {
372        auth_script(s_up);
373    }
374
375#ifdef CBCP_SUPPORT
376    /*
377     * If we negotiated callback, do it now.
378     */
379    if (go->neg_cbcp) {
380        new_phase(PHASE_CALLBACK);
381        (*cbcp_protent.open)(unit);
382        return;
383    }
384#endif
385
386    /*
387     * Process extra options from the secrets file
388     */
389    if (extra_options) {
390        options_from_list(extra_options, 1);
391        free_wordlist(extra_options);
392        extra_options = 0;
393    }
394    start_networks();
395}
396
397void
398start_networks()
399{
400    int i;
401    struct protent *protp;
402
403    new_phase(PHASE_NETWORK);
404    for (i = 0; (protp = protocols[i]) != NULL; ++i)
405        if (protp->protocol < 0xC000 && protp->enabled_flag
406            && protp->open != NULL) {
407            (*protp->open)(0);
408            if (protp->protocol != PPP_CCP)
409                ++num_np_open;
410        }
411
412    if (num_np_open == 0)
413        /* nothing to do */
414        lcp_close(0, "No network protocols running");
415}
416
417/*
418 * The peer has failed to authenticate himself using `protocol'.
419 */
420void
421auth_peer_fail(unit, protocol)
422    int unit, protocol;
423{
424    /*
425     * Authentication failure: take the link down
426     */
427    lcp_close(unit, "Authentication failed");
428    pppd_status = EXIT_PEER_AUTH_FAILED;
429}
430
431/*
432 * The peer has been successfully authenticated using `protocol'.
433 */
434void
435auth_peer_success(unit, protocol, name, namelen)
436    int unit, protocol;
437    char *name;
438    int namelen;
439{
440    int bit;
441
442    switch (protocol) {
443    case PPP_CHAP:
444        bit = CHAP_PEER;
445        break;
446    case PPP_PAP:
447        bit = PAP_PEER;
448        break;
449    default:
450        warn("auth_peer_success: unknown protocol %x", protocol);
451        return;
452    }
453
454    /*
455     * Save the authenticated name of the peer for later.
456     */
457    if (namelen > sizeof(peer_authname) - 1)
458        namelen = sizeof(peer_authname) - 1;
459    BCOPY(name, peer_authname, namelen);
460    peer_authname[namelen] = 0;
461
462    /*
463     * If there is no more authentication still to be done,
464     * proceed to the network (or callback) phase.
465     */
466    if ((auth_pending[unit] &= ~bit) == 0)
467        network_phase(unit);
468}
469
470/*
471 * We have failed to authenticate ourselves to the peer using `protocol'.
472 */
473void
474auth_withpeer_fail(unit, protocol)
475    int unit, protocol;
476{
477    if (passwd_from_file)
478        BZERO(passwd, MAXSECRETLEN);
479    /*
480     * We've failed to authenticate ourselves to our peer.
481     * Some servers keep sending CHAP challenges, but there
482     * is no point in persisting without any way to get updated
483     * authentication secrets.
484     */
485    lcp_close(unit, "Failed to authenticate ourselves to peer");
486    pppd_status = EXIT_AUTH_TOPEER_FAILED;
487}
488
489/*
490 * We have successfully authenticated ourselves with the peer using `protocol'.
491 */
492void
493auth_withpeer_success(unit, protocol)
494    int unit, protocol;
495{
496    int bit;
497
498    switch (protocol) {
499    case PPP_CHAP:
500        bit = CHAP_WITHPEER;
501        break;
502    case PPP_PAP:
503        if (passwd_from_file)
504            BZERO(passwd, MAXSECRETLEN);
505        bit = PAP_WITHPEER;
506        break;
507    default:
508        warn("auth_withpeer_success: unknown protocol %x", protocol);
509        bit = 0;
510    }
511
512    /*
513     * If there is no more authentication still being done,
514     * proceed to the network (or callback) phase.
515     */
516    if ((auth_pending[unit] &= ~bit) == 0)
517        network_phase(unit);
518}
519
520
521/*
522 * np_up - a network protocol has come up.
523 */
524void
525np_up(unit, proto)
526    int unit, proto;
527{
528    int tlim;
529
530    if (num_np_up == 0) {
531        /*
532         * At this point we consider that the link has come up successfully.
533         */
534        pppd_status = EXIT_OK;
535        unsuccess = 0;
536        new_phase(PHASE_RUNNING);
537
538        if (idle_time_hook != 0)
539            tlim = (*idle_time_hook)(NULL);
540        else
541            tlim = idle_time_limit;
542        if (tlim > 0)
543            TIMEOUT(check_idle, NULL, tlim);
544
545        /*
546         * Set a timeout to close the connection once the maximum
547         * connect time has expired.
548         */
549        if (maxconnect > 0)
550            TIMEOUT(connect_time_expired, 0, maxconnect);
551    }
552    ++num_np_up;
553}
554
555/*
556 * np_down - a network protocol has gone down.
557 */
558void
559np_down(unit, proto)
560    int unit, proto;
561{
562    if (--num_np_up == 0) {
563        UNTIMEOUT(check_idle, NULL);
564        new_phase(PHASE_NETWORK);
565    }
566}
567
568/*
569 * np_finished - a network protocol has finished using the link.
570 */
571void
572np_finished(unit, proto)
573    int unit, proto;
574{
575    if (--num_np_open <= 0) {
576        /* no further use for the link: shut up shop. */
577        lcp_close(0, "No network protocols running");
578    }
579}
580
581/*
582 * check_idle - check whether the link has been idle for long
583 * enough that we can shut it down.
584 */
585static void
586check_idle(arg)
587    void *arg;
588{
589    struct ppp_idle idle;
590    time_t itime;
591    int tlim;
592
593    if (!get_idle_time(0, &idle))
594        return;
595    if (idle_time_hook != 0) {
596        tlim = idle_time_hook(&idle);
597    } else {
598        itime = MIN(idle.xmit_idle, idle.recv_idle);
599        tlim = idle_time_limit - itime;
600    }
601    if (tlim <= 0) {
602        /* link is idle: shut it down. */
603        notice("Terminating connection due to lack of activity.");
604        lcp_close(0, "Link inactive");
605        need_holdoff = 0;
606        pppd_status = EXIT_IDLE_TIMEOUT;
607    } else {
608        TIMEOUT(check_idle, NULL, tlim);
609    }
610}
611
612/*
613 * connect_time_expired - log a message and close the connection.
614 */
615static void
616connect_time_expired(arg)
617    void *arg;
618{
619    info("Connect time expired");
620    lcp_close(0, "Connect time expired");       /* Close connection */
621    pppd_status = EXIT_CONNECT_TIME;
622}
623
624/*
625 * auth_check_options - called to check authentication options.
626 */
627int
628auth_check_options()
629{
630    lcp_options *wo = &lcp_wantoptions[0];
631    int status      = 1;
632    int can_auth;
633    int lacks_ip;
634
635    /* Default our_name to hostname, and user to our_name */
636    if (our_name[0] == 0 || usehostname)
637        strlcpy(our_name, hostname, sizeof(our_name));
638    if (user[0] == 0)
639        strlcpy(user, our_name, sizeof(user));
640
641    /*
642     * If we have a default route, require the peer to authenticate
643     * unless the noauth option was given or the real user is root.
644     */
645    if (!auth_required && !allow_any_ip && have_route_to(0) && !privileged) {
646        printf("auth_check_options: turning on\n");
647        auth_required = 1;
648        default_auth = 1;
649    }
650
651    /* If authentication is required, ask peer for CHAP or PAP. */
652    if (auth_required) {
653        if (!wo->neg_chap && !wo->neg_upap) {
654            wo->neg_chap = 1;
655            wo->neg_upap = 1;
656        }
657    } else {
658        wo->neg_chap = 0;
659        wo->neg_upap = 0;
660    }
661
662    /*
663     * Check whether we have appropriate secrets to use
664     * to authenticate the peer.
665     */
666    lacks_ip = 0;
667    can_auth = wo->neg_upap && (uselogin || have_pap_secret(&lacks_ip));
668    if (!can_auth && wo->neg_chap) {
669        can_auth = have_chap_secret((explicit_remote? remote_name: NULL),
670                                    our_name, 1, &lacks_ip);
671    }
672
673    if (auth_required && !can_auth && noauth_addrs == NULL) {
674        if (default_auth) {
675            option_error(
676"By default the remote system is required to authenticate itself");
677            option_error(
678"(because this system has a default route to the internet)");
679        } else if (explicit_remote)
680            option_error(
681"The remote system (%s) is required to authenticate itself",
682                         remote_name);
683        else
684            option_error(
685"The remote system is required to authenticate itself");
686        option_error(
687"but I couldn't find any suitable secret (password) for it to use to do so.");
688        if (lacks_ip)
689            option_error(
690"(None of the available passwords would let it use an IP address.)");
691
692        status = 0;
693    }
694    return ( status );
695}
696
697/*
698 * auth_reset - called when LCP is starting negotiations to recheck
699 * authentication options, i.e. whether we have appropriate secrets
700 * to use for authenticating ourselves and/or the peer.
701 */
702void
703auth_reset(unit)
704    int unit;
705{
706    lcp_options *go = &lcp_gotoptions[unit];
707    lcp_options *ao = &lcp_allowoptions[0];
708
709    ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL));
710    ao->neg_chap = !refuse_chap
711        && (passwd[0] != 0
712            || have_chap_secret(user, (explicit_remote? remote_name: NULL),
713                                0, NULL));
714
715    if (go->neg_upap && !uselogin && !have_pap_secret(NULL))
716        go->neg_upap = 0;
717    if (go->neg_chap) {
718        if (!have_chap_secret((explicit_remote? remote_name: NULL),
719                              our_name, 1, NULL))
720            go->neg_chap = 0;
721    }
722}
723
724
725/*
726 * check_passwd - Check the user name and passwd against the PAP secrets
727 * file.  If requested, also check against the system password database,
728 * and login the user if OK.
729 *
730 * returns:
731 *      UPAP_AUTHNAK: Authentication failed.
732 *      UPAP_AUTHACK: Authentication succeeded.
733 * In either case, msg points to an appropriate message.
734 */
735int
736check_passwd(unit, auser, userlen, apasswd, passwdlen, msg)
737    int unit;
738    char *auser;
739    int userlen;
740    char *apasswd;
741    int passwdlen;
742    char **msg;
743{
744    char passwd[64], user[64];
745
746    if (pap_auth_hook)
747    {
748        slprintf(passwd, sizeof(passwd), "%.*v", passwdlen, apasswd);
749        slprintf(user, sizeof(user), "%.*v", userlen, auser);
750
751        return (*pap_auth_hook)(user, passwd/*, NULL, NULL, NULL*/) ?
752            UPAP_AUTHACK : UPAP_AUTHNAK;
753    }
754
755    return UPAP_AUTHACK;
756
757#if 0
758    int    ret = (int)UPAP_AUTHNAK;
759
760    if (( userlen == 0 ) && ( passwdlen == 0 )) {
761      ret = (int)UPAP_AUTHACK;
762    }
763    printf("check_passwd: %d\n", ret);
764
765    return ret;
766#endif
767}
768
769/*
770 * null_login - Check if a username of "" and a password of "" are
771 * acceptable, and iff so, set the list of acceptable IP addresses
772 * and return 1.
773 */
774static int
775null_login(unit)
776    int unit;
777{
778    return 0;
779}
780
781
782/*
783 * get_pap_passwd - get a password for authenticating ourselves with
784 * our peer using PAP.  Returns 1 on success, 0 if no suitable password
785 * could be found.
786 * Assumes passwd points to MAXSECRETLEN bytes of space (if non-null).
787 */
788static int
789get_pap_passwd(passwd)
790    char *passwd;
791{
792    int ret = (int)0;
793
794    /*
795     * Check whether a plugin wants to supply this.
796     */
797    if (pap_passwd_hook) {
798        ret = (*pap_passwd_hook)(user, passwd);
799    }
800
801    return ( ret );
802}
803
804
805/*
806 * have_pap_secret - check whether we have a PAP file with any
807 * secrets that we could possibly use for authenticating the peer.
808 */
809static int
810have_pap_secret(lacks_ipp)
811    int *lacks_ipp;
812{
813    return 1;
814
815#if 0
816    int ret = (int)0;
817
818    /* let the plugin decide, if there is one */
819    printf("have_pap_secret:\n");
820    if (pap_check_hook) {
821        ret = (*pap_check_hook)();
822    }
823
824    return ( ret );
825#endif
826}
827
828
829/*
830 * have_chap_secret - check whether we have a CHAP file with a
831 * secret that we could possibly use for authenticating `client'
832 * on `server'.  Either can be the null string, meaning we don't
833 * know the identity yet.
834 */
835static int
836have_chap_secret(client, server, need_ip, lacks_ipp)
837    char *client;
838    char *server;
839    int need_ip;
840    int *lacks_ipp;
841{
842    return 0;
843}
844
845
846/*
847 * get_secret - open the CHAP secret file and return the secret
848 * for authenticating the given client on the given server.
849 * (We could be either client or server).
850 */
851int
852get_secret(unit, client, server, secret, secret_len, am_server)
853    int unit;
854    char *client;
855    char *server;
856    char *secret;
857    int *secret_len;
858    int am_server;
859{
860    int len;
861    char secbuf[MAXWORDLEN];
862
863    if (!am_server && passwd[0] != 0) {
864        strlcpy(secbuf, passwd, sizeof(secbuf));
865    } else {
866        return 0;
867    }
868
869    len = strlen(secbuf);
870    if (len > MAXSECRETLEN) {
871        error("Secret for %s on %s is too long", client, server);
872        len = MAXSECRETLEN;
873    }
874    BCOPY(secbuf, secret, len);
875    BZERO(secbuf, sizeof(secbuf));
876    *secret_len = len;
877
878    return 1;
879}
880
881/*
882 * set_allowed_addrs() - set the list of allowed addresses.
883 * Also looks for `--' indicating options to apply for this peer
884 * and leaves the following words in extra_options.
885 */
886static void
887set_allowed_addrs(unit, addrs, opts)
888    int unit;
889    struct wordlist *addrs;
890    struct wordlist *opts;
891{
892    int n;
893    struct wordlist *ap, **pap;
894    struct permitted_ip *ip;
895    char *ptr_word, *ptr_mask;
896    struct hostent *hp;
897    struct netent *np;
898    u_int32_t a, mask, ah, offset;
899    struct ipcp_options *wo = &ipcp_wantoptions[unit];
900    u_int32_t suggested_ip = 0;
901
902    if (addresses[unit] != NULL)
903        free(addresses[unit]);
904    addresses[unit] = NULL;
905    if (extra_options != NULL)
906        free_wordlist(extra_options);
907    extra_options = opts;
908
909    /*
910     * Count the number of IP addresses given.
911     */
912    for (n = 0, pap = &addrs; (ap = *pap) != NULL; pap = &ap->next)
913        ++n;
914    if (n == 0)
915        return;
916    ip = (struct permitted_ip *) malloc((n + 1) * sizeof(struct permitted_ip));
917    if (ip == 0)
918        return;
919
920    n = 0;
921    for (ap = addrs; ap != NULL; ap = ap->next) {
922        /* "-" means no addresses authorized, "*" means any address allowed */
923        ptr_word = ap->word;
924        if (strcmp(ptr_word, "-") == 0)
925            break;
926        if (strcmp(ptr_word, "*") == 0) {
927            ip[n].permit = 1;
928            ip[n].base = ip[n].mask = 0;
929            ++n;
930            break;
931        }
932
933        ip[n].permit = 1;
934        if (*ptr_word == '!') {
935            ip[n].permit = 0;
936            ++ptr_word;
937        }
938
939        mask = ~ (u_int32_t) 0;
940        offset = 0;
941        ptr_mask = strchr (ptr_word, '/');
942        if (ptr_mask != NULL) {
943            int bit_count;
944            char *endp;
945
946            bit_count = (int) strtol (ptr_mask+1, &endp, 10);
947            if (bit_count <= 0 || bit_count > 32) {
948                warn("invalid address length %v in auth. address list",
949                     ptr_mask+1);
950                continue;
951            }
952            bit_count = 32 - bit_count; /* # bits in host part */
953            if (*endp == '+') {
954                offset = pppifunit + 1;
955                ++endp;
956            }
957            if (*endp != 0) {
958                warn("invalid address length syntax: %v", ptr_mask+1);
959                continue;
960            }
961            *ptr_mask = '\0';
962            mask <<= bit_count;
963        }
964
965        hp = gethostbyname(ptr_word);
966        if (hp != NULL && hp->h_addrtype == AF_INET) {
967            a = *(u_int32_t *)hp->h_addr;
968        } else {
969            np = getnetbyname (ptr_word);
970            if (np != NULL && np->n_addrtype == AF_INET) {
971                a = htonl (*(u_int32_t *)np->n_net);
972                if (ptr_mask == NULL) {
973                    /* calculate appropriate mask for net */
974                    ah = ntohl(a);
975                    if (IN_CLASSA(ah))
976                        mask = IN_CLASSA_NET;
977                    else if (IN_CLASSB(ah))
978                        mask = IN_CLASSB_NET;
979                    else if (IN_CLASSC(ah))
980                        mask = IN_CLASSC_NET;
981                }
982            } else {
983                a = inet_addr (ptr_word);
984            }
985        }
986
987        if (ptr_mask != NULL)
988            *ptr_mask = '/';
989
990        if (a == (u_int32_t)-1L) {
991            warn("unknown host %s in auth. address list", ap->word);
992            continue;
993        }
994        if (offset != 0) {
995            if (offset >= ~mask) {
996                warn("interface unit %d too large for subnet %v",
997                     pppifunit, ptr_word);
998                continue;
999            }
1000            a = htonl((ntohl(a) & mask) + offset);
1001            mask = ~(u_int32_t)0;
1002        }
1003        ip[n].mask = htonl(mask);
1004        ip[n].base = a & ip[n].mask;
1005        ++n;
1006        if (~mask == 0 && suggested_ip == 0)
1007            suggested_ip = a;
1008    }
1009
1010    ip[n].permit = 0;           /* make the last entry forbid all addresses */
1011    ip[n].base = 0;             /* to terminate the list */
1012    ip[n].mask = 0;
1013
1014    addresses[unit] = ip;
1015
1016    /*
1017     * If the address given for the peer isn't authorized, or if
1018     * the user hasn't given one, AND there is an authorized address
1019     * which is a single host, then use that if we find one.
1020     */
1021    if (suggested_ip != 0
1022        && (wo->hisaddr == 0 || !auth_ip_addr(unit, wo->hisaddr)))
1023        wo->hisaddr = suggested_ip;
1024}
1025
1026/*
1027 * auth_ip_addr - check whether the peer is authorized to use
1028 * a given IP address.  Returns 1 if authorized, 0 otherwise.
1029 */
1030int
1031auth_ip_addr(unit, addr)
1032    int unit;
1033    u_int32_t addr;
1034{
1035#if 0
1036    int ok;
1037#endif
1038
1039    /* don't allow loopback or multicast address */
1040    if (bad_ip_adrs(addr))
1041        return 0;
1042       
1043    return 1;
1044
1045#if 0
1046    if (addresses[unit] != NULL) {
1047        ok = ip_addr_check(addr, addresses[unit]);
1048        if (ok >= 0)
1049            return ok;
1050    }
1051    if (auth_required)
1052        return 0;               /* no addresses authorized */
1053    return allow_any_ip || !have_route_to(addr);
1054#endif
1055}
1056
1057#if 0
1058static int
1059ip_addr_check(addr, addrs)
1060    u_int32_t addr;
1061    struct permitted_ip *addrs;
1062{
1063    for (; ; ++addrs)
1064        if ((addr & addrs->mask) == addrs->base)
1065            return addrs->permit;
1066}
1067#endif
1068
1069/*
1070 * bad_ip_adrs - return 1 if the IP address is one we don't want
1071 * to use, such as an address in the loopback net or a multicast address.
1072 * addr is in network byte order.
1073 */
1074int
1075bad_ip_adrs(addr)
1076    u_int32_t addr;
1077{
1078    addr = ntohl(addr);
1079    return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET
1080        || IN_MULTICAST(addr) || IN_BADCLASS(addr);
1081}
1082
1083/*
1084 * free_wordlist - release memory allocated for a wordlist.
1085 */
1086static void
1087free_wordlist(wp)
1088    struct wordlist *wp;
1089{
1090    struct wordlist *next;
1091
1092    while (wp != NULL) {
1093        next = wp->next;
1094        free(wp);
1095        wp = next;
1096    }
1097}
1098
1099/*
1100 * auth_script - execute a script with arguments
1101 * interface-name peer-name real-user tty speed
1102 */
1103static void
1104auth_script(s)
1105    enum script_state s;
1106{
1107    switch (s) {
1108    case s_up:
1109        auth_script_state = s_up;
1110        if ( auth_linkup_hook ) {
1111          (*auth_linkup_hook)();
1112        }
1113        break;
1114    case s_down:
1115        auth_script_state = s_down;
1116        if ( auth_linkdown_hook ) {
1117          (*auth_linkdown_hook)();
1118        }
1119        break;
1120    }
1121}
Note: See TracBrowser for help on using the repository browser.