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

📄 auth.c

📁 经典的ppp程序
💻 C
📖 第 1 页 / 共 4 页
字号:
	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, const 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. * In either case, msg points to an appropriate message. */static intplogin(user, passwd, msg)    char *user;    char *passwd;    char **msg;{    char *tty;#ifdef USE_PAM    int pam_error;    pam_error = pam_start ("ppp", user, &PAM_conversation, &pamh);    if (pam_error != PAM_SUCCESS) {        *msg = (char *) pam_strerror (pamh, pam_error);	reopen_log();	return UPAP_AUTHNAK;    }    /*     * Define the fields for the credential validation     */         PAM_username = user;    PAM_password = passwd;    PAM_error = 0;    pam_set_item (pamh, PAM_TTY, devnam); /* this might be useful to some modules */    /*     * Validate the user     */    pam_error = pam_authenticate (pamh, PAM_SILENT);    if (pam_error == PAM_SUCCESS && !PAM_error) {            pam_error = pam_acct_mgmt (pamh, PAM_SILENT);        if (pam_error == PAM_SUCCESS)	    pam_open_session (pamh, PAM_SILENT);    }    *msg = (char *) pam_strerror (pamh, pam_error);    /*     * Clean up the mess     */    reopen_log();	/* apparently the PAM stuff does closelog() */    PAM_username = NULL;    PAM_password = NULL;    if (pam_error != PAM_SUCCESS)        return UPAP_AUTHNAK;#else /* #ifdef USE_PAM *//* * Use the non-PAM methods directly */#ifdef HAS_SHADOW    struct spwd *spwd;    struct spwd *getspnam();#endif    struct passwd *pw = getpwnam(user);    endpwent();    if (pw == NULL)	return (UPAP_AUTHNAK);#ifdef HAS_SHADOW    spwd = getspnam(user);    endspent();    if (spwd) {	/* check the age of the password entry */	long now = time(NULL) / 86400L;	if ((spwd->sp_expire > 0 && now >= spwd->sp_expire)	    || ((spwd->sp_max >= 0 && spwd->sp_max < 10000)		&& spwd->sp_lstchg >= 0		&& now >= spwd->sp_lstchg + spwd->sp_max)) {	    warn("Password for %s has expired", user);	    return (UPAP_AUTHNAK);	}	pw->pw_passwd = spwd->sp_pwdp;    }#endif    /*     * If no passwd, don't let them login.     */    if (pw->pw_passwd == NULL || strlen(pw->pw_passwd) < 2	|| strcmp(crypt(passwd, pw->pw_passwd), pw->pw_passwd) != 0)	return (UPAP_AUTHNAK);#endif /* #ifdef USE_PAM */    /*     * Write a wtmp entry for this user.     */    tty = devnam;    if (strncmp(tty, "/dev/", 5) == 0)	tty += 5;    logwtmp(tty, user, remote_name);		/* Add wtmp login entry */#if defined(_PATH_LASTLOG) && !defined(USE_PAM)    if (pw != (struct passwd *)NULL) {	    struct lastlog ll;	    int fd;	    if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) {		(void)lseek(fd, (off_t)(pw->pw_uid * sizeof(ll)), SEEK_SET);		memset((void *)&ll, 0, sizeof(ll));		(void)time(&ll.ll_time);		(void)strncpy(ll.ll_line, tty, sizeof(ll.ll_line));		(void)write(fd, (char *)&ll, sizeof(ll));		(void)close(fd);	    }    }#endif /* _PATH_LASTLOG and not USE_PAM */    info("user %s logged in", user);    logged_in = 1;    return (UPAP_AUTHACK);}/* * plogout - Logout the user. */static voidplogout(){#ifdef USE_PAM    int pam_error;    if (pamh != NULL) {	pam_error = pam_close_session (pamh, PAM_SILENT);	pam_end (pamh, pam_error);	pamh = NULL;    }    /* Apparently the pam stuff does closelog(). */    reopen_log();#else /* ! USE_PAM */       char *tty;    tty = devnam;    if (strncmp(tty, "/dev/", 5) == 0)	tty += 5;    logwtmp(tty, "", "");		/* Wipe out utmp logout entry */#endif /* ! USE_PAM */    logged_in = 0;}/* * null_login - Check if a username of "" and a password of "" are * acceptable, and iff so, set the list of acceptable IP addresses * and return 1. */static intnull_login(unit)    int unit;{    char *filename;    FILE *f;    int i, ret;    struct wordlist *addrs, *opts;    char secret[MAXWORDLEN];    /*     * Open the file of pap secrets and scan for a suitable secret.     */    filename = _PATH_UPAPFILE;    addrs = NULL;    f = fopen(filename, "r");    if (f == NULL)	return 0;    check_access(f, filename);    i = scan_authfile(f, "", our_name, secret, &addrs, &opts, filename);    ret = i >= 0 && secret[0] == 0;    BZERO(secret, sizeof(secret));    if (ret)	set_allowed_addrs(unit, addrs, opts);    else if (opts != 0)	free_wordlist(opts);    if (addrs != 0)	free_wordlist(addrs);    fclose(f);    return ret;}/* * get_pap_passwd - get a password for authenticating ourselves with * our peer using PAP.  Returns 1 on success, 0 if no suitable password * could be found. * Assumes passwd points to MAXSECRETLEN bytes of space (if non-null). */static intget_pap_passwd(passwd)    char *passwd;{    char *filename;    FILE *f;    int ret;    char secret[MAXWORDLEN];    /*     * Check whether a plugin wants to supply this.     */    if (pap_passwd_hook) {	ret = (*pap_passwd_hook)(user, passwd);	if (ret >= 0)	    return ret;    }    filename = _PATH_UPAPFILE;    f = fopen(filename, "r");    if (f == NULL)	return 0;    check_access(f, filename);    ret = scan_authfile(f, user,			(remote_name[0]? remote_name: NULL),			secret, NULL, NULL, filename);    fclose(f);    if (ret < 0)	return 0;    if (passwd != NULL)	strlcpy(passwd, secret, MAXSECRETLEN);    BZERO(secret, sizeof(secret));    return 1;}/* * have_pap_secret - check whether we have a PAP file with any * secrets that we could possibly use for authenticating the peer. */static inthave_pap_secret(lacks_ipp)    int *lacks_ipp;{    FILE *f;    int ret;    char *filename;    struct wordlist *addrs;    /* let the plugin decide, if there is one */    if (pap_check_hook) {	ret = (*pap_check_hook)();	if (ret >= 0)	    return ret;    }    filename = _PATH_UPAPFILE;    f = fopen(filename, "r");    if (f == NULL)	return 0;    ret = scan_authfile(f, (explicit_remote? remote_name: NULL), our_name,			NULL, &addrs, NULL, filename);    fclose(f);    if (ret >= 0 && !some_ip_ok(addrs)) {	if (lacks_ipp != 0)	    *lacks_ipp = 1;	ret = -1;    }    if (addrs != 0)	free_wordlist(addrs);    return ret >= 0;}/* * have_chap_secret - check whether we have a CHAP file with a * secret that we could possibly use for authenticating `client' * on `server'.  Either can be the null string, meaning we don't * know the identity yet. */static inthave_chap_secret(client, server, need_ip, lacks_ipp)    char *client;    char *server;    int need_ip;    int *lacks_ipp;{    FILE *f;    int ret;    char *filename;    struct wordlist *addrs;    filename = _PATH_CHAPFILE;    f = fopen(filename, "r");    if (f == NULL)	return 0;    if (client != NULL && client[0] == 0)	client = NULL;    else if (server != NULL && server[0] == 0)	server = NULL;    ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename);    fclose(f);    if (ret >= 0 && need_ip && !some_ip_ok(addrs)) {	if (lacks_ipp != 0)	    *lacks_ipp = 1;	ret = -1;    }    if (addrs != 0)	free_wordlist(addrs);    return ret >= 0;}/* * get_secret - open the CHAP secret file and return the secret * for authenticating the given client on the given server. * (We could be either client or server). */intget_secret(unit, client, server, secret, secret_len, am_server)    int unit;    char *client;    char *server;    char *secret;    int *secret_len;    int am_server;{    FILE *f;    int ret, len;    char *filename;    struct wordlist *addrs, *opts;    char secbuf[MAXWORDLEN];    if (!am_server && passwd[0] != 0) {	strlcpy(secbuf, passwd, sizeof(secbuf));    } else {	filename = _PATH_CHAPFILE;	addrs = NULL;	secbuf[0] = 0;	f = fopen(filename, "r");	if (f == NULL) {	    error("Can't open chap secret file %s: %m", filename);	    return 0;	}	check_access(f, filename);	ret = scan_authfile(f, client, server, secbuf, &addrs, &opts, filename);	fclose(f);	if (ret < 0)	    return 0;	if (am_server)	    set_allowed_addrs(unit, addrs, opts);	else if (opts != 0)	    free_wordlist(opts);	if (addrs != 0)	    free_wordlist(addrs);    }    len = strlen(secbuf);    if (len > MAXSECRETLEN) {	error("Secret for %s on %s is too long", client, server);	len = MAXSECRETLEN;    }    BCOPY(secbuf, secret, len);    BZERO(secbuf, sizeof(secbuf));    *secret_len = len;    return 1;}/* * set_allowed_addrs() - set the list of allowed addresses. * Also looks for `--' indicating options to apply for this peer * and leaves the following words in extra_options. */static void

⌨️ 快捷键说明

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