⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 auth.c

📁 自己精简过的PPPD代码。在嵌入中应用可以更好的发挥。比原先的小了很多
💻 C
📖 第 1 页 / 共 5 页
字号:
    case PPP_EAP:	bit = EAP_WITHPEER;	prot = "EAP";	break;    default:	warn("auth_withpeer_success: unknown protocol %x", protocol);	bit = 0;    }    notice("%s authentication succeeded", prot);    /* Save the authentication method for later. */    auth_done[unit] |= bit;    /*     * If there is no more authentication still being done,     * proceed to the network (or callback) phase.     */    if ((auth_pending[unit] &= ~bit) == 0)	network_phase(unit);}/* * np_up - a network protocol has come up. */voidnp_up(unit, proto)    int unit, proto;{    int tlim;    if (num_np_up == 0) {	/*	 * At this point we consider that the link has come up successfully.	 */	status = EXIT_OK;	unsuccess = 0;	new_phase(PHASE_RUNNING);	if (idle_time_hook != 0)	    tlim = (*idle_time_hook)(NULL);	else	    tlim = idle_time_limit;	if (tlim > 0)	    TIMEOUT(check_idle, NULL, tlim);	/*	 * Set a timeout to close the connection once the maximum	 * connect time has expired.	 */	if (maxconnect > 0)	    TIMEOUT(connect_time_expired, 0, maxconnect);#ifdef MAXOCTETS	if (maxoctets > 0)	    TIMEOUT(check_maxoctets, NULL, maxoctets_timeout);#endif	/*	 * Detach now, if the updetach option was given.	 */	if (updetach && !nodetach)	    detach();    }    ++num_np_up;}/* * np_down - a network protocol has gone down. */voidnp_down(unit, proto)    int unit, proto;{    if (--num_np_up == 0) {	UNTIMEOUT(check_idle, NULL);	UNTIMEOUT(connect_time_expired, NULL);#ifdef MAXOCTETS	UNTIMEOUT(check_maxoctets, NULL);#endif		new_phase(PHASE_NETWORK);    }}/* * np_finished - a network protocol has finished using the link. */voidnp_finished(unit, proto)    int unit, proto;{    if (--num_np_open <= 0) {	/* no further use for the link: shut up shop. */	lcp_close(0, "No network protocols running");    }}#ifdef MAXOCTETSstatic voidcheck_maxoctets(arg)    void *arg;{    int diff;    unsigned int used;    update_link_stats(ifunit);    link_stats_valid=0;        switch(maxoctets_dir) {	case PPP_OCTETS_DIRECTION_IN:	    used = link_stats.bytes_in;	    break;	case PPP_OCTETS_DIRECTION_OUT:	    used = link_stats.bytes_out;	    break;	case PPP_OCTETS_DIRECTION_MAXOVERAL:	case PPP_OCTETS_DIRECTION_MAXSESSION:	    used = (link_stats.bytes_in > link_stats.bytes_out) ? link_stats.bytes_in : link_stats.bytes_out;	    break;	default:	    used = link_stats.bytes_in+link_stats.bytes_out;	    break;    }    diff = maxoctets - used;    if(diff < 0) {	notice("Traffic limit reached. Limit: %u Used: %u", maxoctets, used);	status = EXIT_TRAFFIC_LIMIT;	lcp_close(0, "Traffic limit");	need_holdoff = 0;    } else {        TIMEOUT(check_maxoctets, NULL, maxoctets_timeout);    }}#endif/* * check_idle - check whether the link has been idle for long * enough that we can shut it down. */static voidcheck_idle(arg)    void *arg;{    struct ppp_idle idle;    time_t itime;    int tlim;    if (!get_idle_time(0, &idle))	return;    if (idle_time_hook != 0) {	tlim = idle_time_hook(&idle);    } else {	itime = MIN(idle.xmit_idle, idle.recv_idle);	tlim = idle_time_limit - itime;    }    if (tlim <= 0) {	/* link is idle: shut it down. */	notice("Terminating connection due to lack of activity.");	status = EXIT_IDLE_TIMEOUT;	lcp_close(0, "Link inactive");	need_holdoff = 0;    } else {	TIMEOUT(check_idle, NULL, tlim);    }}/* * connect_time_expired - log a message and close the connection. */static voidconnect_time_expired(arg)    void *arg;{    info("Connect time expired");    status = EXIT_CONNECT_TIME;    lcp_close(0, "Connect time expired");	/* Close connection */}#ifdef INCLUDE/* * auth_check_options - called to check authentication options. */voidauth_check_options(){    lcp_options *wo = &lcp_wantoptions[0];    int can_auth;    int lacks_ip;    /* Default our_name to hostname, and user to our_name */    if (our_name[0] == 0 || usehostname)	strlcpy(our_name, hostname, sizeof(our_name));    if (user[0] == 0)	strlcpy(user, our_name, sizeof(user));    /*     * If we have a default route, require the peer to authenticate     * unless the noauth option was given or the real user is root.     */    if (!auth_required && !allow_any_ip && have_route_to(0) && !privileged) {	auth_required = 1;	default_auth = 1;    }    /* If we selected any CHAP flavors, we should probably negotiate it. :-) */    if (wo->chap_mdtype)	wo->neg_chap = 1;    /* If authentication is required, ask peer for CHAP, PAP, or EAP. */    if (auth_required) {	allow_any_ip = 0;	if (!wo->neg_chap && !wo->neg_upap && !wo->neg_eap) {	    //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_upap = 0;	wo->neg_eap = 0;    }    /*     * Check whether we have appropriate secrets to use     * to authenticate the peer.  Note that EAP can authenticate by way     * of a CHAP-like exchanges as well as SRP.     */    lacks_ip = 0;    can_auth = wo->neg_upap && (uselogin || have_pap_secret(&lacks_ip));    if (!can_auth && (wo->neg_chap || wo->neg_eap)) {	can_auth = have_chap_secret((explicit_remote? remote_name: NULL),				    our_name, 1, &lacks_ip);    }    if (!can_auth && wo->neg_eap) {	can_auth = have_srp_secret((explicit_remote? remote_name: NULL),				    our_name, 1, &lacks_ip);    }    if (auth_required && !can_auth && noauth_addrs == NULL) {	if (default_auth) {	    option_error("By default the remote system is required to authenticate itself");	    option_error("(because this system has a default route to the internet)");	} else if (explicit_remote)	    option_error("The remote system (%s) is required to authenticate itself",			 remote_name);	else	    option_error("The remote system is required to authenticate itself");	option_error("but I couldn't find any suitable secret (password) for it to use to do so.");	if (lacks_ip)	    option_error("(None of the available passwords would let it use an IP address.)");	exit(1);    }    /*     * Early check for remote number authorization.     */    if (!auth_number()) {	warn("calling number %q is not authorized", remote_number);	exit(EXIT_CNID_AUTH_FAILED);    }}/* * auth_reset - called when LCP is starting negotiations to recheck * authentication options, i.e. whether we have appropriate secrets * to use for authenticating ourselves and/or the peer. */voidauth_reset(unit)    int unit;{    lcp_options *go = &lcp_gotoptions[unit];    lcp_options *ao = &lcp_allowoptions[unit];    int hadchap;    hadchap = -1;    ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL));    ao->neg_chap = (!refuse_chap || !refuse_mschap || !refuse_mschap_v2)	&& (passwd[0] != 0 ||	    (hadchap = have_chap_secret(user, (explicit_remote? remote_name:					       NULL), 0, NULL)));    ao->neg_eap = !refuse_eap && (	passwd[0] != 0 ||	(hadchap == 1 || (hadchap == -1 && have_chap_secret(user,	    (explicit_remote? remote_name: NULL), 0, NULL))) ||	have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL));    hadchap = -1;    if (go->neg_upap && !uselogin && !have_pap_secret(NULL))	go->neg_upap = 0;    if (go->neg_chap) {	if (!(hadchap = have_chap_secret((explicit_remote? remote_name: NULL),			      our_name, 1, NULL)))	    go->neg_chap = 0;    }    if (go->neg_eap &&	(hadchap == 0 || (hadchap == -1 &&	    !have_chap_secret((explicit_remote? remote_name: NULL), our_name,		1, NULL))) &&	!have_srp_secret((explicit_remote? remote_name: NULL), our_name, 1,	    NULL))	go->neg_eap = 0;}/* * check_passwd - Check the user name and passwd against the PAP secrets * file.  If requested, also check against the system password database, * and login the user if OK. * * returns: *	UPAP_AUTHNAK: Authentication failed. *	UPAP_AUTHACK: Authentication succeeded. * In either case, msg points to an appropriate message. */intcheck_passwd(unit, auser, userlen, apasswd, passwdlen, msg)    int unit;    char *auser;    int userlen;    char *apasswd;    int passwdlen;    char **msg;{    int ret;    char *filename;    FILE *f;    struct wordlist *addrs = NULL, *opts = NULL;    char passwd[256], user[256];    char secret[MAXWORDLEN];    static int attempts = 0;    /*     * Make copies of apasswd and auser, then null-terminate them.     * If there are unprintable characters in the password, make     * them visible.     */    slprintf(passwd, sizeof(passwd), "%.*v", passwdlen, apasswd);    slprintf(user, sizeof(user), "%.*v", userlen, auser);    *msg = "";    /*     * Check if a plugin wants to handle this.     */    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);	    else if (opts != 0)		free_wordlist(opts);	    if (addrs != 0)		free_wordlist(addrs);	    BZERO(passwd, sizeof(passwd));	    return ret? UPAP_AUTHACK: UPAP_AUTHNAK;	}    }    /*     * Open the file of pap secrets and scan for a suitable secret     * for authenticating this user.     */    filename = _PATH_UPAPFILE;    addrs = opts = NULL;    ret = UPAP_AUTHNAK;    f = fopen(filename, "r");    if (f == NULL) {	error("Can't open PAP password file %s: %m", filename);    } else {	check_access(f, filename);	if (scan_authfile(f, user, our_name, secret, &addrs, &opts, filename, 0) < 0) {	    warn("no PAP secret found for %s", user);	} else {	    /*	     * If the secret is "@login", it means to check	     * the password against the login database.	     */	    int login_secret = strcmp(secret, "@login") == 0;	    ret = UPAP_AUTHACK;	    if (uselogin || login_secret) {		/* login option or secret is @login */		if ((ret = plogin(user, passwd, msg)) == UPAP_AUTHACK)		    used_login = 1;	    }	    if (secret[0] != 0 && !login_secret) {		/* password given in pap-secrets - must match */		if ((cryptpap || strcmp(passwd, secret) != 0)		    && strcmp(crypt(passwd, secret), secret) != 0)		    ret = UPAP_AUTHNAK;	    }	}	fclose(f);    }    if (ret == UPAP_AUTHNAK) {        if (**msg == 0)	    *msg = "Login incorrect";	/*	 * XXX can we ever get here more than once??	 * Frustrate passwd stealer programs.	 * Allow 10 tries, but start backing off after 3 (stolen from login).	 * On 10'th, drop the connection.	 */	if (attempts++ >= 10) {	    warn("%d LOGIN FAILURES ON %s, %s", attempts, devnam, user);	    lcp_close(unit, "login failed");	}	if (attempts > 3)	    sleep((u_int) (attempts - 3) * 5);	if (opts != NULL)	    free_wordlist(opts);    } else {	attempts = 0;			/* Reset count */	if (**msg == 0)	    *msg = "Login ok";	set_allowed_addrs(unit, addrs, opts);    }    if (addrs != NULL)	free_wordlist(addrs);    BZERO(passwd, sizeof(passwd));    BZERO(secret, sizeof(secret));    return ret;}/* * This function is needed for PAM. */#ifdef USE_PAM/* Static variables used to communicate between the conversation function * and the server_login function  */static char *PAM_username;static char *PAM_password;static int PAM_error = 0;static pam_handle_t *pamh = NULL;/* PAM conversation function * Here we assume (for now, at least) that echo on means login name, and * echo off means password. */static int PAM_conv (int num_msg,#ifndef SOL2    const#endif    struct pam_message **msg,    struct pam_response **resp, void *appdata_ptr){    int replies = 0;    struct pam_response *reply = NULL;#define COPY_STRING(s) (s) ? strdup(s) : NULL    reply = malloc(sizeof(struct pam_response) * num_msg);    if (!reply) return PAM_CONV_ERR;    for (replies = 0; replies < num_msg; replies++) {        switch (msg[replies]->msg_style) {            case PAM_PROMPT_ECHO_ON:                reply[replies].resp_retcode = PAM_SUCCESS;                reply[replies].resp = COPY_STRING(PAM_username);                /* PAM frees resp */                break;            case PAM_PROMPT_ECHO_OFF:                reply[replies].resp_retcode = PAM_SUCCESS;                reply[replies].resp = COPY_STRING(PAM_password);                /* PAM frees resp */                break;            case PAM_TEXT_INFO:                /* fall through */            case PAM_ERROR_MSG:                /* ignore it, but pam still wants a NULL response... */                reply[replies].resp_retcode = PAM_SUCCESS;                reply[replies].resp = NULL;                break;            default:                       /* Must be an error of some sort... */                free (reply);                PAM_error = 1;                return PAM_CONV_ERR;        }    }    *resp = reply;         return PAM_SUCCESS;}static struct pam_conv PAM_conversation = {    &PAM_conv,    NULL};#endif  /* USE_PAM *//* * plogin - Check the user name and password against the system * password database, and login the user if OK. * * returns: *	UPAP_AUTHNAK: Login failed. *	UPAP_AUTHACK: Login succeeded.

⌨️ 快捷键说明

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