source: rtems/cpukit/pppd/auth.c @ d0950ad

4.104.114.84.9
Last change on this file since d0950ad was d0950ad, checked in by Joel Sherrill <joel.sherrill@…>, on Nov 30, 1999 at 10:12:50 PM

Added port of ppp-2.3.5 from Tomasz Domin <dot@…> of ComArch? SA.
Tomasz only tested this on the mpc823.

The official site for the original source for this PPP implementation is:

ftp://cs.anu.edu.au/pub/software/ppp

NOTE: As of 11/30/1999, the current version of this source is 2.3.10.

  • Property mode set to 100644
File size: 19.1 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#ifndef lint
36/* static char rcsid[] = "$Id$"; */
37#endif
38
39#include <stdio.h>
40#include <stddef.h>
41#include <stdlib.h> 
42#include <unistd.h>
43#include <syslog.h>
44#include <pwd.h>
45#include <string.h>
46#include <sys/types.h>
47#include <sys/stat.h>
48#include <sys/socket.h>
49
50#include <fcntl.h>
51#if defined(_PATH_LASTLOG) && defined(_linux_)
52#include <lastlog.h>
53#endif
54
55#include <netdb.h>
56#include <netinet/in.h>
57#include <arpa/inet.h>
58/* #include <stbconfig.h> */
59
60#include "pppd.h"
61#include "fsm.h"
62#include "lcp.h"
63#include "ipcp.h"
64#include "upap.h"
65#include "chap.h"
66#ifdef CBCP_SUPPORT
67#include "cbcp.h"
68#endif
69#include "pathnames.h"
70
71/* Used for storing a sequence of words.  Usually malloced. */
72struct wordlist {
73    struct wordlist     *next;
74    char                word[1];
75};
76
77/* Bits in scan_authfile return value */
78#define NONWILD_SERVER  1
79#define NONWILD_CLIENT  2
80
81#define ISWILD(word)    (word[0] == '*' && word[1] == 0)
82
83#define FALSE   0
84#define TRUE    1
85
86/* The name by which the peer authenticated itself to us. */
87char peer_authname[MAXNAMELEN];
88
89/* Records which authentication operations haven't completed yet. */
90static int auth_pending[NUM_PPP];
91
92/* Set if we have successfully called plogin() */
93static int logged_in;
94
95/* Set if we have run the /etc/ppp/auth-up script. */
96static int did_authup;
97
98/* List of addresses which the peer may use. */
99static struct wordlist *addresses[NUM_PPP];
100
101/* Number of network protocols which we have opened. */
102static int num_np_open;
103
104/* Number of network protocols which have come up. */
105static int num_np_up;
106
107/* Set if we got the contents of passwd[] from the pap-secrets file. */
108static int passwd_from_file;
109
110/* Bits in auth_pending[] */
111#define PAP_WITHPEER    1
112#define PAP_PEER        2
113#define CHAP_WITHPEER   4
114#define CHAP_PEER       8
115
116extern char *crypt __P((const char *, const char *));
117
118/* Prototypes for procedures local to this file. */
119
120static void network_phase __P((int));
121static void check_idle __P((void *));
122static void connect_time_expired __P((void *));
123static int  plogin __P((char *, char *, char **, int *));
124static void plogout __P((void));
125static int  null_login __P((int));
126static int  get_pap_passwd __P((char *));
127static int  have_pap_secret __P((void));
128static int  have_chap_secret __P((char *, char *, u_int32_t));
129static int  ip_addr_check __P((u_int32_t, struct wordlist *));
130static int  scan_authfile __P((FILE *, char *, char *, u_int32_t, char *,
131                               struct wordlist **, char *));
132static void free_wordlist __P((struct wordlist *));
133static void auth_script __P((char *));
134static void set_allowed_addrs __P((int, struct wordlist *));
135
136/*
137 * An Open on LCP has requested a change from Dead to Establish phase.
138 * Do what's necessary to bring the physical layer up.
139 */
140void
141link_required(unit)
142    int unit;
143{
144}
145
146/*
147 * LCP has terminated the link; go to the Dead phase and take the
148 * physical layer down.
149 */
150void
151link_terminated(unit)
152    int unit;
153{
154    if (phase == PHASE_DEAD)
155        return;
156    if (logged_in)
157        plogout();
158    phase = PHASE_DEAD;
159    syslog(LOG_NOTICE, "Connection terminated.");
160}
161
162/*
163 * LCP has gone down; it will either die or try to re-establish.
164 */
165void
166link_down(unit)
167    int unit;
168{
169    int i;
170    struct protent *protp;
171
172        did_authup = 0;
173    for (i = 0; (protp = protocols[i]) != NULL; ++i) {
174        if (!protp->enabled_flag)
175            continue;
176        if (protp->protocol != PPP_LCP && protp->lowerdown != NULL)
177            (*protp->lowerdown)(unit);
178        if (protp->protocol < 0xC000 && protp->close != NULL)
179            (*protp->close)(unit, "LCP down");
180    }
181    num_np_open = 0;
182    num_np_up = 0;
183    if (phase != PHASE_DEAD)
184        phase = PHASE_TERMINATE;
185}
186
187/*
188 * The link is established.
189 * Proceed to the Dead, Authenticate or Network phase as appropriate.
190 */
191void
192link_established(unit)
193    int unit;
194{
195    int auth;
196    lcp_options *wo = &lcp_wantoptions[unit];
197    lcp_options *go = &lcp_gotoptions[unit];
198    lcp_options *ho = &lcp_hisoptions[unit];
199    int i;
200    struct protent *protp;
201
202    /*
203     * Tell higher-level protocols that LCP is up.
204     */
205    for (i = 0; (protp = protocols[i]) != NULL; ++i)
206        if (protp->protocol != PPP_LCP && protp->enabled_flag
207            && protp->lowerup != NULL)
208            (*protp->lowerup)(unit);
209
210    if (auth_required && !(go->neg_chap || go->neg_upap)) {
211        /*
212         * We wanted the peer to authenticate itself, and it refused:
213         * treat it as though it authenticated with PAP using a username
214         * of "" and a password of "".  If that's not OK, boot it out.
215         */
216        if (!wo->neg_upap || !null_login(unit)) {
217            lcp_close(unit, "peer refused to authenticate");
218            return;
219        }
220    }
221
222    phase = PHASE_AUTHENTICATE;
223    auth = 0;
224    if (go->neg_chap) {
225        ChapAuthPeer(unit, our_name, go->chap_mdtype);
226        auth |= CHAP_PEER;
227    } else if (go->neg_upap) {
228        upap_authpeer(unit);
229        auth |= PAP_PEER;
230    }
231    if (ho->neg_chap) {
232        ChapAuthWithPeer(unit, user, ho->chap_mdtype);
233        auth |= CHAP_WITHPEER;
234    } else if (ho->neg_upap) {
235        if (passwd[0] == 0) {
236            passwd_from_file = 1;
237            get_pap_passwd(passwd);
238        }
239        upap_authwithpeer(unit, user, passwd);
240        auth |= PAP_WITHPEER;
241    }
242    auth_pending[unit] = auth;
243
244    if (!auth)
245        network_phase(unit);
246}
247
248/*
249 * Proceed to the network phase.
250 */
251static void
252network_phase(unit)
253    int unit;
254{
255    int i;
256    struct protent *protp;
257    lcp_options *go = &lcp_gotoptions[unit];
258
259    /*
260     * If the peer had to authenticate, run the auth-up script now.
261     */
262    if ((go->neg_chap || go->neg_upap) && !did_authup) {
263        auth_script(_PATH_AUTHUP);
264        did_authup = 1;
265    }
266
267#ifdef CBCP_SUPPORT
268    /*
269     * If we negotiated callback, do it now.
270     */
271    if (go->neg_cbcp) {
272        phase = PHASE_CALLBACK;
273        (*cbcp_protent.open)(unit);
274        return;
275    }
276#endif
277
278    phase = PHASE_NETWORK;
279
280    for (i = 0; (protp = protocols[i]) != NULL; ++i)
281        if (protp->protocol < 0xC000 && protp->enabled_flag
282            && protp->open != NULL) {
283            (*protp->open)(unit);
284            if (protp->protocol != PPP_CCP)
285                ++num_np_open;
286        }
287
288    if (num_np_open == 0)
289        /* nothing to do */
290        lcp_close(0, "No network protocols running");
291}
292
293/*
294 * The peer has failed to authenticate himself using `protocol'.
295 */
296void
297auth_peer_fail(unit, protocol)
298    int unit, protocol;
299{
300    /*
301     * Authentication failure: take the link down
302     */
303    lcp_close(unit, "Authentication failed");
304}
305
306/*
307 * The peer has been successfully authenticated using `protocol'.
308 */
309void
310auth_peer_success(unit, protocol, name, namelen)
311    int unit, protocol;
312    char *name;
313    int namelen;
314{
315    int bit;
316
317    switch (protocol) {
318    case PPP_CHAP:
319        bit = CHAP_PEER;
320        break;
321    case PPP_PAP:
322        bit = PAP_PEER;
323        break;
324    default:
325        syslog(LOG_WARNING, "auth_peer_success: unknown protocol %x",
326               protocol);
327        return;
328    }
329
330    /*
331     * Save the authenticated name of the peer for later.
332     */
333    if (namelen > sizeof(peer_authname) - 1)
334        namelen = sizeof(peer_authname) - 1;
335    BCOPY(name, peer_authname, namelen);
336    peer_authname[namelen] = 0;
337    /*
338     * If there is no more authentication still to be done,
339     * proceed to the network (or callback) phase.
340     */
341    if ((auth_pending[unit] &= ~bit) == 0)
342        network_phase(unit);
343}
344
345/*
346 * We have failed to authenticate ourselves to the peer using `protocol'.
347 */
348void
349auth_withpeer_fail(unit, protocol)
350    int unit, protocol;
351{
352    if (passwd_from_file)
353        BZERO(passwd, MAXSECRETLEN);
354    /*
355     * We've failed to authenticate ourselves to our peer.
356     * He'll probably take the link down, and there's not much
357     * we can do except wait for that.
358     */
359}
360
361/*
362 * We have successfully authenticated ourselves with the peer using `protocol'.
363 */
364void
365auth_withpeer_success(unit, protocol)
366    int unit, protocol;
367{
368    int bit;
369
370    switch (protocol) {
371    case PPP_CHAP:
372        bit = CHAP_WITHPEER;
373        break;
374    case PPP_PAP:
375        if (passwd_from_file)
376            BZERO(passwd, MAXSECRETLEN);
377        bit = PAP_WITHPEER;
378        break;
379    default:
380
381        bit = 0;
382    }
383
384    /*
385     * If there is no more authentication still being done,
386     * proceed to the network (or callback) phase.
387     */
388    if ((auth_pending[unit] &= ~bit) == 0)
389        network_phase(unit);
390}
391
392
393/*
394 * np_up - a network protocol has come up.
395 */
396void
397np_up(unit, proto)
398    int unit, proto;
399{
400    if (num_np_up == 0) {
401        /*
402         * At this point we consider that the link has come up successfully.
403         */
404        need_holdoff = 0;
405
406        if (idle_time_limit > 0)
407            TIMEOUT(check_idle, NULL, idle_time_limit);
408
409        /*
410         * Set a timeout to close the connection once the maximum
411         * connect time has expired.
412         */
413        if (maxconnect > 0)
414            TIMEOUT(connect_time_expired, 0, maxconnect);
415
416        /*
417         * Detach now, if the updetach option was given.
418         */
419        if (nodetach == -1)
420            detach();
421    }
422    ++num_np_up;
423}
424
425/*
426 * np_down - a network protocol has gone down.
427 */
428void
429np_down(unit, proto)
430    int unit, proto;
431{
432    if (--num_np_up == 0 && idle_time_limit > 0) {
433        UNTIMEOUT(check_idle, NULL);
434    }
435}
436
437/*
438 * np_finished - a network protocol has finished using the link.
439 */
440void
441np_finished(unit, proto)
442    int unit, proto;
443{
444    if (--num_np_open <= 0) {
445        /* no further use for the link: shut up shop. */
446        lcp_close(0, "No network protocols running");
447    }
448}
449
450/*
451 * check_idle - check whether the link has been idle for long
452 * enough that we can shut it down.
453 */
454static void
455check_idle(arg)
456     void *arg;
457{
458    struct ppp_idle idle;
459    time_t itime;
460
461    if (!get_idle_time(0, &idle))
462        return;
463    itime = MIN(idle.xmit_idle, idle.recv_idle);
464    if (itime >= idle_time_limit) {
465        /* link is idle: shut it down. */
466        syslog(LOG_INFO, "Terminating connection due to lack of activity.");
467        lcp_close(0, "Link inactive");
468    } else {
469        TIMEOUT(check_idle, NULL, idle_time_limit - itime);
470    }
471}
472
473/*
474 * connect_time_expired - log a message and close the connection.
475 */
476static void
477connect_time_expired(arg)
478    void *arg;
479{
480    syslog(LOG_INFO, "Connect time expired");
481    lcp_close(0, "Connect time expired");       /* Close connection */
482}
483
484/*
485 * auth_check_options - called to check authentication options.
486 */
487void
488auth_check_options()
489{
490    lcp_options *wo = &lcp_wantoptions[0];
491    int can_auth;
492    ipcp_options *ipwo = &ipcp_wantoptions[0];
493    u_int32_t remote;
494
495    /* Default our_name to hostname, and user to our_name */
496    if (our_name[0] == 0 || usehostname)
497        strcpy(our_name, hostname);
498    if (user[0] == 0)
499        strcpy(user, our_name);
500
501    /* If authentication is required, ask peer for CHAP or PAP. */
502    if (auth_required && !wo->neg_chap && !wo->neg_upap) {
503        wo->neg_chap = 1;
504        wo->neg_upap = 1;
505    }
506
507    /*
508     * Check whether we have appropriate secrets to use
509     * to authenticate the peer.
510     */
511    can_auth = wo->neg_upap && (uselogin || have_pap_secret());
512    if (!can_auth && wo->neg_chap) {
513        remote = ipwo->accept_remote? 0: ipwo->hisaddr;
514        can_auth = have_chap_secret(remote_name, our_name, remote);
515    }
516
517    if (auth_required && !can_auth) {
518        option_error("peer authentication required but no suitable secret(s) found\n");
519        if (remote_name[0] == 0)
520            option_error("for authenticating any peer to us (%s)\n", our_name);
521        else
522            option_error("for authenticating peer %s to us (%s)\n",
523                         remote_name, our_name);
524        exit(1);
525    }
526
527    /*
528     * Check whether the user tried to override certain values
529     * set by root.
530     */
531    if (!auth_required && auth_req_info.priv > 0) {
532        if (!default_device && devnam_info.priv == 0) {
533            option_error("can't override device name when noauth option used");
534            exit(1);
535        }
536        if ((connector != NULL && connector_info.priv == 0)
537            || (disconnector != NULL && disconnector_info.priv == 0)
538            || (welcomer != NULL && welcomer_info.priv == 0)) {
539            option_error("can't override connect, disconnect or welcome");
540            option_error("option values when noauth option used");
541            exit(1);
542        }
543    }
544}
545
546/*
547 * auth_reset - called when LCP is starting negotiations to recheck
548 * authentication options, i.e. whether we have appropriate secrets
549 * to use for authenticating ourselves and/or the peer.
550 */
551void
552auth_reset(unit)
553    int unit;
554{
555    lcp_options *go = &lcp_gotoptions[unit];
556    lcp_options *ao = &lcp_allowoptions[0];
557    ipcp_options *ipwo = &ipcp_wantoptions[0];
558    u_int32_t remote;
559
560    ao->neg_upap = !refuse_pap /*&& (passwd[0] != 0 || get_pap_passwd(NULL))*/;
561    ao->neg_chap = !refuse_chap
562        && have_chap_secret(user, remote_name, (u_int32_t)0);
563
564    if (go->neg_upap && !uselogin && !have_pap_secret())
565        go->neg_upap = 0;
566    if (go->neg_chap) {
567        remote = ipwo->accept_remote? 0: ipwo->hisaddr;
568        if (!have_chap_secret(remote_name, our_name, remote))
569            go->neg_chap = 0;
570    }
571}
572
573
574/*
575 * check_passwd - Check the user name and passwd against the PAP secrets
576 * file.  If requested, also check against the system password database,
577 * and login the user if OK.
578 *
579 * returns:
580 *      UPAP_AUTHNAK: Authentication failed.
581 *      UPAP_AUTHACK: Authentication succeeded.
582 * In either case, msg points to an appropriate message.
583 */
584int
585check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen)
586    int unit;
587    char *auser;
588    int userlen;
589    char *apasswd;
590    int passwdlen;
591    char **msg;
592    int *msglen;
593{
594
595
596    return UPAP_AUTHNAK;
597}
598
599
600/*
601 * plogin - Check the user name and password against the system
602 * password database, and login the user if OK.
603 *
604 * returns:
605 *      UPAP_AUTHNAK: Login failed.
606 *      UPAP_AUTHACK: Login succeeded.
607 * In either case, msg points to an appropriate message.
608 */
609
610static int
611plogin(user, passwd, msg, msglen)
612    char *user;
613    char *passwd;
614    char **msg;
615    int *msglen;
616{
617    syslog(LOG_INFO, "user %s logged in", user);
618    logged_in = TRUE;
619
620    return (UPAP_AUTHACK);
621}
622
623/*
624 * plogout - Logout the user.
625 */
626static void
627plogout()
628{
629
630    logged_in = FALSE;
631}
632
633
634/*
635 * null_login - Check if a username of "" and a password of "" are
636 * acceptable, and iff so, set the list of acceptable IP addresses
637 * and return 1.
638 */
639static int
640null_login(unit)
641    int unit;
642{
643    return 1;
644}
645
646
647/*
648 * get_pap_passwd - get a password for authenticating ourselves with
649 * our peer using PAP.  Returns 1 on success, 0 if no suitable password
650 * could be found.
651 */
652
653static int
654get_pap_passwd(passwd)
655    char *passwd;
656{
657#if 0
658/* XXX PPPConfiguration */
659        GlobalSystemStatus *stat;
660        stat=LockSTBSystemParam();
661        strncpy(passwd,  stat->PPP_Password, MAXSECRETLEN);
662        UnlockSTBSystemParam();
663#endif
664    return 1;
665}
666
667
668/*
669 * have_pap_secret - check whether we have a PAP file with any
670 * secrets that we could possibly use for authenticating the peer.
671 */
672static int
673have_pap_secret()
674{
675    return 1;
676}
677
678
679/*
680 * have_chap_secret - check whether we have a CHAP file with a
681 * secret that we could possibly use for authenticating `client'
682 * on `server'.  Either can be the null string, meaning we don't
683 * know the identity yet.
684 */
685static int
686have_chap_secret(client, server, remote)
687    char *client;
688    char *server;
689    u_int32_t remote;
690{
691
692    return 1;
693}
694
695
696/*
697 * get_secret - open the CHAP secret file and return the secret
698 * for authenticating the given client on the given server.
699 * (We could be either client or server).
700 */
701int
702get_secret(unit, client, server, secret, secret_len, save_addrs)
703    int unit;
704    char *client;
705    char *server;
706    char *secret;
707    int *secret_len;
708    int save_addrs;
709{
710#if 0
711/* XXX PPPConfiguration */
712    int len;
713        GlobalSystemStatus *stat;
714        stat=LockSTBSystemParam();
715    len=strlen(stat->PPP_Password);
716    strcpy( secret,stat->PPP_Password);
717        UnlockSTBSystemParam();
718
719    *secret_len = len;
720#endif
721    return 1;
722}
723
724/*
725 * set_allowed_addrs() - set the list of allowed addresses.
726 */
727static void
728set_allowed_addrs(unit, addrs)
729    int unit;
730    struct wordlist *addrs;
731{
732
733}
734
735/*
736 * auth_ip_addr - check whether the peer is authorized to use
737 * a given IP address.  Returns 1 if authorized, 0 otherwise.
738 */
739int
740auth_ip_addr(unit, addr)
741    int unit;
742    u_int32_t addr;
743{
744    return ip_addr_check(addr, addresses[unit]);
745}
746
747static int
748ip_addr_check(addr, addrs)
749    u_int32_t addr;
750    struct wordlist *addrs;
751{
752#if 0
753    u_int32_t a, mask, ah;
754    int accept;
755    char *ptr_word, *ptr_mask;
756    struct hostent *hp;
757    struct netent *np;
758#endif
759
760    /* don't allow loopback or multicast address */
761    if (bad_ip_adrs(addr))
762        return 0;
763
764    if (addrs == NULL)
765        return !auth_required;          /* no addresses authorized */
766
767        return 1;
768}
769
770/*
771 * bad_ip_adrs - return 1 if the IP address is one we don't want
772 * to use, such as an address in the loopback net or a multicast address.
773 * addr is in network byte order.
774 */
775int
776bad_ip_adrs(addr)
777    u_int32_t addr;
778{
779    addr = ntohl(addr);
780    return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET
781        || IN_MULTICAST(addr) || IN_BADCLASS(addr);
782}
783
784/*
785 * check_access - complain if a secret file has too-liberal permissions.
786 */
787void
788check_access(f, filename)
789    FILE *f;
790    char *filename;
791{
792
793}
794
795
796/*
797 * scan_authfile - Scan an authorization file for a secret suitable
798 * for authenticating `client' on `server'.  The return value is -1
799 * if no secret is found, otherwise >= 0.  The return value has
800 * NONWILD_CLIENT set if the secret didn't have "*" for the client, and
801 * NONWILD_SERVER set if the secret didn't have "*" for the server.
802 * Any following words on the line (i.e. address authorization
803 * info) are placed in a wordlist and returned in *addrs. 
804 */
805static int
806scan_authfile(f, client, server, ipaddr, secret, addrs, filename)
807    FILE *f;
808    char *client;
809    char *server;
810    u_int32_t ipaddr;
811    char *secret;
812    struct wordlist **addrs;
813    char *filename;
814{
815
816    return -1;
817}
818
819/*
820 * free_wordlist - release memory allocated for a wordlist.
821 */
822static void
823free_wordlist(wp)
824    struct wordlist *wp;
825{
826    struct wordlist *next;
827
828    while (wp != NULL) {
829        next = wp->next;
830        free(wp);
831        wp = next;
832    }
833}
834
835/*
836 * auth_script - execute a script with arguments
837 * interface-name peer-name real-user tty speed
838 */
839static void
840auth_script(script)
841    char *script;
842{
843}
Note: See TracBrowser for help on using the repository browser.