X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fauth.c;h=cf042686a33557e14fb1f81ce29b83c7a28c787b;hp=1e2602bf7d5702b784868ab1093a7a4b794f9e15;hb=fd25394d146bb83043189608d30dd0eeb983186d;hpb=59a3d197fdf9d15d0d78a794257f23b1faafaf36 diff --git a/pppd/auth.c b/pppd/auth.c index 1e2602b..cf04268 100644 --- a/pppd/auth.c +++ b/pppd/auth.c @@ -32,7 +32,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define RCSID "$Id: auth.c,v 1.79 2002/07/15 11:04:18 kad Exp $" +#define RCSID "$Id: auth.c,v 1.88 2002/10/27 12:56:26 fcusack Exp $" #include #include @@ -46,7 +46,7 @@ #include #include #include -#if defined(_PATH_LASTLOG) && defined(_linux_) +#if defined(_PATH_LASTLOG) && defined(__linux__) #include #endif @@ -106,6 +106,12 @@ static struct permitted_ip *addresses[NUM_PPP]; without authenticating itself. */ static struct wordlist *noauth_addrs; +/* Remote telephone number, if available */ +char remote_number[MAXNAMELEN]; + +/* Wordlist giving remote telephone numbers which may connect. */ +static struct wordlist *permitted_numbers; + /* Extra options to apply, from the secrets file entry for the peer. */ static struct wordlist *extra_options; @@ -214,6 +220,7 @@ static int some_ip_ok __P((struct wordlist *)); static int setupapfile __P((char **)); static int privgroup __P((char **)); static int set_noauth_addr __P((char **)); +static int set_permitted_number __P((char **)); static void check_access __P((FILE *, char *)); static int wordlist_count __P((struct wordlist *)); @@ -228,39 +235,39 @@ option_t auth_options[] = { { "auth", o_bool, &auth_required, "Require authentication from peer", OPT_PRIO | 1 }, { "noauth", o_bool, &auth_required, - "Don't require peer to authenticate", OPT_PRIOSUB | OPT_PRIV | OPT_A2COPY, + "Don't require peer to authenticate", OPT_PRIOSUB | OPT_PRIV, &allow_any_ip }, { "require-pap", o_bool, &lcp_wantoptions[0].neg_upap, "Require PAP authentication from peer", - OPT_PRIOSUB | OPT_A2COPY | 1, &auth_required }, + OPT_PRIOSUB | 1, &auth_required }, { "+pap", o_bool, &lcp_wantoptions[0].neg_upap, "Require PAP authentication from peer", - OPT_ALIAS | OPT_PRIOSUB | OPT_A2COPY | 1, &auth_required }, - { "require-chap", o_bool, &lcp_wantoptions[0].neg_chap, + OPT_ALIAS | OPT_PRIOSUB | 1, &auth_required }, + { "require-chap", o_bool, &auth_required, "Require CHAP authentication from peer", - OPT_PRIOSUB | OPT_A2COPY | OPT_A3OR | MDTYPE_MD5, - &auth_required, 0, 0, NULL, 0, 0, &lcp_wantoptions[0].chap_mdtype }, - { "+chap", o_bool, &lcp_wantoptions[0].neg_chap, + OPT_PRIOSUB | OPT_A2OR | MDTYPE_MD5, + &lcp_wantoptions[0].chap_mdtype }, + { "+chap", o_bool, &auth_required, "Require CHAP authentication from peer", - OPT_ALIAS | OPT_PRIOSUB | OPT_A2COPY | OPT_A3OR | MDTYPE_MD5, - &auth_required, 0, 0, NULL, 0, 0, &lcp_wantoptions[0].chap_mdtype }, + OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MD5, + &lcp_wantoptions[0].chap_mdtype }, #ifdef CHAPMS - { "require-mschap", o_bool, &lcp_wantoptions[0].neg_chap, + { "require-mschap", o_bool, &auth_required, "Require MS-CHAP authentication from peer", - OPT_PRIOSUB | OPT_A2COPY | OPT_A3OR | MDTYPE_MICROSOFT, - &auth_required, 0, 0, NULL, 0, 0, &lcp_wantoptions[0].chap_mdtype }, - { "+mschap", o_bool, &lcp_wantoptions[0].neg_chap, + OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT, + &lcp_wantoptions[0].chap_mdtype }, + { "+mschap", o_bool, &auth_required, "Require MS-CHAP authentication from peer", - OPT_ALIAS | OPT_PRIOSUB | OPT_A2COPY | OPT_A3OR | MDTYPE_MICROSOFT, - &auth_required, 0, 0, NULL, 0, 0, &lcp_wantoptions[0].chap_mdtype }, - { "require-mschap-v2", o_bool, &lcp_wantoptions[0].neg_chap, + OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT, + &lcp_wantoptions[0].chap_mdtype }, + { "require-mschap-v2", o_bool, &auth_required, "Require MS-CHAPv2 authentication from peer", - OPT_PRIOSUB | OPT_A2COPY | OPT_A3OR | MDTYPE_MICROSOFT_V2, - &auth_required, 0, 0, NULL, 0, 0, &lcp_wantoptions[0].chap_mdtype }, - { "+mschap-v2", o_bool, &lcp_wantoptions[0].neg_chap, + OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT_V2, + &lcp_wantoptions[0].chap_mdtype }, + { "+mschap-v2", o_bool, &auth_required, "Require MS-CHAPv2 authentication from peer", - OPT_ALIAS | OPT_PRIOSUB | OPT_A2COPY | OPT_A3OR | MDTYPE_MICROSOFT_V2, - &auth_required, 0, 0, NULL, 0, 0, &lcp_wantoptions[0].chap_mdtype }, + OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT_V2, + &lcp_wantoptions[0].chap_mdtype }, #endif { "refuse-pap", o_bool, &refuse_pap, @@ -268,7 +275,8 @@ option_t auth_options[] = { { "-pap", o_bool, &refuse_pap, "Don't allow PAP authentication with peer", OPT_ALIAS | 1 }, { "refuse-chap", o_bool, &refuse_chap, - "Don't agree to auth to peer with CHAP", OPT_A2CLRB | MDTYPE_MD5, + "Don't agree to auth to peer with CHAP", + OPT_A2CLRB | MDTYPE_MD5, &lcp_allowoptions[0].chap_mdtype }, { "-chap", o_bool, &refuse_chap, "Don't allow CHAP authentication with peer", @@ -277,14 +285,16 @@ option_t auth_options[] = { #ifdef CHAPMS { "refuse-mschap", o_bool, &refuse_mschap, "Don't agree to auth to peer with MS-CHAP", - OPT_A2CLRB | MDTYPE_MICROSOFT, &lcp_allowoptions[0].chap_mdtype }, + OPT_A2CLRB | MDTYPE_MICROSOFT, + &lcp_allowoptions[0].chap_mdtype }, { "-mschap", o_bool, &refuse_mschap, "Don't allow MS-CHAP authentication with peer", OPT_ALIAS | OPT_A2CLRB | MDTYPE_MICROSOFT, &lcp_allowoptions[0].chap_mdtype }, { "refuse-mschap-v2", o_bool, &refuse_mschap_v2, "Don't agree to auth to peer with MS-CHAPv2", - OPT_A2CLRB | MDTYPE_MICROSOFT_V2, &lcp_allowoptions[0].chap_mdtype }, + OPT_A2CLRB | MDTYPE_MICROSOFT_V2, + &lcp_allowoptions[0].chap_mdtype }, { "-mschap-v2", o_bool, &refuse_mschap_v2, "Don't allow MS-CHAPv2 authentication with peer", OPT_ALIAS | OPT_A2CLRB | MDTYPE_MICROSOFT_V2, @@ -326,6 +336,14 @@ option_t auth_options[] = { "Set IP address(es) which can be used without authentication", OPT_PRIV | OPT_A2LIST }, + { "remotenumber", o_string, remote_number, + "Set remote telephone number for authentication", OPT_PRIO | OPT_STATIC, + NULL, MAXNAMELEN }, + + { "allow-number", o_special, (void *)set_permitted_number, + "Set telephone number(s) which are allowed to connect", + OPT_PRIV | OPT_A2LIST }, + { NULL } }; @@ -430,6 +448,28 @@ set_noauth_addr(argv) } +/* + * set_permitted_number - set remote telephone number(s) that may connect. + */ +static int +set_permitted_number(argv) + char **argv; +{ + char *number = *argv; + int l = strlen(number) + 1; + struct wordlist *wp; + + wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l); + if (wp == NULL) + novm("allow-number argument"); + wp->word = (char *) (wp + 1); + wp->next = permitted_numbers; + BCOPY(number, wp->word, l); + permitted_numbers = wp; + return 1; +} + + /* * An Open on LCP has requested a change from Dead to Establish phase. * Do what's necessary to bring the physical layer up. @@ -570,6 +610,10 @@ network_phase(unit) { lcp_options *go = &lcp_gotoptions[unit]; + /* Log calling number. */ + if (*remote_number) + notice("peer from calling number %q authorized", remote_number); + /* * If the peer had to authenticate, run the auth-up script now. */ @@ -608,59 +652,62 @@ void start_networks(unit) int unit; { - static int started = 0; int i; struct protent *protp; int ecp_required, mppe_required; - if (!started) { - started = 1; - new_phase(PHASE_NETWORK); + new_phase(PHASE_NETWORK); #ifdef HAVE_MULTILINK - if (multilink) { - if (mp_join_bundle()) { - if (updetach && !nodetach) - detach(); - return; - } + if (multilink) { + if (mp_join_bundle()) { + if (updetach && !nodetach) + detach(); + return; } + } #endif /* HAVE_MULTILINK */ #ifdef PPP_FILTER - if (!demand) - set_filters(&pass_filter, &active_filter); + if (!demand) + set_filters(&pass_filter, &active_filter); #endif - /* Start CCP and ECP */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if ((protp->protocol == PPP_ECP || protp->protocol == PPP_CCP) - && protp->enabled_flag && protp->open != NULL) - (*protp->open)(0); - } + /* Start CCP and ECP */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if ((protp->protocol == PPP_ECP || protp->protocol == PPP_CCP) + && protp->enabled_flag && protp->open != NULL) + (*protp->open)(0); /* - * Bring up other network protocols after encryption has completed. - * OPENED here merely means that negotiation has completed. It is - * up to the protocol to correctly terminate or disable LCP/NCP - * based on the result of the negotiation. + * Bring up other network protocols iff encryption is not required. */ ecp_required = ecp_gotoptions[unit].required; mppe_required = ccp_gotoptions[unit].mppe; - if ((!ecp_required && !mppe_required) - || (ecp_required && ecp_fsm[unit].state == OPENED) - || (mppe_required && ccp_fsm[unit].state == OPENED)) { - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->protocol < 0xC000 - && protp->protocol != PPP_CCP && protp->protocol != PPP_ECP - && protp->enabled_flag && protp->open != NULL) { - (*protp->open)(0); - ++num_np_open; - } + if (!ecp_required && !mppe_required) + continue_networks(unit); +} - if (num_np_open == 0) - /* nothing to do */ - lcp_close(0, "No network protocols running"); - } +void +continue_networks(unit) + int unit; +{ + int i; + struct protent *protp; + + /* + * Start the "real" network protocols. + */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if (protp->protocol < 0xC000 + && protp->protocol != PPP_CCP && protp->protocol != PPP_ECP + && protp->enabled_flag && protp->open != NULL) { + (*protp->open)(0); + ++num_np_open; + } + + if (num_np_open == 0) + /* nothing to do */ + lcp_close(0, "No network protocols running"); } /* @@ -893,8 +940,8 @@ check_maxoctets(arg) case PPP_OCTETS_DIRECTION_OUT: used = link_stats.bytes_out; break; - case PPP_OCTETS_DIRECTION_MAX: - case PPP_OCTETS_DIRECTION_MAX2: + case PPP_OCTETS_DIRECTION_MAXOVERAL: + case PPP_OCTETS_DIRECTION_MAXSESSION: used = (link_stats.bytes_in > link_stats.bytes_out) ? link_stats.bytes_in : link_stats.bytes_out; break; default: @@ -981,6 +1028,10 @@ auth_check_options() default_auth = 1; } + /* If we selected any CHAP flavors, we should probably negotiate it. :-) */ + if (wo->chap_mdtype) + wo->neg_chap = 1; + /* If authentication is required, ask peer for CHAP or PAP. */ if (auth_required) { allow_any_ip = 0; @@ -1133,19 +1184,14 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) ret = UPAP_AUTHACK; if (uselogin || login_secret) { /* login option or secret is @login */ - ret = plogin(user, passwd, msg); - if (ret == UPAP_AUTHNAK) - warn("PAP login failure for %s", user); - else + if ((ret = plogin(user, passwd, msg)) == UPAP_AUTHACK) used_login = 1; } if (secret[0] != 0 && !login_secret) { /* password given in pap-secrets - must match */ if ((cryptpap || strcmp(passwd, secret) != 0) - && strcmp(crypt(passwd, secret), secret) != 0) { + && strcmp(crypt(passwd, secret), secret) != 0) ret = UPAP_AUTHNAK; - warn("PAP authentication failure for %s", user); - } } } fclose(f); @@ -1355,7 +1401,7 @@ plogin(user, passwd, msg) tty = devnam; if (strncmp(tty, "/dev/", 5) == 0) tty += 5; - logwtmp(tty, user, remote_name); /* Add wtmp login entry */ + logwtmp(tty, user, ifname); /* Add wtmp login entry */ #if defined(_PATH_LASTLOG) && !defined(USE_PAM) if (pw != (struct passwd *)NULL) { @@ -1882,6 +1928,34 @@ some_ip_ok(addrs) return 0; } +/* + * auth_number - check whether the remote number is allowed to connect. + * Returns 1 if authorized, 0 otherwise. + */ +int +auth_number() +{ + struct wordlist *wp = permitted_numbers; + int l; + + /* Allow all if no authorization list. */ + if (!wp) + return 1; + + /* Allow if we have a match in the authorization list. */ + while (wp) { + /* trailing '*' wildcard */ + l = strlen(wp->word); + if ((wp->word)[l - 1] == '*') + l--; + if (!strncasecmp(wp->word, remote_number, l)) + return 1; + wp = wp->next; + } + + return 0; +} + /* * check_access - complain if a secret file has too-liberal permissions. */