📄 auth.c
字号:
/* * logout - Logout the user. */static voidlogout(){ char *tty; tty = strrchr(ppp_if[ppp_unit]->devname, '/'); if (tty == NULL) tty = ppp_if[ppp_unit]->devname; else tty++; ppp_if[ppp_unit]->logged_in = FALSE;}#endif /* notyet *//* * 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 = NULL; int i, ret; struct wordlist *addrs = NULL; char secret[MAXWORDLEN]; i = pppSecretFind ("", ppp_if[unit]->our_name, secret, &addrs); ret = i >= 0 && (i & NONWILD_CLIENT) != 0 && secret[0] == 0; if (!ret) { /* * Open the file of upap secrets and scan for a suitable secret. * We don't accept a wildcard client. */ if ((filename = ppp_if[unit]->options->pap_file) != NULL) f = fopen(filename, "r"); if (f == NULL) return 0; check_access(f, filename); i = scan_authfile(f, "", ppp_if[unit]->our_name, secret, &addrs, filename); ret = i >= 0 && (i & NONWILD_CLIENT) != 0 && secret[0] == 0; fclose(f); } if (ret) { if (ppp_if[unit]->addresses != NULL) free_wordlist(ppp_if[unit]->addresses); ppp_if[unit]->addresses = addrs; } return ret;}/* * get_upap_passwd - get a password for authenticating ourselves with * our peer using PAP. Returns 1 on success, 0 if no suitable password * could be found. */static intget_upap_passwd(){ char *filename; FILE *f = NULL; char secret[MAXWORDLEN]; if (pppSecretFind (ppp_if[ppp_unit]->user, ppp_if[ppp_unit]->remote_name, secret, NULL) < 0) { if ((filename = ppp_if[ppp_unit]->options->pap_file) != NULL) f = fopen(filename, "r"); if (f == NULL) return 0; check_access(f, filename); if (scan_authfile(f, ppp_if[ppp_unit]->user, ppp_if[ppp_unit]->remote_name, secret, NULL, filename) < 0) { fclose(f); return 0; } fclose(f); } strncpy(ppp_if[ppp_unit]->passwd, secret, MAXSECRETLEN); ppp_if[ppp_unit]->passwd[MAXSECRETLEN-1] = 0; return 1;}/* * have_upap_secret - check whether we have a PAP file with any * secrets that we could possibly use for authenticating the peer. */static inthave_upap_secret(){ FILE *f = NULL; int ret; char *filename; if (ppp_if[ppp_unit]->uselogin) return 1; if (pppSecretFind (NULL, ppp_if[ppp_unit]->our_name, NULL, NULL) < 0) { if ((filename = ppp_if[ppp_unit]->options->pap_file) != NULL) f = fopen(filename, "r"); if (f == NULL) return 0; ret = scan_authfile(f, NULL, ppp_if[ppp_unit]->our_name, NULL, NULL, filename); fclose(f); if (ret < 0) return 0; } return 1;}/* * 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) char *client; char *server;{ FILE *f = NULL; int ret; char *filename; if (client[0] == 0) client = NULL; else if (server[0] == 0) server = NULL; if (pppSecretFind (client, server, NULL, NULL) < 0) { if ((filename = ppp_if[ppp_unit]->options->chap_file) != NULL) f = fopen(filename, "r"); if (f == NULL) return 0; ret = scan_authfile(f, client, server, NULL, NULL, filename); fclose(f); if (ret < 0) return 0; } return 1;}/* * 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, save_addrs) int unit; char *client; char *server; char *secret; int *secret_len; int save_addrs;{ FILE *f = NULL; int ret, len; char *filename; struct wordlist *addrs = NULL; char secbuf[MAXWORDLEN]; secbuf[0] = 0; if (pppSecretFind (client, server, secbuf, &addrs) < 0) { if ((filename = ppp_if[unit]->options->chap_file) != NULL) f = fopen(filename, "r"); if (f == NULL) { syslog(LOG_ERR, "Can't open chap secret file %s", filename); return 0; } check_access(f, filename); ret = scan_authfile(f, client, server, secbuf, &addrs, filename); fclose(f); if (ret < 0) return 0; } if (save_addrs) { if (ppp_if[unit]->addresses != NULL) free_wordlist(ppp_if[unit]->addresses); ppp_if[unit]->addresses = addrs; } len = strlen(secbuf); if (len > MAXSECRETLEN) { syslog(LOG_ERR, "Secret for %s on %s is too long", client, server); len = MAXSECRETLEN; } BCOPY(secbuf, secret, len); *secret_len = len; return 1;}/* * auth_ip_addr - check whether the peer is authorized to use * a given IP address. Returns 1 if authorized, 0 otherwise. */intauth_ip_addr(unit, addr) int unit; u_long addr;{ u_long a; struct wordlist *addrs; /* don't allow loopback or multicast address */ if (bad_ip_adrs(addr)) return 0; if ((addrs = ppp_if[unit]->addresses) == NULL) return 1; /* no restriction */ for (; addrs != NULL; addrs = addrs->next) { /* "-" means no addresses authorized */ if (strcmp(addrs->word, "-") == 0) break; if ((a = inet_addr(addrs->word)) == -1) { if ((a = hostGetByName (addrs->word)) == NULL) { syslog(LOG_WARNING, "unknown host %s in auth. address list", addrs->word); continue; } } if (addr == a) return 1; } return 0; /* not in list => can't have it */}/* * bad_ip_adrs - return 1 if the IP address is one we don't want * to use, such as an address in the loopback net or a multicast address. * addr is in network byte order. */intbad_ip_adrs(addr) u_long addr;{ addr = ntohl(addr);#if CPU==SIMSPARCSOLARIS return IN_MULTICAST(addr) || IN_BADCLASS(addr);#else return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET || IN_MULTICAST(addr) || IN_BADCLASS(addr);#endif}/* * check_access - complain if a secret file has too-liberal permissions. */voidcheck_access(f, fileName) FILE *f; char *fileName;{ struct stat sbuf; if (fstat(fileno(f), &sbuf) < 0) { syslog(LOG_WARNING, "cannot stat secret file %s: %m", fileName); } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) { syslog(LOG_WARNING, "Warning - secret file %s has world and/or group access", fileName); }}/* * scan_authfile - Scan an authorization file for a secret suitable * for authenticating `client' on `server'. The return value is -1 * if no secret is found, otherwise >= 0. The return value has * NONWILD_CLIENT set if the secret didn't have "*" for the client, and * NONWILD_SERVER set if the secret didn't have "*" for the server. * Any following words on the line (i.e. address authorization * info) are placed in a wordlist and returned in *addrs. */static intscan_authfile(f, client, server, secret, addrs, fileName) FILE *f; char *client; char *server; char *secret; struct wordlist **addrs; char *fileName;{ int newline, xxx; int got_flag, best_flag; FILE *sf; struct wordlist *ap, *addr_list, *addr_last; char word[MAXWORDLEN]; char atfile[MAXWORDLEN]; if (addrs != NULL) *addrs = NULL; addr_list = NULL; if (!getword(f, word, &newline, fileName)) return -1; /* file is empty??? */ newline = 1; best_flag = -1; for (;;) { /* * Skip until we find a word at the start of a line. */ while (!newline && getword(f, word, &newline, fileName)) ; if (!newline) break; /* got to end of file */ /* * Got a client - check if it's a match or a wildcard. */ got_flag = 0; if (client != NULL && client[0] && strcmp(word, client) != 0 && !ISWILD(word)) { newline = 0; continue; } if (!ISWILD(word)) got_flag = NONWILD_CLIENT; /* * Now get a server and check if it matches. */ if (!getword(f, word, &newline, fileName)) break; if (newline) continue; if (server != NULL && server[0] && strcmp(word, server) != 0 && !ISWILD(word)) continue; if (!ISWILD(word)) got_flag |= NONWILD_SERVER; /* * Got some sort of a match - see if it's better than what * we have already. */ if (got_flag <= best_flag) continue; /* * Get the secret. */ if (!getword(f, word, &newline, fileName)) break; if (newline) continue; /* * Special syntax: @filename means read secret from file. */ if (word[0] == '@') { strcpy(atfile, word+1); if ((sf = fopen(atfile, "r")) == NULL) { syslog(LOG_WARNING, "can't open indirect secret file %s", atfile); continue; } check_access(sf, atfile); if (!getword(sf, word, &xxx, atfile)) { syslog(LOG_WARNING, "no secret in indirect secret file %s", atfile); fclose(sf); continue; } fclose(sf); } if (secret != NULL) strcpy(secret, word); best_flag = got_flag; /* * Now read address authorization info and make a wordlist. */ if (addr_list) free_wordlist(addr_list); addr_list = addr_last = NULL; for (;;) { if (!getword(f, word, &newline, fileName) || newline) break; ap = (struct wordlist *) malloc(sizeof(struct wordlist) + strlen(word)); if (ap == NULL) novm("authorized addresses"); ap->next = NULL; strcpy(ap->word, word); if (addr_list == NULL) addr_list = ap; else addr_last->next = ap; addr_last = ap; } if (!newline) break; } if (addrs != NULL) *addrs = addr_list; else if (addr_list != NULL) free_wordlist(addr_list); return best_flag;}/* * free_wordlist - release memory allocated for a wordlist. */static voidfree_wordlist(wp) struct wordlist *wp;{ struct wordlist *next; while (wp != NULL) { next = wp->next; free(wp); wp = next; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -