source: rtems-libbsd/rtemsbsd/pppd/auth.c @ f0aaa04

55-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since f0aaa04 was 70fa95a, checked in by Sebastian Huber <sebastian.huber@…>, on 09/30/14 at 12:46:12

ppp: Import from RTEMS sources

  • Property mode set to 100644
File size: 27.0 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)(void) = NULL;
110void (*auth_linkdown_hook)(void) = NULL;
111
112/* Hook to enable a plugin to control the idle time limit */
113int (*idle_time_hook)(struct ppp_idle *) = NULL;
114
115/* Hook for a plugin to say whether we can possibly authenticate any peer */
116int (*pap_check_hook)(void) = NULL;
117
118/* Hook for a plugin to check the PAP user and password */
119int (*pap_auth_hook)(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)(void) = NULL;
125
126/* Hook for a plugin to get the PAP password for authenticating us */
127int (*pap_passwd_hook)(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(const char *, const char *);
161
162/* Prototypes for procedures local to this file. */
163
164static void network_phase(int);
165static void check_idle(void *);
166static void connect_time_expired(void *);
167static int  null_login(int);
168static int  get_pap_passwd(char *);
169static int  have_pap_secret(int *);
170static int  have_chap_secret(char *, char *, int, int *);
171#if 0
172static int  ip_addr_check(uint32_t, struct permitted_ip *);
173#endif
174static void free_wordlist(struct wordlist *);
175static void auth_script(enum script_state s);
176static void set_allowed_addrs(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, 0, 0 },
185    { "+pap", o_bool, &lcp_wantoptions[0].neg_upap,
186      "Require PAP authentication from peer", 1, &auth_required, 0, 0 },
187    { "refuse-pap", o_bool, &refuse_pap,
188      "Don't agree to auth to peer with PAP", 1, NULL, 0, 0 },
189    { "-pap", o_bool, &refuse_pap,
190      "Don't allow PAP authentication with peer", 1, NULL, 0, 0 },
191    { "require-chap", o_bool, &lcp_wantoptions[0].neg_chap,
192      "Require CHAP authentication from peer", 1, &auth_required, 0, 0 },
193    { "+chap", o_bool, &lcp_wantoptions[0].neg_chap,
194      "Require CHAP authentication from peer", 1, &auth_required, 0, 0 },
195    { "refuse-chap", o_bool, &refuse_chap,
196      "Don't agree to auth to peer with CHAP", 1, NULL, 0, 0 },
197    { "-chap", o_bool, &refuse_chap,
198      "Don't allow CHAP authentication with peer", 1, NULL, 0, 0 },
199    { "name", o_string, our_name,
200      "Set local name for authentication",
201      OPT_PRIV|OPT_STATIC, NULL, MAXNAMELEN, 0 },
202    { "user", o_string, user,
203      "Set name for auth with peer", OPT_STATIC, NULL, MAXNAMELEN, 0 },
204    { "usehostname", o_bool, &usehostname,
205      "Must use hostname for authentication", 1, NULL, 0, 0 },
206    { "remotename", o_string, remote_name,
207      "Set remote name for authentication", OPT_STATIC,
208      &explicit_remote, MAXNAMELEN, 0 },
209    { "auth", o_bool, &auth_required,
210      "Require authentication from peer", 1, NULL, 0, 0 },
211    { "noauth", o_bool, &auth_required,
212      "Don't require peer to authenticate", OPT_PRIV, &allow_any_ip, 0, 0 },
213    {  "login", o_bool, &uselogin,
214      "Use system password database for PAP", 1, NULL, 0, 0 },
215    { "papcrypt", o_bool, &cryptpap,
216      "PAP passwords are encrypted", 1, NULL, 0, 0 },
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, 0 },
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, 0, NULL, NULL, 0,  NULL, 0, 0 }
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(
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(
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(
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(
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(
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(void)
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(
422    int unit,
423    int protocol)
424{
425    /*
426     * Authentication failure: take the link down
427     */
428    lcp_close(unit, "Authentication failed");
429    pppd_status = EXIT_PEER_AUTH_FAILED;
430}
431
432/*
433 * The peer has been successfully authenticated using `protocol'.
434 */
435void
436auth_peer_success(
437    int unit,
438    int protocol,
439    char *name,
440    int namelen)
441{
442    int bit;
443
444    switch (protocol) {
445    case PPP_CHAP:
446        bit = CHAP_PEER;
447        break;
448    case PPP_PAP:
449        bit = PAP_PEER;
450        break;
451    default:
452        warn("auth_peer_success: unknown protocol %x", protocol);
453        return;
454    }
455
456    /*
457     * Save the authenticated name of the peer for later.
458     */
459    if (namelen > sizeof(peer_authname) - 1)
460        namelen = sizeof(peer_authname) - 1;
461    BCOPY(name, peer_authname, namelen);
462    peer_authname[namelen] = 0;
463
464    /*
465     * If there is no more authentication still to be done,
466     * proceed to the network (or callback) phase.
467     */
468    if ((auth_pending[unit] &= ~bit) == 0)
469        network_phase(unit);
470}
471
472/*
473 * We have failed to authenticate ourselves to the peer using `protocol'.
474 */
475void
476auth_withpeer_fail(
477    int unit,
478    int protocol )
479{
480    if (passwd_from_file)
481        BZERO(passwd, MAXSECRETLEN);
482    /*
483     * We've failed to authenticate ourselves to our peer.
484     * Some servers keep sending CHAP challenges, but there
485     * is no point in persisting without any way to get updated
486     * authentication secrets.
487     */
488    lcp_close(unit, "Failed to authenticate ourselves to peer");
489    pppd_status = EXIT_AUTH_TOPEER_FAILED;
490}
491
492/*
493 * We have successfully authenticated ourselves with the peer using `protocol'.
494 */
495void
496auth_withpeer_success(
497    int unit,
498    int protocol )
499{
500    int bit;
501
502    switch (protocol) {
503    case PPP_CHAP:
504        bit = CHAP_WITHPEER;
505        break;
506    case PPP_PAP:
507        if (passwd_from_file)
508            BZERO(passwd, MAXSECRETLEN);
509        bit = PAP_WITHPEER;
510        break;
511    default:
512        warn("auth_withpeer_success: unknown protocol %x", protocol);
513        bit = 0;
514    }
515
516    /*
517     * If there is no more authentication still being done,
518     * proceed to the network (or callback) phase.
519     */
520    if ((auth_pending[unit] &= ~bit) == 0)
521        network_phase(unit);
522}
523
524
525/*
526 * np_up - a network protocol has come up.
527 */
528void
529np_up(
530    int unit,
531    int proto )
532{
533    int tlim;
534
535    if (num_np_up == 0) {
536        /*
537         * At this point we consider that the link has come up successfully.
538         */
539        pppd_status = EXIT_OK;
540        unsuccess = 0;
541        new_phase(PHASE_RUNNING);
542
543        if (idle_time_hook != 0)
544            tlim = (*idle_time_hook)(NULL);
545        else
546            tlim = idle_time_limit;
547        if (tlim > 0)
548            TIMEOUT(check_idle, NULL, tlim);
549
550        /*
551         * Set a timeout to close the connection once the maximum
552         * connect time has expired.
553         */
554        if (maxconnect > 0)
555            TIMEOUT(connect_time_expired, 0, maxconnect);
556    }
557    ++num_np_up;
558}
559
560/*
561 * np_down - a network protocol has gone down.
562 */
563void
564np_down(
565    int unit,
566    int proto)
567{
568    if (--num_np_up == 0) {
569        UNTIMEOUT(check_idle, NULL);
570        new_phase(PHASE_NETWORK);
571    }
572}
573
574/*
575 * np_finished - a network protocol has finished using the link.
576 */
577void
578np_finished(
579    int unit,
580    int proto )
581{
582    if (--num_np_open <= 0) {
583        /* no further use for the link: shut up shop. */
584        lcp_close(0, "No network protocols running");
585    }
586}
587
588/*
589 * check_idle - check whether the link has been idle for long
590 * enough that we can shut it down.
591 */
592static void
593check_idle(
594    void *arg )
595{
596    struct ppp_idle idle;
597    time_t itime;
598    int tlim;
599
600    if (!get_idle_time(0, &idle))
601        return;
602    if (idle_time_hook != 0) {
603        tlim = idle_time_hook(&idle);
604    } else {
605        itime = MIN(idle.xmit_idle, idle.recv_idle);
606        tlim = idle_time_limit - itime;
607    }
608    if (tlim <= 0) {
609        /* link is idle: shut it down. */
610        notice("Terminating connection due to lack of activity.");
611        lcp_close(0, "Link inactive");
612        need_holdoff = 0;
613        pppd_status = EXIT_IDLE_TIMEOUT;
614    } else {
615        TIMEOUT(check_idle, NULL, tlim);
616    }
617}
618
619/*
620 * connect_time_expired - log a message and close the connection.
621 */
622static void
623connect_time_expired(
624    void *arg)
625{
626    info("Connect time expired");
627    lcp_close(0, "Connect time expired");       /* Close connection */
628    pppd_status = EXIT_CONNECT_TIME;
629}
630
631/*
632 * auth_check_options - called to check authentication options.
633 */
634int
635auth_check_options(void)
636{
637    lcp_options *wo = &lcp_wantoptions[0];
638    int status      = 1;
639    int can_auth;
640    int lacks_ip;
641
642    /* Default our_name to hostname, and user to our_name */
643    if (our_name[0] == 0 || usehostname)
644        strlcpy(our_name, hostname, sizeof(our_name));
645    if (user[0] == 0)
646        strlcpy(user, our_name, sizeof(user));
647
648    /*
649     * If we have a default route, require the peer to authenticate
650     * unless the noauth option was given or the real user is root.
651     */
652    if (!auth_required && !allow_any_ip && have_route_to(0) && !privileged) {
653        printf("auth_check_options: turning on\n");
654        auth_required = 1;
655        default_auth = 1;
656    }
657
658    /* If authentication is required, ask peer for CHAP or PAP. */
659    if (auth_required) {
660        if (!wo->neg_chap && !wo->neg_upap) {
661            wo->neg_chap = 1;
662            wo->neg_upap = 1;
663        }
664    } else {
665        wo->neg_chap = 0;
666        wo->neg_upap = 0;
667    }
668
669    /*
670     * Check whether we have appropriate secrets to use
671     * to authenticate the peer.
672     */
673    lacks_ip = 0;
674    can_auth = wo->neg_upap && (uselogin || have_pap_secret(&lacks_ip));
675    if (!can_auth && wo->neg_chap) {
676        can_auth = have_chap_secret((explicit_remote? remote_name: NULL),
677                                    our_name, 1, &lacks_ip);
678    }
679
680    if (auth_required && !can_auth && noauth_addrs == NULL) {
681        if (default_auth) {
682            option_error(
683"By default the remote system is required to authenticate itself");
684            option_error(
685"(because this system has a default route to the internet)");
686        } else if (explicit_remote)
687            option_error(
688"The remote system (%s) is required to authenticate itself",
689                         remote_name);
690        else
691            option_error(
692"The remote system is required to authenticate itself");
693        option_error(
694"but I couldn't find any suitable secret (password) for it to use to do so.");
695        if (lacks_ip)
696            option_error(
697"(None of the available passwords would let it use an IP address.)");
698
699        status = 0;
700    }
701    return ( status );
702}
703
704/*
705 * auth_reset - called when LCP is starting negotiations to recheck
706 * authentication options, i.e. whether we have appropriate secrets
707 * to use for authenticating ourselves and/or the peer.
708 */
709void
710auth_reset(
711    int unit)
712{
713    lcp_options *go = &lcp_gotoptions[unit];
714    lcp_options *ao = &lcp_allowoptions[0];
715
716    ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL));
717    ao->neg_chap = !refuse_chap
718        && (passwd[0] != 0
719            || have_chap_secret(user, (explicit_remote? remote_name: NULL),
720                                0, NULL));
721
722    if (go->neg_upap && !uselogin && !have_pap_secret(NULL))
723        go->neg_upap = 0;
724    if (go->neg_chap) {
725        if (!have_chap_secret((explicit_remote? remote_name: NULL),
726                              our_name, 1, NULL))
727            go->neg_chap = 0;
728    }
729}
730
731
732/*
733 * check_passwd - Check the user name and passwd against the PAP secrets
734 * file.  If requested, also check against the system password database,
735 * and login the user if OK.
736 *
737 * returns:
738 *      UPAP_AUTHNAK: Authentication failed.
739 *      UPAP_AUTHACK: Authentication succeeded.
740 * In either case, msg points to an appropriate message.
741 */
742int
743check_passwd(
744    int unit,
745    char *auser,
746    int userlen,
747    char *apasswd,
748    int passwdlen,
749    char **msg)
750{
751    char passwd[64], user[64];
752
753    if (pap_auth_hook)
754    {
755        slprintf(passwd, sizeof(passwd), "%.*v", passwdlen, apasswd);
756        slprintf(user, sizeof(user), "%.*v", userlen, auser);
757
758        return (*pap_auth_hook)(user, passwd/*, NULL, NULL, NULL*/) ?
759            UPAP_AUTHACK : UPAP_AUTHNAK;
760    }
761
762    return UPAP_AUTHACK;
763
764#if 0
765    int    ret = (int)UPAP_AUTHNAK;
766
767    if (( userlen == 0 ) && ( passwdlen == 0 )) {
768      ret = (int)UPAP_AUTHACK;
769    }
770    printf("check_passwd: %d\n", ret);
771
772    return ret;
773#endif
774}
775
776/*
777 * null_login - Check if a username of "" and a password of "" are
778 * acceptable, and iff so, set the list of acceptable IP addresses
779 * and return 1.
780 */
781static int
782null_login(
783    int unit)
784{
785    return 0;
786}
787
788
789/*
790 * get_pap_passwd - get a password for authenticating ourselves with
791 * our peer using PAP.  Returns 1 on success, 0 if no suitable password
792 * could be found.
793 * Assumes passwd points to MAXSECRETLEN bytes of space (if non-null).
794 */
795static int
796get_pap_passwd(
797    char *passwd)
798{
799    int ret = (int)0;
800
801    /*
802     * Check whether a plugin wants to supply this.
803     */
804    if (pap_passwd_hook) {
805        ret = (*pap_passwd_hook)(user, passwd);
806    }
807
808    return ( ret );
809}
810
811
812/*
813 * have_pap_secret - check whether we have a PAP file with any
814 * secrets that we could possibly use for authenticating the peer.
815 */
816static int
817have_pap_secret(
818    int *lacks_ipp)
819{
820    return 1;
821
822#if 0
823    int ret = (int)0;
824
825    /* let the plugin decide, if there is one */
826    printf("have_pap_secret:\n");
827    if (pap_check_hook) {
828        ret = (*pap_check_hook)();
829    }
830
831    return ( ret );
832#endif
833}
834
835
836/*
837 * have_chap_secret - check whether we have a CHAP file with a
838 * secret that we could possibly use for authenticating `client'
839 * on `server'.  Either can be the null string, meaning we don't
840 * know the identity yet.
841 */
842static int
843have_chap_secret(
844    char *client,
845    char *server,
846    int need_ip,
847    int *lacks_ipp)
848{
849    return 0;
850}
851
852
853/*
854 * get_secret - open the CHAP secret file and return the secret
855 * for authenticating the given client on the given server.
856 * (We could be either client or server).
857 */
858int
859get_secret(
860    int unit,
861    char *client,
862    char *server,
863    unsigned char *secret,
864    int *secret_len,
865    int am_server)
866{
867    int len;
868    char secbuf[MAXWORDLEN];
869
870    if (!am_server && passwd[0] != 0) {
871        strlcpy(secbuf, passwd, sizeof(secbuf));
872    } else {
873        return 0;
874    }
875
876    len = strlen(secbuf);
877    if (len > MAXSECRETLEN) {
878        error("Secret for %s on %s is too long", client, server);
879        len = MAXSECRETLEN;
880    }
881    BCOPY(secbuf, secret, len);
882    BZERO(secbuf, sizeof(secbuf));
883    *secret_len = len;
884
885    return 1;
886}
887
888/*
889 * set_allowed_addrs() - set the list of allowed addresses.
890 * Also looks for `--' indicating options to apply for this peer
891 * and leaves the following words in extra_options.
892 */
893static void
894set_allowed_addrs(
895    int unit,
896    struct wordlist *addrs,
897    struct wordlist *opts)
898{
899    int n;
900    struct wordlist *ap, **pap;
901    struct permitted_ip *ip;
902    char *ptr_word, *ptr_mask;
903    struct hostent *hp;
904    struct netent *np;
905    uint32_t a, mask, ah, offset;
906    struct ipcp_options *wo = &ipcp_wantoptions[unit];
907    uint32_t suggested_ip = 0;
908
909    if (addresses[unit] != NULL)
910        free(addresses[unit]);
911    addresses[unit] = NULL;
912    if (extra_options != NULL)
913        free_wordlist(extra_options);
914    extra_options = opts;
915
916    /*
917     * Count the number of IP addresses given.
918     */
919    for (n = 0, pap = &addrs; (ap = *pap) != NULL; pap = &ap->next)
920        ++n;
921    if (n == 0)
922        return;
923    ip = (struct permitted_ip *) malloc((n + 1) * sizeof(struct permitted_ip));
924    if (ip == 0)
925        return;
926
927    n = 0;
928    for (ap = addrs; ap != NULL; ap = ap->next) {
929        /* "-" means no addresses authorized, "*" means any address allowed */
930        ptr_word = ap->word;
931        if (strcmp(ptr_word, "-") == 0)
932            break;
933        if (strcmp(ptr_word, "*") == 0) {
934            ip[n].permit = 1;
935            ip[n].base = ip[n].mask = 0;
936            ++n;
937            break;
938        }
939
940        ip[n].permit = 1;
941        if (*ptr_word == '!') {
942            ip[n].permit = 0;
943            ++ptr_word;
944        }
945
946        mask = ~ (uint32_t) 0;
947        offset = 0;
948        ptr_mask = strchr (ptr_word, '/');
949        if (ptr_mask != NULL) {
950            int bit_count;
951            char *endp;
952
953            bit_count = (int) strtol (ptr_mask+1, &endp, 10);
954            if (bit_count <= 0 || bit_count > 32) {
955                warn("invalid address length %v in auth. address list",
956                     ptr_mask+1);
957                continue;
958            }
959            bit_count = 32 - bit_count; /* # bits in host part */
960            if (*endp == '+') {
961                offset = pppifunit + 1;
962                ++endp;
963            }
964            if (*endp != 0) {
965                warn("invalid address length syntax: %v", ptr_mask+1);
966                continue;
967            }
968            *ptr_mask = '\0';
969            mask <<= bit_count;
970        }
971
972        hp = gethostbyname(ptr_word);
973        if (hp != NULL && hp->h_addrtype == AF_INET) {
974            a = *(uint32_t *)hp->h_addr;
975        } else {
976            np = getnetbyname (ptr_word);
977            if (np != NULL && np->n_addrtype == AF_INET) {
978                a = htonl (np->n_net);
979                if (ptr_mask == NULL) {
980                    /* calculate appropriate mask for net */
981                    ah = ntohl(a);
982                    if (IN_CLASSA(ah))
983                        mask = IN_CLASSA_NET;
984                    else if (IN_CLASSB(ah))
985                        mask = IN_CLASSB_NET;
986                    else if (IN_CLASSC(ah))
987                        mask = IN_CLASSC_NET;
988                }
989            } else {
990                a = inet_addr (ptr_word);
991            }
992        }
993
994        if (ptr_mask != NULL)
995            *ptr_mask = '/';
996
997        if (a == (uint32_t)-1L) {
998            warn("unknown host %s in auth. address list", ap->word);
999            continue;
1000        }
1001        if (offset != 0) {
1002            if (offset >= ~mask) {
1003                warn("interface unit %d too large for subnet %v",
1004                     pppifunit, ptr_word);
1005                continue;
1006            }
1007            a = htonl((ntohl(a) & mask) + offset);
1008            mask = ~(uint32_t)0;
1009        }
1010        ip[n].mask = htonl(mask);
1011        ip[n].base = a & ip[n].mask;
1012        ++n;
1013        if (~mask == 0 && suggested_ip == 0)
1014            suggested_ip = a;
1015    }
1016
1017    ip[n].permit = 0;           /* make the last entry forbid all addresses */
1018    ip[n].base = 0;             /* to terminate the list */
1019    ip[n].mask = 0;
1020
1021    addresses[unit] = ip;
1022
1023    /*
1024     * If the address given for the peer isn't authorized, or if
1025     * the user hasn't given one, AND there is an authorized address
1026     * which is a single host, then use that if we find one.
1027     */
1028    if (suggested_ip != 0
1029        && (wo->hisaddr == 0 || !auth_ip_addr(unit, wo->hisaddr)))
1030        wo->hisaddr = suggested_ip;
1031}
1032
1033/*
1034 * auth_ip_addr - check whether the peer is authorized to use
1035 * a given IP address.  Returns 1 if authorized, 0 otherwise.
1036 */
1037int
1038auth_ip_addr(
1039    int unit,
1040    uint32_t addr)
1041{
1042#if 0
1043    int ok;
1044#endif
1045
1046    /* don't allow loopback or multicast address */
1047    if (bad_ip_adrs(addr))
1048        return 0;
1049       
1050    return 1;
1051
1052#if 0
1053    if (addresses[unit] != NULL) {
1054        ok = ip_addr_check(addr, addresses[unit]);
1055        if (ok >= 0)
1056            return ok;
1057    }
1058    if (auth_required)
1059        return 0;               /* no addresses authorized */
1060    return allow_any_ip || !have_route_to(addr);
1061#endif
1062}
1063
1064#if 0
1065static int
1066ip_addr_check(
1067    uint32_t addr,
1068    struct permitted_ip *addrs)
1069{
1070    for (; ; ++addrs)
1071        if ((addr & addrs->mask) == addrs->base)
1072            return addrs->permit;
1073}
1074#endif
1075
1076/*
1077 * bad_ip_adrs - return 1 if the IP address is one we don't want
1078 * to use, such as an address in the loopback net or a multicast address.
1079 * addr is in network byte order.
1080 */
1081int
1082bad_ip_adrs(
1083    uint32_t addr)
1084{
1085    addr = ntohl(addr);
1086    return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET
1087        || IN_MULTICAST(addr) || IN_BADCLASS(addr);
1088}
1089
1090/*
1091 * free_wordlist - release memory allocated for a wordlist.
1092 */
1093static void
1094free_wordlist(
1095    struct wordlist *wp)
1096{
1097    struct wordlist *next;
1098
1099    while (wp != NULL) {
1100        next = wp->next;
1101        free(wp);
1102        wp = next;
1103    }
1104}
1105
1106/*
1107 * auth_script - execute a script with arguments
1108 * interface-name peer-name real-user tty speed
1109 */
1110static void
1111auth_script(
1112    enum script_state s)
1113{
1114    switch (s) {
1115    case s_up:
1116        auth_script_state = s_up;
1117        if ( auth_linkup_hook ) {
1118          (*auth_linkup_hook)();
1119        }
1120        break;
1121    case s_down:
1122        auth_script_state = s_down;
1123        if ( auth_linkdown_hook ) {
1124          (*auth_linkdown_hook)();
1125        }
1126        break;
1127    }
1128}
Note: See TracBrowser for help on using the repository browser.