📄 auth.c
字号:
* 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_error = 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, ifname); /* 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(){ char *tty;#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();#endif /* USE_PAM */ tty = devnam; if (strncmp(tty, "/dev/", 5) == 0) tty += 5; logwtmp(tty, "", ""); /* Wipe out utmp logout entry */ 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]; /* * Check if a plugin wants to handle this. */ ret = -1; if (null_auth_hook) ret = (*null_auth_hook)(&addrs, &opts); /* * Open the file of pap secrets and scan for a suitable secret. */ if (ret <= 0) { 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, 0); ret = i >= 0 && secret[0] == 0; BZERO(secret, sizeof(secret)); fclose(f); } if (ret) set_allowed_addrs(unit, addrs, opts); else if (opts != 0) free_wordlist(opts); if (addrs != 0) free_wordlist(addrs); 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, 0); 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, 0); 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; if (chap_check_hook) { ret = (*chap_check_hook)(); if (ret >= 0) { return ret; } } 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, 0); 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;}/* * have_srp_secret - check whether we have a SRP 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_srp_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_SRPFILE; 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, 0); 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 if (!am_server && chap_passwd_hook) { if ( (*chap_passwd_hook)(client, secbuf) < 0) { error("Unable to obtain CHAP password for %s on %s from plugin", client, server); return 0; } } 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, 0); 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;}/* * get_srp_secret - open the SRP secret file and return the secret * for authenticating the given client on the given server. * (We could be either client or server). */intget_srp_secret(unit, client, server, secret, am_server) int unit; char *client; char *server; char *secret; int am_server;{ FILE *fp; int ret; char *filename; struct wordlist *addrs, *opts; if (!am_server && passwd[0] != '\0') { strlcpy(secret, passwd, MAXWORDLEN); } else { filename = _PATH_SRPFILE; addrs = NULL; fp = fopen(filename, "r"); if (fp == NULL) { error("Can't open srp secret file %s: %m", filename); return 0; } check_access(fp, filename); secret[0] = '\0'; ret = scan_authfile(fp, client, server, secret, &addrs, &opts, filename, am_server); fclose(fp); if (ret < 0) return 0; if (am_server) set_allowed_addrs(unit, addrs, opts); else if (opts != NULL) free_wordlist(opts); if (addrs != NULL) free_wordlist(addrs); } 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 voidset_allowed_addrs(unit, addrs, opts) int unit; struct wordlist *addrs; struct wordlist *opts;{ int n; struct wordlist *ap, **plink; struct permitted_ip *ip; char *ptr_word, *ptr_mask; struct hostent *hp; struct netent *np; u_int32_t a, mask, ah, offset; struct ipcp_options *wo = &ipcp_wantoptions[unit]; u_int32_t suggested_ip = 0; if (addresses[unit] != NULL) free(addresses[unit]); addresses[unit] = NULL; if (extra_options != NULL) free_wordlist(extra_options); extra_options = opts;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -