📄 auth.c
字号:
/*****************************************************************************
* auth.c - Network Authentication and Phase Control program file.
*
* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
* Copyright (c) 1997 by Global Election Systems Inc. All rights reserved.
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice and the following disclaimer are included verbatim in any
* distributions. No written agreement, license, or royalty fee is required
* for any of the authorized uses.
*
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
* REVISION HISTORY
*
* 03-01-01 Marc Boucher <marc@mbsi.ca>
* Ported to lwIP.
* 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
* Ported from public pppd code.
*****************************************************************************/
/*
* 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.
*/
#include "lwip/opt.h"
#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
#include "ppp.h"
#include "pppdebug.h"
#include "fsm.h"
#include "lcp.h"
#include "pap.h"
#include "chap.h"
#include "auth.h"
#include "ipcp.h"
#if CBCP_SUPPORT
#include "cbcp.h"
#endif /* CBCP_SUPPORT */
#include "lwip/inet.h"
#include <string.h>
#if 0 /* UNUSED */
/* Bits in scan_authfile return value */
#define NONWILD_SERVER 1
#define NONWILD_CLIENT 2
#define ISWILD(word) (word[0] == '*' && word[1] == 0)
#endif /* UNUSED */
#if PAP_SUPPORT || CHAP_SUPPORT
/* The name by which the peer authenticated itself to us. */
static char peer_authname[MAXNAMELEN];
#endif /* PAP_SUPPORT || CHAP_SUPPORT */
/* 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 we have run the /etc/ppp/auth-up script. */
static int did_authup; /* @todo, we don't need this in lwip*/
/* List of addresses which the peer may use. */
static struct wordlist *addresses[NUM_PPP];
#if 0 /* UNUSED */
/* Wordlist giving addresses which the peer may use
without authenticating itself. */
static struct wordlist *noauth_addrs;
/* Extra options to apply, from the secrets file entry for the peer. */
static struct wordlist *extra_options;
#endif /* UNUSED */
/* 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;
#if PAP_SUPPORT || CHAP_SUPPORT
/* Set if we got the contents of passwd[] from the pap-secrets file. */
static int passwd_from_file;
#endif /* PAP_SUPPORT || CHAP_SUPPORT */
#if 0 /* UNUSED */
/* Set if we require authentication only because we have a default route. */
static bool default_auth;
/* Hook to enable a plugin to control the idle time limit */
int (*idle_time_hook) __P((struct ppp_idle *)) = NULL;
/* Hook for a plugin to say whether we can possibly authenticate any peer */
int (*pap_check_hook) __P((void)) = NULL;
/* Hook for a plugin to check the PAP user and password */
int (*pap_auth_hook) __P((char *user, char *passwd, char **msgp,
struct wordlist **paddrs,
struct wordlist **popts)) = NULL;
/* Hook for a plugin to know about the PAP user logout */
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;
/*
* This is used to ensure that we don't start an auth-up/down
* script while one is already running.
*/
enum script_state {
s_down,
s_up
};
static enum script_state auth_state = s_down;
static enum script_state auth_script_state = s_down;
static pid_t auth_script_pid = 0;
/*
* Option variables.
* lwip: some of these are present in the ppp_settings structure
*/
bool uselogin = 0; /* Use /etc/passwd for checking PAP */
bool cryptpap = 0; /* Passwords in pap-secrets are encrypted */
bool refuse_pap = 0; /* Don't wanna auth. ourselves with PAP */
bool refuse_chap = 0; /* Don't wanna auth. ourselves with CHAP */
bool usehostname = 0; /* Use hostname for our_name */
bool auth_required = 0; /* Always require authentication from peer */
bool allow_any_ip = 0; /* Allow peer to use any IP address */
bool explicit_remote = 0; /* User specified explicit remote name */
char remote_name[MAXNAMELEN]; /* Peer's name for authentication */
#endif /* UNUSED */
/* Bits in auth_pending[] */
#define PAP_WITHPEER 1
#define PAP_PEER 2
#define CHAP_WITHPEER 4
#define CHAP_PEER 8
/* @todo, move this somewhere */
/* Used for storing a sequence of words. Usually malloced. */
struct wordlist {
struct wordlist *next;
char word[1];
};
extern char *crypt (const char *, const char *);
/* Prototypes for procedures local to this file. */
static void network_phase (int);
static void check_idle (void *);
static void connect_time_expired (void *);
#if 0
static int plogin (char *, char *, char **, int *);
#endif
static void plogout (void);
static int null_login (int);
static int get_pap_passwd (int, char *, char *);
static int have_pap_secret (void);
static int have_chap_secret (char *, char *, u32_t);
static int ip_addr_check (u32_t, struct wordlist *);
#if 0 /* PAP_SUPPORT || CHAP_SUPPORT */
static int scan_authfile (FILE *, char *, char *, char *,
struct wordlist **, struct wordlist **,
char *);
static void free_wordlist (struct wordlist *);
static void auth_script (char *);
static void auth_script_done (void *);
static void set_allowed_addrs (int unit, struct wordlist *addrs);
static int some_ip_ok (struct wordlist *);
static int setupapfile (char **);
static int privgroup (char **);
static int set_noauth_addr (char **);
static void check_access (FILE *, char *);
#endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */
#if 0 /* UNUSED */
/*
* Authentication-related options.
*/
option_t auth_options[] = {
{ "require-pap", o_bool, &lcp_wantoptions[0].neg_upap,
"Require PAP authentication from peer", 1, &auth_required },
{ "+pap", o_bool, &lcp_wantoptions[0].neg_upap,
"Require PAP authentication from peer", 1, &auth_required },
{ "refuse-pap", o_bool, &refuse_pap,
"Don't agree to auth to peer with PAP", 1 },
{ "-pap", o_bool, &refuse_pap,
"Don't allow PAP authentication with peer", 1 },
{ "require-chap", o_bool, &lcp_wantoptions[0].neg_chap,
"Require CHAP authentication from peer", 1, &auth_required },
{ "+chap", o_bool, &lcp_wantoptions[0].neg_chap,
"Require CHAP authentication from peer", 1, &auth_required },
{ "refuse-chap", o_bool, &refuse_chap,
"Don't agree to auth to peer with CHAP", 1 },
{ "-chap", o_bool, &refuse_chap,
"Don't allow CHAP authentication with peer", 1 },
{ "name", o_string, our_name,
"Set local name for authentication",
OPT_PRIV|OPT_STATIC, NULL, MAXNAMELEN },
{ "user", o_string, user,
"Set name for auth with peer", OPT_STATIC, NULL, MAXNAMELEN },
{ "usehostname", o_bool, &usehostname,
"Must use hostname for authentication", 1 },
{ "remotename", o_string, remote_name,
"Set remote name for authentication", OPT_STATIC,
&explicit_remote, MAXNAMELEN },
{ "auth", o_bool, &auth_required,
"Require authentication from peer", 1 },
{ "noauth", o_bool, &auth_required,
"Don't require peer to authenticate", OPT_PRIV, &allow_any_ip },
{ "login", o_bool, &uselogin,
"Use system password database for PAP", 1 },
{ "papcrypt", o_bool, &cryptpap,
"PAP passwords are encrypted", 1 },
{ "+ua", o_special, (void *)setupapfile,
"Get PAP user and password from file" },
{ "password", o_string, passwd,
"Password for authenticating us to the peer", OPT_STATIC,
NULL, MAXSECRETLEN },
{ "privgroup", o_special, (void *)privgroup,
"Allow group members to use privileged options", OPT_PRIV },
{ "allow-ip", o_special, (void *)set_noauth_addr,
"Set IP address(es) which can be used without authentication",
OPT_PRIV },
{ NULL }
};
#endif /* UNUSED */
#if 0 /* UNUSED */
/*
* setupapfile - specifies UPAP info for authenticating with peer.
*/
static int
setupapfile(char **argv)
{
FILE * ufile;
int l;
lcp_allowoptions[0].neg_upap = 1;
/* open user info file */
seteuid(getuid());
ufile = fopen(*argv, "r");
seteuid(0);
if (ufile == NULL) {
option_error("unable to open user login data file %s", *argv);
return 0;
}
check_access(ufile, *argv);
/* get username */
if (fgets(user, MAXNAMELEN - 1, ufile) == NULL
|| fgets(passwd, MAXSECRETLEN - 1, ufile) == NULL){
option_error("unable to read user login data file %s", *argv);
return 0;
}
fclose(ufile);
/* get rid of newlines */
l = strlen(user);
if (l > 0 && user[l-1] == '\n')
user[l-1] = 0;
l = strlen(passwd);
if (l > 0 && passwd[l-1] == '\n')
passwd[l-1] = 0;
return (1);
}
#endif /* UNUSED */
#if 0 /* UNUSED */
/*
* privgroup - allow members of the group to have privileged access.
*/
static int
privgroup(char **argv)
{
struct group *g;
int i;
g = getgrnam(*argv);
if (g == 0) {
option_error("group %s is unknown", *argv);
return 0;
}
for (i = 0; i < ngroups; ++i) {
if (groups[i] == g->gr_gid) {
privileged = 1;
break;
}
}
return 1;
}
#endif
#if 0 /* UNUSED */
/*
* set_noauth_addr - set address(es) that can be used without authentication.
* Equivalent to specifying an entry like `"" * "" addr' in pap-secrets.
*/
static int
set_noauth_addr(char **argv)
{
char *addr = *argv;
int l = strlen(addr);
struct wordlist *wp;
wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l + 1);
if (wp == NULL)
novm("allow-ip argument");
wp->word = (char *) (wp + 1);
wp->next = noauth_addrs;
BCOPY(addr, wp->word, l);
noauth_addrs = wp;
return 1;
}
#endif /* UNUSED */
/*
* An Open on LCP has requested a change from Dead to Establish phase.
* Do what's necessary to bring the physical layer up.
*/
void
link_required(int unit)
{
LWIP_UNUSED_ARG(unit);
AUTHDEBUG(LOG_INFO, ("link_required: %d\n", unit));
}
/*
* LCP has terminated the link; go to the Dead phase and take the
* physical layer down.
*/
void
link_terminated(int unit)
{
AUTHDEBUG(LOG_INFO, ("link_terminated: %d\n", unit));
if (lcp_phase[unit] == PHASE_DEAD) {
return;
}
if (logged_in) {
plogout();
}
lcp_phase[unit] = PHASE_DEAD;
AUTHDEBUG(LOG_NOTICE, ("Connection terminated.\n"));
pppLinkTerminated(unit);
}
/*
* LCP has gone down; it will either die or try to re-establish.
*/
void
link_down(int unit)
{
int i;
struct protent *protp;
AUTHDEBUG(LOG_INFO, ("link_down: %d\n", unit));
if (did_authup) {
/* XXX Do link down processing. */
did_authup = 0;
}
for (i = 0; (protp = ppp_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; /* number of network protocols we have opened */
num_np_up = 0; /* Number of network protocols which have come up */
if (lcp_phase[unit] != PHASE_DEAD) {
lcp_phase[unit] = PHASE_TERMINATE;
}
pppLinkDown(unit);
}
/*
* The link is established.
* Proceed to the Dead, Authenticate or Network phase as appropriate.
*/
void
link_established(int unit)
{
int auth;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -