auth.c

来自「eCos操作系统源码」· C语言 代码 · 共 893 行 · 第 1/2 页

C
893
字号
//==========================================================================////      src/auth.c////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Portions created by Nick Garnett are// Copyright (C) 2003 eCosCentric Ltd.//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//####BSDCOPYRIGHTBEGIN####//// -------------------------------------------//// Portions of this software may have been derived from OpenBSD, // FreeBSD or other sources, and are covered by the appropriate// copyright disclaimers included herein.//// -------------------------------------------////####BSDCOPYRIGHTEND####//==========================================================================/* * auth.c - PPP authentication and phase control. * * Copyright (c) 1993 The Australian National University. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the Australian National University.  The name of the University * may not be used to endorse or promote products derived from this * software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Copyright (c) 1989 Carnegie Mellon University. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by Carnegie Mellon University.  The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */#ifndef lint//static char rcsid[] = "$FreeBSD: src/usr.sbin/pppd/auth.c,v 1.24.2.1 2000/12/11 01:03:37 obrien Exp $";#endif#include <stdio.h>#include <stddef.h>#include <stdlib.h>#include <unistd.h>#include <cyg/ppp/syslog.h>#ifndef __ECOS#include <paths.h>#endif//#include <pwd.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/socket.h>//#include <utmp.h>#include <fcntl.h>#if defined(_PATH_LASTLOG) && defined(_linux_)#include <lastlog.h>#endif#include <netdb.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/time.h>//#include <utmp.h>#ifdef USE_PAM#include <security/pam_appl.h>#endif#ifdef HAS_SHADOW#include <shadow.h>#ifndef PW_PPP#define PW_PPP PW_LOGIN#endif#endif#include "cyg/ppp/pppd.h"#include "cyg/ppp/fsm.h"#include "cyg/ppp/lcp.h"#include "cyg/ppp/ipcp.h"#include "cyg/ppp/upap.h"#include "cyg/ppp/chap.h"#ifdef CBCP_SUPPORT#include "cyg/ppp/cbcp.h"#endif//#include "cyg/ppp/pathnames.h"/* Used for storing a sequence of words.  Usually malloced. */struct wordlist {    struct wordlist	*next;    char		word[1];};/* Bits in scan_authfile return value */#define NONWILD_SERVER	1#define NONWILD_CLIENT	2#define ISWILD(word)	(word[0] == '*' && word[1] == 0)#define FALSE	0#define TRUE	1/* The name by which the peer authenticated itself to us. */char peer_authname[MAXNAMELEN];/* Records which authentication operations haven't completed yet. */static int auth_pending[NUM_PPP];/* Set if we have successfully called plogin() *///static int logged_in;/* Set if not wild or blank *///static int non_wildclient;/* Set if we have run the /etc/ppp/auth-up script. *///static int did_authup;/* List of addresses which the peer may use. */static struct wordlist *addresses[NUM_PPP];/* Number of network protocols which we have opened. */static int num_np_open;/* Number of network protocols which have come up. */static int num_np_up;/* Set if we got the contents of passwd[] from the pap-secrets file. */static int passwd_from_file;/* Bits in auth_pending[] */#define PAP_WITHPEER	1#define PAP_PEER	2#define CHAP_WITHPEER	4#define CHAP_PEER	8extern char *crypt __P((const char *, const char *));/* Prototypes for procedures local to this file. */static void network_phase __P((int));static void check_idle __P((void *));static void connect_time_expired __P((void *));static int  null_login __P((int));static int  get_pap_passwd __P((char *));static int  have_pap_secret __P((void));static int  have_chap_secret __P((char *, char *, u_int32_t));static int  ip_addr_check __P((u_int32_t, struct wordlist *));static void auth_set_ip_addr __P((int));/* * An Open on LCP has requested a change from Dead to Establish phase. * Do what's necessary to bring the physical layer up. */voidlink_required(unit)    int unit;{}/* * LCP has terminated the link; go to the Dead phase and take the * physical layer down. */voidlink_terminated(unit)    int unit;{    extern	time_t	etime, stime;    extern	int	minutes;db_printf("%s()\n",__PRETTY_FUNCTION__);        if (phase == PHASE_DEAD)	return;    phase = PHASE_DEAD;    etime = time((time_t *) NULL);    minutes = (etime-stime)/60;    syslog(LOG_NOTICE, "Connection terminated, connected for %d minutes\n",	minutes > 1 ? minutes : 1);}/* * LCP has gone down; it will either die or try to re-establish. */voidlink_down(unit)    int unit;{    int i;    struct protent *protp;db_printf("%s()\n",__PRETTY_FUNCTION__);    for (i = 0; (protp = protocols[i]) != NULL; ++i) {	if (!protp->enabled_flag)	    continue;        if (protp->protocol != PPP_LCP && protp->lowerdown != NULL)	    (*protp->lowerdown)(unit);        if (protp->protocol < 0xC000 && protp->close != NULL)	    (*protp->close)(unit, "LCP down");    }    num_np_open = 0;    num_np_up = 0;    if (phase != PHASE_DEAD)	phase = PHASE_TERMINATE;}/* * The link is established. * Proceed to the Dead, Authenticate or Network phase as appropriate. */voidlink_established(unit)    int unit;{    int auth;    lcp_options *wo = &lcp_wantoptions[unit];    lcp_options *go = &lcp_gotoptions[unit];    lcp_options *ho = &lcp_hisoptions[unit];    int i;    struct protent *protp;    /*     * 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 (auth_required && !(go->neg_chap || go->neg_upap)) {	/*	 * We wanted the peer to authenticate itself, and it refused:	 * treat it as though it authenticated with PAP using a username	 * of "" and a password of "".  If that's not OK, boot it out.	 */	if (!wo->neg_upap || !null_login(unit)) {	    syslog(LOG_WARNING, "peer refused to authenticate");	    lcp_close(unit, "peer refused to authenticate");	    return;	}    }    phase = PHASE_AUTHENTICATE;    auth = 0;    if (go->neg_chap) {	ChapAuthPeer(unit, our_name, go->chap_mdtype);	auth |= CHAP_PEER;    } else if (go->neg_upap) {	upap_authpeer(unit);	auth |= PAP_PEER;    }    if (ho->neg_chap) {	ChapAuthWithPeer(unit, user, ho->chap_mdtype);	auth |= CHAP_WITHPEER;    } else if (ho->neg_upap) {	if (passwd[0] == 0) {	    passwd_from_file = 1;	    if (!get_pap_passwd(passwd))		syslog(LOG_ERR, "No secret found for PAP login");	}	upap_authwithpeer(unit, user, passwd);	auth |= PAP_WITHPEER;    }    auth_pending[unit] = auth;    if (!auth)	network_phase(unit);}/* * Proceed to the network phase. */static voidnetwork_phase(unit)    int unit;{    int i;    struct protent *protp;    #ifdef CBCP_SUPPORT    /*     * If we negotiated callback, do it now.     */    if (go->neg_cbcp) {	phase = PHASE_CALLBACK;	(*cbcp_protent.open)(unit);	return;    }#endif    phase = PHASE_NETWORK;    for (i = 0; (protp = protocols[i]) != NULL; ++i)        if (protp->protocol < 0xC000 && protp->enabled_flag	    && protp->open != NULL) {	    (*protp->open)(unit);	    if (protp->protocol != PPP_CCP)		++num_np_open;	}    if (num_np_open == 0)	/* nothing to do */	lcp_close(0, "No network protocols running");}/* * The peer has failed to authenticate himself using `protocol'. */voidauth_peer_fail(unit, protocol)    int unit, protocol;{    /*     * Authentication failure: take the link down     */    lcp_close(unit, "Authentication failed");}/* * The peer has been successfully authenticated using `protocol'. */voidauth_peer_success(unit, protocol, name, namelen)    int unit, protocol;    char *name;    int namelen;{    int bit;    switch (protocol) {    case PPP_CHAP:	bit = CHAP_PEER;	break;    case PPP_PAP:	bit = PAP_PEER;	break;    default:	syslog(LOG_WARNING, "auth_peer_success: unknown protocol %x",	       protocol);	return;    }    /*     * Save the authenticated name of the peer for later.     */    if (namelen > sizeof(peer_authname) - 1)	namelen = sizeof(peer_authname) - 1;    BCOPY(name, peer_authname, namelen);    peer_authname[namelen] = 0;    /*     * If we have overridden addresses based on auth info     * then set that information now before continuing.     */    auth_set_ip_addr(unit);    /*     * If there is no more authentication still to be done,     * proceed to the network (or callback) phase.     */    if ((auth_pending[unit] &= ~bit) == 0)        network_phase(unit);}/* * We have failed to authenticate ourselves to the peer using `protocol'. */voidauth_withpeer_fail(unit, protocol)    int unit, protocol;{    if (passwd_from_file)	BZERO(passwd, MAXSECRETLEN);    /*     * We've failed to authenticate ourselves to our peer.     * He'll probably take the link down, and there's not much     * we can do except wait for that.     */}/* * We have successfully authenticated ourselves with the peer using `protocol'. */voidauth_withpeer_success(unit, protocol)    int unit, protocol;{    int bit;    switch (protocol) {    case PPP_CHAP:	bit = CHAP_WITHPEER;	break;    case PPP_PAP:	if (passwd_from_file)	    BZERO(passwd, MAXSECRETLEN);	bit = PAP_WITHPEER;	break;    default:	syslog(LOG_WARNING, "auth_peer_success: unknown protocol %x",	       protocol);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?