1 /*****************************************************************************
\r
2 * auth.c - Network Authentication and Phase Control program file.
\r
4 * Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
\r
5 * Copyright (c) 1997 by Global Election Systems Inc. All rights reserved.
\r
7 * The authors hereby grant permission to use, copy, modify, distribute,
\r
8 * and license this software and its documentation for any purpose, provided
\r
9 * that existing copyright notices are retained in all copies and that this
\r
10 * notice and the following disclaimer are included verbatim in any
\r
11 * distributions. No written agreement, license, or royalty fee is required
\r
12 * for any of the authorized uses.
\r
14 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
\r
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
\r
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
\r
17 * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
\r
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
\r
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
\r
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
\r
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
\r
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
\r
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
25 ******************************************************************************
\r
28 * 03-01-01 Marc Boucher <marc@mbsi.ca>
\r
30 * 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
\r
31 * Ported from public pppd code.
\r
32 *****************************************************************************/
\r
34 * auth.c - PPP authentication and phase control.
\r
36 * Copyright (c) 1993 The Australian National University.
\r
37 * All rights reserved.
\r
39 * Redistribution and use in source and binary forms are permitted
\r
40 * provided that the above copyright notice and this paragraph are
\r
41 * duplicated in all such forms and that any documentation,
\r
42 * advertising materials, and other materials related to such
\r
43 * distribution and use acknowledge that the software was developed
\r
44 * by the Australian National University. The name of the University
\r
45 * may not be used to endorse or promote products derived from this
\r
46 * software without specific prior written permission.
\r
47 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
\r
48 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
\r
49 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
\r
51 * Copyright (c) 1989 Carnegie Mellon University.
\r
52 * All rights reserved.
\r
54 * Redistribution and use in source and binary forms are permitted
\r
55 * provided that the above copyright notice and this paragraph are
\r
56 * duplicated in all such forms and that any documentation,
\r
57 * advertising materials, and other materials related to such
\r
58 * distribution and use acknowledge that the software was developed
\r
59 * by Carnegie Mellon University. The name of the
\r
60 * University may not be used to endorse or promote products derived
\r
61 * from this software without specific prior written permission.
\r
62 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
\r
63 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
\r
64 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
\r
67 #include "lwip/opt.h"
\r
69 #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
\r
72 #include "pppdebug.h"
\r
83 #endif /* CBCP_SUPPORT */
\r
85 /*************************/
\r
86 /*** LOCAL DEFINITIONS ***/
\r
87 /*************************/
\r
89 /* Bits in auth_pending[] */
\r
90 #define PAP_WITHPEER 1
\r
92 #define CHAP_WITHPEER 4
\r
96 /************************/
\r
97 /*** LOCAL DATA TYPES ***/
\r
98 /************************/
\r
99 /* Used for storing a sequence of words. Usually malloced. */
\r
101 struct wordlist *next;
\r
106 /***********************************/
\r
107 /*** LOCAL FUNCTION DECLARATIONS ***/
\r
108 /***********************************/
\r
109 extern char *crypt (const char *, const char *);
\r
111 /* Prototypes for procedures local to this file. */
\r
113 static void network_phase (int);
\r
114 static void check_idle (void *);
\r
115 static void connect_time_expired (void *);
\r
117 static int login (char *, char *, char **, int *);
\r
119 static void logout (void);
\r
120 static int null_login (int);
\r
121 static int get_pap_passwd (int, char *, char *);
\r
122 static int have_pap_secret (void);
\r
123 static int have_chap_secret (char *, char *, u32_t);
\r
124 static int ip_addr_check (u32_t, struct wordlist *);
\r
125 #if 0 /* PAP_SUPPORT || CHAP_SUPPORT */
\r
126 static void set_allowed_addrs(int unit, struct wordlist *addrs);
\r
127 static void free_wordlist (struct wordlist *);
\r
128 #endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */
\r
130 static void callback_phase (int);
\r
131 #endif /* CBCP_SUPPORT */
\r
134 /******************************/
\r
135 /*** PUBLIC DATA STRUCTURES ***/
\r
136 /******************************/
\r
139 /*****************************/
\r
140 /*** LOCAL DATA STRUCTURES ***/
\r
141 /*****************************/
\r
142 #if PAP_SUPPORT || CHAP_SUPPORT
\r
143 /* The name by which the peer authenticated itself to us. */
\r
144 static char peer_authname[MAXNAMELEN];
\r
145 #endif /* PAP_SUPPORT || CHAP_SUPPORT */
\r
147 /* Records which authentication operations haven't completed yet. */
\r
148 static int auth_pending[NUM_PPP];
\r
150 /* Set if we have successfully called login() */
\r
151 static int logged_in;
\r
153 /* Set if we have run the /etc/ppp/auth-up script. */
\r
154 static int did_authup;
\r
156 /* List of addresses which the peer may use. */
\r
157 static struct wordlist *addresses[NUM_PPP];
\r
159 /* Number of network protocols which we have opened. */
\r
160 static int num_np_open;
\r
162 /* Number of network protocols which have come up. */
\r
163 static int num_np_up;
\r
165 #if PAP_SUPPORT || CHAP_SUPPORT
\r
166 /* Set if we got the contents of passwd[] from the pap-secrets file. */
\r
167 static int passwd_from_file;
\r
168 #endif /* PAP_SUPPORT || CHAP_SUPPORT */
\r
171 /***********************************/
\r
172 /*** PUBLIC FUNCTION DEFINITIONS ***/
\r
173 /***********************************/
\r
175 * An Open on LCP has requested a change from Dead to Establish phase.
\r
176 * Do what's necessary to bring the physical layer up.
\r
179 link_required(int unit)
\r
181 LWIP_UNUSED_ARG(unit);
\r
183 AUTHDEBUG((LOG_INFO, "link_required: %d\n", unit));
\r
187 * LCP has terminated the link; go to the Dead phase and take the
\r
188 * physical layer down.
\r
191 link_terminated(int unit)
\r
193 AUTHDEBUG((LOG_INFO, "link_terminated: %d\n", unit));
\r
194 if (lcp_phase[unit] == PHASE_DEAD) {
\r
200 lcp_phase[unit] = PHASE_DEAD;
\r
201 AUTHDEBUG((LOG_NOTICE, "Connection terminated.\n"));
\r
202 pppLinkTerminated(unit);
\r
206 * LCP has gone down; it will either die or try to re-establish.
\r
209 link_down(int unit)
\r
212 struct protent *protp;
\r
214 AUTHDEBUG((LOG_INFO, "link_down: %d\n", unit));
\r
216 /* XXX Do link down processing. */
\r
219 for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {
\r
220 if (!protp->enabled_flag) {
\r
223 if (protp->protocol != PPP_LCP && protp->lowerdown != NULL) {
\r
224 (*protp->lowerdown)(unit);
\r
226 if (protp->protocol < 0xC000 && protp->close != NULL) {
\r
227 (*protp->close)(unit, "LCP down");
\r
232 if (lcp_phase[unit] != PHASE_DEAD) {
\r
233 lcp_phase[unit] = PHASE_TERMINATE;
\r
239 * The link is established.
\r
240 * Proceed to the Dead, Authenticate or Network phase as appropriate.
\r
243 link_established(int unit)
\r
247 struct protent *protp;
\r
248 lcp_options *wo = &lcp_wantoptions[unit];
\r
249 lcp_options *go = &lcp_gotoptions[unit];
\r
250 #if PAP_SUPPORT || CHAP_SUPPORT
\r
251 lcp_options *ho = &lcp_hisoptions[unit];
\r
252 #endif /* PAP_SUPPORT || CHAP_SUPPORT */
\r
254 AUTHDEBUG((LOG_INFO, "link_established: %d\n", unit));
\r
256 * Tell higher-level protocols that LCP is up.
\r
258 for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {
\r
259 if (protp->protocol != PPP_LCP && protp->enabled_flag && protp->lowerup != NULL) {
\r
260 (*protp->lowerup)(unit);
\r
263 if (ppp_settings.auth_required && !(go->neg_chap || go->neg_upap)) {
\r
265 * We wanted the peer to authenticate itself, and it refused:
\r
266 * treat it as though it authenticated with PAP using a username
\r
267 * of "" and a password of "". If that's not OK, boot it out.
\r
269 if (!wo->neg_upap || !null_login(unit)) {
\r
270 AUTHDEBUG((LOG_WARNING, "peer refused to authenticate\n"));
\r
271 lcp_close(unit, "peer refused to authenticate");
\r
276 lcp_phase[unit] = PHASE_AUTHENTICATE;
\r
279 if (go->neg_chap) {
\r
280 ChapAuthPeer(unit, ppp_settings.our_name, go->chap_mdtype);
\r
283 #endif /* CHAP_SUPPORT */
\r
284 #if PAP_SUPPORT && CHAP_SUPPORT
\r
286 #endif /* PAP_SUPPORT && CHAP_SUPPORT */
\r
288 if (go->neg_upap) {
\r
289 upap_authpeer(unit);
\r
292 #endif /* PAP_SUPPORT */
\r
294 if (ho->neg_chap) {
\r
295 ChapAuthWithPeer(unit, ppp_settings.user, ho->chap_mdtype);
\r
296 auth |= CHAP_WITHPEER;
\r
298 #endif /* CHAP_SUPPORT */
\r
299 #if PAP_SUPPORT && CHAP_SUPPORT
\r
301 #endif /* PAP_SUPPORT && CHAP_SUPPORT */
\r
303 if (ho->neg_upap) {
\r
304 if (ppp_settings.passwd[0] == 0) {
\r
305 passwd_from_file = 1;
\r
306 if (!get_pap_passwd(unit, ppp_settings.user, ppp_settings.passwd)) {
\r
307 AUTHDEBUG((LOG_ERR, "No secret found for PAP login\n"));
\r
310 upap_authwithpeer(unit, ppp_settings.user, ppp_settings.passwd);
\r
311 auth |= PAP_WITHPEER;
\r
313 #endif /* PAP_SUPPORT */
\r
314 auth_pending[unit] = auth;
\r
317 network_phase(unit);
\r
322 * The peer has failed to authenticate himself using `protocol'.
\r
325 auth_peer_fail(int unit, u16_t protocol)
\r
327 LWIP_UNUSED_ARG(protocol);
\r
329 AUTHDEBUG((LOG_INFO, "auth_peer_fail: %d proto=%X\n", unit, protocol));
\r
331 * Authentication failure: take the link down
\r
333 lcp_close(unit, "Authentication failed");
\r
337 #if PAP_SUPPORT || CHAP_SUPPORT
\r
339 * The peer has been successfully authenticated using `protocol'.
\r
342 auth_peer_success(int unit, u16_t protocol, char *name, int namelen)
\r
346 AUTHDEBUG((LOG_INFO, "auth_peer_success: %d proto=%X\n", unit, protocol));
\r
347 switch (protocol) {
\r
355 AUTHDEBUG((LOG_WARNING, "auth_peer_success: unknown protocol %x\n", protocol));
\r
360 * Save the authenticated name of the peer for later.
\r
362 if (namelen > sizeof(peer_authname) - 1) {
\r
363 namelen = sizeof(peer_authname) - 1;
\r
365 BCOPY(name, peer_authname, namelen);
\r
366 peer_authname[namelen] = 0;
\r
369 * If there is no more authentication still to be done,
\r
370 * proceed to the network (or callback) phase.
\r
372 if ((auth_pending[unit] &= ~pbit) == 0) {
\r
373 network_phase(unit);
\r
378 * We have failed to authenticate ourselves to the peer using `protocol'.
\r
381 auth_withpeer_fail(int unit, u16_t protocol)
\r
383 int errCode = PPPERR_AUTHFAIL;
\r
385 LWIP_UNUSED_ARG(protocol);
\r
387 AUTHDEBUG((LOG_INFO, "auth_withpeer_fail: %d proto=%X\n", unit, protocol));
\r
388 if (passwd_from_file) {
\r
389 BZERO(ppp_settings.passwd, MAXSECRETLEN);
\r
392 * XXX Warning: the unit number indicates the interface which is
\r
393 * not necessarily the PPP connection. It works here as long
\r
394 * as we are only supporting PPP interfaces.
\r
396 pppIOCtl(unit, PPPCTLS_ERRCODE, &errCode);
\r
399 * We've failed to authenticate ourselves to our peer.
\r
400 * He'll probably take the link down, and there's not much
\r
401 * we can do except wait for that.
\r
406 * We have successfully authenticated ourselves with the peer using `protocol'.
\r
409 auth_withpeer_success(int unit, u16_t protocol)
\r
413 AUTHDEBUG((LOG_INFO, "auth_withpeer_success: %d proto=%X\n", unit, protocol));
\r
414 switch (protocol) {
\r
416 pbit = CHAP_WITHPEER;
\r
419 if (passwd_from_file) {
\r
420 BZERO(ppp_settings.passwd, MAXSECRETLEN);
\r
422 pbit = PAP_WITHPEER;
\r
425 AUTHDEBUG((LOG_WARNING, "auth_peer_success: unknown protocol %x\n", protocol));
\r
430 * If there is no more authentication still being done,
\r
431 * proceed to the network (or callback) phase.
\r
433 if ((auth_pending[unit] &= ~pbit) == 0) {
\r
434 network_phase(unit);
\r
437 #endif /* PAP_SUPPORT || CHAP_SUPPORT */
\r
441 * np_up - a network protocol has come up.
\r
444 np_up(int unit, u16_t proto)
\r
446 LWIP_UNUSED_ARG(unit);
\r
447 LWIP_UNUSED_ARG(proto);
\r
449 AUTHDEBUG((LOG_INFO, "np_up: %d proto=%X\n", unit, proto));
\r
450 if (num_np_up == 0) {
\r
451 AUTHDEBUG((LOG_INFO, "np_up: maxconnect=%d idle_time_limit=%d\n",ppp_settings.maxconnect,ppp_settings.idle_time_limit));
\r
453 * At this point we consider that the link has come up successfully.
\r
455 if (ppp_settings.idle_time_limit > 0) {
\r
456 TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit);
\r
460 * Set a timeout to close the connection once the maximum
\r
461 * connect time has expired.
\r
463 if (ppp_settings.maxconnect > 0) {
\r
464 TIMEOUT(connect_time_expired, 0, ppp_settings.maxconnect);
\r
471 * np_down - a network protocol has gone down.
\r
474 np_down(int unit, u16_t proto)
\r
476 LWIP_UNUSED_ARG(unit);
\r
477 LWIP_UNUSED_ARG(proto);
\r
479 AUTHDEBUG((LOG_INFO, "np_down: %d proto=%X\n", unit, proto));
\r
480 if (--num_np_up == 0 && ppp_settings.idle_time_limit > 0) {
\r
481 UNTIMEOUT(check_idle, NULL);
\r
486 * np_finished - a network protocol has finished using the link.
\r
489 np_finished(int unit, u16_t proto)
\r
491 LWIP_UNUSED_ARG(unit);
\r
492 LWIP_UNUSED_ARG(proto);
\r
494 AUTHDEBUG((LOG_INFO, "np_finished: %d proto=%X\n", unit, proto));
\r
495 if (--num_np_open <= 0) {
\r
496 /* no further use for the link: shut up shop. */
\r
497 lcp_close(0, "No network protocols running");
\r
502 * auth_reset - called when LCP is starting negotiations to recheck
\r
503 * authentication options, i.e. whether we have appropriate secrets
\r
504 * to use for authenticating ourselves and/or the peer.
\r
507 auth_reset(int unit)
\r
509 lcp_options *go = &lcp_gotoptions[unit];
\r
510 lcp_options *ao = &lcp_allowoptions[0];
\r
511 ipcp_options *ipwo = &ipcp_wantoptions[0];
\r
514 AUTHDEBUG((LOG_INFO, "auth_reset: %d\n", unit));
\r
515 ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(unit, NULL, NULL));
\r
516 ao->neg_chap = !ppp_settings.refuse_chap && ppp_settings.passwd[0] != 0 /*have_chap_secret(ppp_settings.user, ppp_settings.remote_name, (u32_t)0)*/;
\r
518 if (go->neg_upap && !have_pap_secret()) {
\r
521 if (go->neg_chap) {
\r
522 remote = ipwo->accept_remote? 0: ipwo->hisaddr;
\r
523 if (!have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote)) {
\r
531 * check_passwd - Check the user name and passwd against the PAP secrets
\r
532 * file. If requested, also check against the system password database,
\r
533 * and login the user if OK.
\r
536 * UPAP_AUTHNAK: Authentication failed.
\r
537 * UPAP_AUTHACK: Authentication succeeded.
\r
538 * In either case, msg points to an appropriate message.
\r
541 check_passwd( int unit, char *auser, int userlen, char *apasswd, int passwdlen, char **msg, int *msglen)
\r
544 LWIP_UNUSED_ARG(unit);
\r
545 LWIP_UNUSED_ARG(auser);
\r
546 LWIP_UNUSED_ARG(userlen);
\r
547 LWIP_UNUSED_ARG(apasswd);
\r
548 LWIP_UNUSED_ARG(passwdlen);
\r
549 LWIP_UNUSED_ARG(msglen);
\r
551 return UPAP_AUTHACK; /* XXX Assume all entries OK. */
\r
554 struct wordlist *addrs = NULL;
\r
555 char passwd[256], user[256];
\r
556 char secret[MAXWORDLEN];
\r
557 static u_short attempts = 0;
\r
560 * Make copies of apasswd and auser, then null-terminate them.
\r
562 BCOPY(apasswd, passwd, passwdlen);
\r
563 passwd[passwdlen] = '\0';
\r
564 BCOPY(auser, user, userlen);
\r
565 user[userlen] = '\0';
\r
568 /* XXX Validate user name and password. */
\r
569 ret = UPAP_AUTHACK; /* XXX Assume all entries OK. */
\r
571 if (ret == UPAP_AUTHNAK) {
\r
572 if (*msg == (char *) 0) {
\r
573 *msg = "Login incorrect";
\r
575 *msglen = strlen(*msg);
\r
577 * Frustrate passwd stealer programs.
\r
578 * Allow 10 tries, but start backing off after 3 (stolen from login).
\r
579 * On 10'th, drop the connection.
\r
581 if (attempts++ >= 10) {
\r
582 AUTHDEBUG((LOG_WARNING, "%d LOGIN FAILURES BY %s\n", attempts, user));
\r
583 /*ppp_panic("Excess Bad Logins");*/
\r
585 if (attempts > 3) {
\r
586 sys_msleep((attempts - 3) * 5);
\r
588 if (addrs != NULL) {
\r
589 free_wordlist(addrs);
\r
592 attempts = 0; /* Reset count */
\r
593 if (*msg == (char *) 0) {
\r
596 *msglen = strlen(*msg);
\r
597 set_allowed_addrs(unit, addrs);
\r
600 BZERO(passwd, sizeof(passwd));
\r
601 BZERO(secret, sizeof(secret));
\r
606 #endif /* PAP_SUPPORT */
\r
610 * auth_ip_addr - check whether the peer is authorized to use
\r
611 * a given IP address. Returns 1 if authorized, 0 otherwise.
\r
614 auth_ip_addr(int unit, u32_t addr)
\r
616 return ip_addr_check(addr, addresses[unit]);
\r
620 * bad_ip_adrs - return 1 if the IP address is one we don't want
\r
621 * to use, such as an address in the loopback net or a multicast address.
\r
622 * addr is in network byte order.
\r
625 bad_ip_adrs(u32_t addr)
\r
627 addr = ntohl(addr);
\r
628 return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET
\r
629 || IN_MULTICAST(addr) || IN_BADCLASS(addr);
\r
635 * get_secret - open the CHAP secret file and return the secret
\r
636 * for authenticating the given client on the given server.
\r
637 * (We could be either client or server).
\r
639 int get_secret( int unit, char *client, char *server, char *secret, int *secret_len, int save_addrs)
\r
643 struct wordlist *addrs;
\r
645 LWIP_UNUSED_ARG(unit);
\r
646 LWIP_UNUSED_ARG(server);
\r
647 LWIP_UNUSED_ARG(save_addrs);
\r
651 if(!client || !client[0] || strcmp(client, ppp_settings.user)) {
\r
655 len = strlen(ppp_settings.passwd);
\r
656 if (len > MAXSECRETLEN) {
\r
657 AUTHDEBUG((LOG_ERR, "Secret for %s on %s is too long\n", client, server));
\r
658 len = MAXSECRETLEN;
\r
661 BCOPY(ppp_settings.passwd, secret, len);
\r
667 struct wordlist *addrs;
\r
668 char secbuf[MAXWORDLEN];
\r
673 /* XXX Find secret. */
\r
679 set_allowed_addrs(unit, addrs);
\r
682 len = strlen(secbuf);
\r
683 if (len > MAXSECRETLEN) {
\r
684 AUTHDEBUG((LOG_ERR, "Secret for %s on %s is too long\n", client, server));
\r
685 len = MAXSECRETLEN;
\r
688 BCOPY(secbuf, secret, len);
\r
689 BZERO(secbuf, sizeof(secbuf));
\r
695 #endif /* CHAP_SUPPORT */
\r
700 * auth_check_options - called to check authentication options.
\r
703 auth_check_options(void)
\r
705 lcp_options *wo = &lcp_wantoptions[0];
\r
707 ipcp_options *ipwo = &ipcp_wantoptions[0];
\r
710 /* Default our_name to hostname, and user to our_name */
\r
711 if (ppp_settings.our_name[0] == 0 || ppp_settings.usehostname) {
\r
712 strcpy(ppp_settings.our_name, ppp_settings.hostname);
\r
715 if (ppp_settings.user[0] == 0) {
\r
716 strcpy(ppp_settings.user, ppp_settings.our_name);
\r
719 /* If authentication is required, ask peer for CHAP or PAP. */
\r
720 if (ppp_settings.auth_required && !wo->neg_chap && !wo->neg_upap) {
\r
726 * Check whether we have appropriate secrets to use
\r
727 * to authenticate the peer.
\r
729 can_auth = wo->neg_upap && have_pap_secret();
\r
730 if (!can_auth && wo->neg_chap) {
\r
731 remote = ipwo->accept_remote? 0: ipwo->hisaddr;
\r
732 can_auth = have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote);
\r
735 if (ppp_settings.auth_required && !can_auth) {
\r
736 ppp_panic("No auth secret");
\r
742 /**********************************/
\r
743 /*** LOCAL FUNCTION DEFINITIONS ***/
\r
744 /**********************************/
\r
746 * Proceed to the network phase.
\r
749 network_phase(int unit)
\r
752 struct protent *protp;
\r
753 lcp_options *go = &lcp_gotoptions[unit];
\r
756 * If the peer had to authenticate, run the auth-up script now.
\r
758 if ((go->neg_chap || go->neg_upap) && !did_authup) {
\r
759 /* XXX Do setup for peer authentication. */
\r
765 * If we negotiated callback, do it now.
\r
767 if (go->neg_cbcp) {
\r
768 lcp_phase[unit] = PHASE_CALLBACK;
\r
769 (*cbcp_protent.open)(unit);
\r
772 #endif /* CBCP_SUPPORT */
\r
774 lcp_phase[unit] = PHASE_NETWORK;
\r
775 for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {
\r
776 if (protp->protocol < 0xC000 && protp->enabled_flag && protp->open != NULL) {
\r
777 (*protp->open)(unit);
\r
778 if (protp->protocol != PPP_CCP) {
\r
784 if (num_np_open == 0) {
\r
785 /* nothing to do */
\r
786 lcp_close(0, "No network protocols running");
\r
791 * check_idle - check whether the link has been idle for long
\r
792 * enough that we can shut it down.
\r
795 check_idle(void *arg)
\r
797 struct ppp_idle idle;
\r
800 LWIP_UNUSED_ARG(arg);
\r
801 if (!get_idle_time(0, &idle)) {
\r
804 itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle);
\r
805 if (itime >= ppp_settings.idle_time_limit) {
\r
806 /* link is idle: shut it down. */
\r
807 AUTHDEBUG((LOG_INFO, "Terminating connection due to lack of activity.\n"));
\r
808 lcp_close(0, "Link inactive");
\r
810 TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit - itime);
\r
815 * connect_time_expired - log a message and close the connection.
\r
818 connect_time_expired(void *arg)
\r
820 LWIP_UNUSED_ARG(arg);
\r
822 AUTHDEBUG((LOG_INFO, "Connect time expired\n"));
\r
823 lcp_close(0, "Connect time expired"); /* Close connection */
\r
828 * login - Check the user name and password against the system
\r
829 * password database, and login the user if OK.
\r
832 * UPAP_AUTHNAK: Login failed.
\r
833 * UPAP_AUTHACK: Login succeeded.
\r
834 * In either case, msg points to an appropriate message.
\r
837 login(char *user, char *passwd, char **msg, int *msglen)
\r
839 /* XXX Fail until we decide that we want to support logins. */
\r
840 return (UPAP_AUTHNAK);
\r
845 * logout - Logout the user.
\r
854 * null_login - Check if a username of "" and a password of "" are
\r
855 * acceptable, and iff so, set the list of acceptable IP addresses
\r
859 null_login(int unit)
\r
861 LWIP_UNUSED_ARG(unit);
\r
862 /* XXX Fail until we decide that we want to support logins. */
\r
867 * get_pap_passwd - get a password for authenticating ourselves with
\r
868 * our peer using PAP. Returns 1 on success, 0 if no suitable password
\r
872 get_pap_passwd(int unit, char *user, char *passwd)
\r
874 LWIP_UNUSED_ARG(unit);
\r
875 /* normally we would reject PAP if no password is provided,
\r
876 but this causes problems with some providers (like CHT in Taiwan)
\r
877 who incorrectly request PAP and expect a bogus/empty password, so
\r
878 always provide a default user/passwd of "none"/"none"
\r
881 strcpy(user, "none");
\r
884 strcpy(passwd, "none");
\r
890 * have_pap_secret - check whether we have a PAP file with any
\r
891 * secrets that we could possibly use for authenticating the peer.
\r
894 have_pap_secret(void)
\r
896 /* XXX Fail until we set up our passwords. */
\r
901 * have_chap_secret - check whether we have a CHAP file with a
\r
902 * secret that we could possibly use for authenticating `client'
\r
903 * on `server'. Either can be the null string, meaning we don't
\r
904 * know the identity yet.
\r
907 have_chap_secret(char *client, char *server, u32_t remote)
\r
909 LWIP_UNUSED_ARG(client);
\r
910 LWIP_UNUSED_ARG(server);
\r
911 LWIP_UNUSED_ARG(remote);
\r
912 /* XXX Fail until we set up our passwords. */
\r
916 #if 0 /* PAP_SUPPORT || CHAP_SUPPORT */
\r
918 * set_allowed_addrs() - set the list of allowed addresses.
\r
921 set_allowed_addrs(int unit, struct wordlist *addrs)
\r
923 if (addresses[unit] != NULL) {
\r
924 free_wordlist(addresses[unit]);
\r
926 addresses[unit] = addrs;
\r
930 * If there's only one authorized address we might as well
\r
931 * ask our peer for that one right away
\r
933 if (addrs != NULL && addrs->next == NULL) {
\r
934 char *p = addrs->word;
\r
935 struct ipcp_options *wo = &ipcp_wantoptions[unit];
\r
937 struct hostent *hp;
\r
939 if (wo->hisaddr == 0 && *p != '!' && *p != '-' && strchr(p, '/') == NULL) {
\r
940 hp = gethostbyname(p);
\r
941 if (hp != NULL && hp->h_addrtype == AF_INET) {
\r
942 a = *(u32_t *)hp->h_addr;
\r
946 if (a != (u32_t) -1) {
\r
953 #endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */
\r
956 ip_addr_check(u32_t addr, struct wordlist *addrs)
\r
958 /* don't allow loopback or multicast address */
\r
959 if (bad_ip_adrs(addr)) {
\r
963 if (addrs == NULL) {
\r
964 return !ppp_settings.auth_required; /* no addresses authorized */
\r
967 /* XXX All other addresses allowed. */
\r
971 #if 0 /* PAP_SUPPORT || CHAP_SUPPORT */
\r
973 * free_wordlist - release memory allocated for a wordlist.
\r
976 free_wordlist(struct wordlist *wp)
\r
978 struct wordlist *next;
\r
980 while (wp != NULL) {
\r
986 #endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */
\r
988 #endif /* PPP_SUPPORT */
\r