X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fauth.c;h=92fe82d9cac8e56fc64405a4c1f3641ecc951f36;hp=d554bfd0f7e6aecb5cfa921f903a160fd45cc92f;hb=f482dc10721044d7ffe4cbc2e78f7ea93b1040e0;hpb=cb67581446e926290c6147634f7f467f48c806b5 diff --git a/pppd/auth.c b/pppd/auth.c index d554bfd..92fe82d 100644 --- a/pppd/auth.c +++ b/pppd/auth.c @@ -10,16 +10,11 @@ * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to + * 2. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * - * 4. Redistributions of any form whatsoever must retain the following + * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". @@ -73,12 +68,13 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: auth.c,v 1.93 2003/03/03 05:11:45 paulus Exp $" +#define RCSID "$Id: auth.c,v 1.104 2005/07/09 05:49:44 paulus Exp $" #include #include #include #include +#include #include #include #include @@ -114,7 +110,7 @@ #include "ecp.h" #include "ipcp.h" #include "upap.h" -#include "chap.h" +#include "chap-new.h" #include "eap.h" #ifdef CBCP_SUPPORT #include "cbcp.h" @@ -186,6 +182,12 @@ void (*pap_logout_hook) __P((void)) = NULL; /* Hook for a plugin to get the PAP password for authenticating us */ int (*pap_passwd_hook) __P((char *user, char *passwd)) = NULL; +/* Hook for a plugin to say if we can possibly authenticate a peer using CHAP */ +int (*chap_check_hook) __P((void)) = NULL; + +/* Hook for a plugin to get the CHAP password for authenticating us */ +int (*chap_passwd_hook) __P((char *user, char *passwd)) = NULL; + /* Hook for a plugin to say whether it is OK if the peer refuses to authenticate. */ int (*null_auth_hook) __P((struct wordlist **paddrs, @@ -530,6 +532,58 @@ void link_required(unit) int unit; { + char *msg; + + new_phase(PHASE_SERIALCONN); + + devfd = the_channel->connect(); + msg = "Connect script failed"; + if (devfd < 0) + goto fail; + + /* set up the serial device as a ppp interface */ + /* + * N.B. we used to do tdb_writelock/tdb_writeunlock around this + * (from establish_ppp to set_ifunit). However, we won't be + * doing the set_ifunit in multilink mode, which is the only time + * we need the atomicity that the tdb_writelock/tdb_writeunlock + * gives us. Thus we don't need the tdb_writelock/tdb_writeunlock. + */ + fd_ppp = the_channel->establish_ppp(devfd); + msg = "ppp establishment failed"; + if (fd_ppp < 0) { + status = EXIT_FATAL_ERROR; + goto disconnect; + } + + if (!demand && ifunit >= 0) + set_ifunit(1); + + /* + * Start opening the connection and wait for + * incoming events (reply, timeout, etc.). + */ + if (ifunit >= 0) + notice("Connect: %s <--> %s", ifname, ppp_devnam); + else + notice("Starting negotiation on %s", ppp_devnam); + add_fd(fd_ppp); + + status = EXIT_NEGOTIATION_FAILED; + new_phase(PHASE_ESTABLISH); + + lcp_lowerup(0); + return; + + disconnect: + new_phase(PHASE_DISCONNECT); + if (the_channel->disconnect) + the_channel->disconnect(); + + fail: + new_phase(PHASE_DEAD); + if (the_channel->cleanup) + (*the_channel->cleanup)(); } /* @@ -540,16 +594,65 @@ void link_terminated(unit) int unit; { - if (phase == PHASE_DEAD) + if (phase == PHASE_DEAD || phase == PHASE_MASTER) return; + new_phase(PHASE_DISCONNECT); + if (pap_logout_hook) { pap_logout_hook(); } else { if (logged_in) plogout(); } - new_phase(PHASE_DEAD); - notice("Connection terminated."); + + if (!doing_multilink) { + notice("Connection terminated."); + print_link_stats(); + } else + notice("Link terminated."); + + /* + * Delete pid files before disestablishing ppp. Otherwise it + * can happen that another pppd gets the same unit and then + * we delete its pid file. + */ + if (!doing_multilink && !demand) + remove_pidfiles(); + + /* + * If we may want to bring the link up again, transfer + * the ppp unit back to the loopback. Set the + * real serial device back to its normal mode of operation. + */ + if (fd_ppp >= 0) { + remove_fd(fd_ppp); + clean_check(); + the_channel->disestablish_ppp(devfd); + if (doing_multilink) + mp_exit_bundle(); + fd_ppp = -1; + } + if (!hungup) + lcp_lowerdown(0); + if (!doing_multilink && !demand) + script_unsetenv("IFNAME"); + + /* + * Run disconnector script, if requested. + * XXX we may not be able to do this if the line has hung up! + */ + if (devfd >= 0 && the_channel->disconnect) { + the_channel->disconnect(); + devfd = -1; + } + + if (doing_multilink && multilink_master) { + if (!bundle_terminating) + new_phase(PHASE_MASTER); + else + mp_bundle_terminated(); + } else + new_phase(PHASE_DEAD); } /* @@ -558,17 +661,30 @@ link_terminated(unit) void link_down(unit) int unit; +{ + if (auth_state != s_down) { + notify(link_down_notifier, 0); + auth_state = s_down; + if (auth_script_state == s_up && auth_script_pid == 0) { + update_link_stats(unit); + auth_script_state = s_down; + auth_script(_PATH_AUTHDOWN); + } + } + if (!doing_multilink) { + upper_layers_down(unit); + if (phase != PHASE_DEAD && phase != PHASE_MASTER) + new_phase(PHASE_ESTABLISH); + } + /* XXX if doing_multilink, should do something to stop + network-layer traffic on the link */ +} + +void upper_layers_down(int unit) { int i; struct protent *protp; - notify(link_down_notifier, 0); - auth_state = s_down; - if (auth_script_state == s_up && auth_script_pid == 0) { - update_link_stats(unit); - auth_script_state = s_down; - auth_script(_PATH_AUTHDOWN); - } for (i = 0; (protp = protocols[i]) != NULL; ++i) { if (!protp->enabled_flag) continue; @@ -579,8 +695,6 @@ link_down(unit) } num_np_open = 0; num_np_up = 0; - if (phase != PHASE_DEAD) - new_phase(PHASE_ESTABLISH); } /* @@ -601,10 +715,12 @@ link_established(unit) /* * Tell higher-level protocols that LCP is up. */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->protocol != PPP_LCP && protp->enabled_flag - && protp->lowerup != NULL) - (*protp->lowerup)(unit); + if (!doing_multilink) { + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if (protp->protocol != PPP_LCP && protp->enabled_flag + && protp->lowerup != NULL) + (*protp->lowerup)(unit); + } if (!auth_required && noauth_addrs != NULL) set_allowed_addrs(unit, NULL, NULL); @@ -634,7 +750,7 @@ link_established(unit) eap_authpeer(unit, our_name); auth |= EAP_PEER; } else if (go->neg_chap) { - ChapAuthPeer(unit, our_name, CHAP_DIGEST(go->chap_mdtype)); + chap_auth_peer(unit, our_name, CHAP_DIGEST(go->chap_mdtype)); auth |= CHAP_PEER; } else if (go->neg_upap) { upap_authpeer(unit); @@ -644,7 +760,7 @@ link_established(unit) eap_authwithpeer(unit, user); auth |= EAP_WITHPEER; } else if (ho->neg_chap) { - ChapAuthWithPeer(unit, user, CHAP_DIGEST(ho->chap_mdtype)); + chap_auth_with_peer(unit, user, CHAP_DIGEST(ho->chap_mdtype)); auth |= CHAP_WITHPEER; } else if (ho->neg_upap) { if (passwd[0] == 0) { @@ -800,7 +916,7 @@ auth_peer_success(unit, protocol, prot_flavor, name, namelen) case PPP_CHAP: bit = CHAP_PEER; switch (prot_flavor) { - case CHAP_DIGEST_MD5: + case CHAP_MD5: bit |= CHAP_MD5_PEER; break; #ifdef CHAPMS @@ -876,7 +992,7 @@ auth_withpeer_success(unit, protocol, prot_flavor) case PPP_CHAP: bit = CHAP_WITHPEER; switch (prot_flavor) { - case CHAP_DIGEST_MD5: + case CHAP_MD5: bit |= CHAP_MD5_WITHPEER; break; #ifdef CHAPMS @@ -1066,8 +1182,8 @@ connect_time_expired(arg) void *arg; { info("Connect time expired"); - lcp_close(0, "Connect time expired"); /* Close connection */ status = EXIT_CONNECT_TIME; + lcp_close(0, "Connect time expired"); /* Close connection */ } /* @@ -1103,12 +1219,14 @@ auth_check_options() if (auth_required) { allow_any_ip = 0; if (!wo->neg_chap && !wo->neg_upap && !wo->neg_eap) { - wo->neg_chap = 1; wo->chap_mdtype = MDTYPE_ALL; + wo->neg_chap = chap_mdtype_all != MDTYPE_NONE; + wo->chap_mdtype = chap_mdtype_all; wo->neg_upap = 1; wo->neg_eap = 1; } } else { - wo->neg_chap = 0; wo->chap_mdtype = MDTYPE_NONE; + wo->neg_chap = 0; + wo->chap_mdtype = MDTYPE_NONE; wo->neg_upap = 0; wo->neg_eap = 0; } @@ -1245,14 +1363,15 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) if (pap_auth_hook) { ret = (*pap_auth_hook)(user, passwd, msg, &addrs, &opts); if (ret >= 0) { + /* note: set_allowed_addrs() saves opts (but not addrs): + don't free it! */ if (ret) set_allowed_addrs(unit, addrs, opts); - BZERO(passwd, sizeof(passwd)); + else if (opts != 0) + free_wordlist(opts); if (addrs != 0) free_wordlist(addrs); - if (opts != 0) { - free_wordlist(opts); - } + BZERO(passwd, sizeof(passwd)); return ret? UPAP_AUTHACK: UPAP_AUTHNAK; } } @@ -1532,6 +1651,7 @@ plogin(user, passwd, msg) static void plogout() { + char *tty; #ifdef USE_PAM int pam_error; @@ -1542,14 +1662,12 @@ plogout() } /* Apparently the pam stuff does closelog(). */ reopen_log(); -#else /* ! USE_PAM */ - char *tty; +#endif /* USE_PAM */ tty = devnam; if (strncmp(tty, "/dev/", 5) == 0) tty += 5; logwtmp(tty, "", ""); /* Wipe out utmp logout entry */ -#endif /* ! USE_PAM */ logged_in = 0; } @@ -1986,7 +2104,7 @@ set_allowed_addrs(unit, addrs, opts) } else { np = getnetbyname (ptr_word); if (np != NULL && np->n_addrtype == AF_INET) { - a = htonl (*(u_int32_t *)np->n_net); + a = htonl ((u_int32_t)np->n_net); if (ptr_mask == NULL) { /* calculate appropriate mask for net */ ah = ntohl(a);