auth.c
来自「RTEMS (Real-Time Executive for Multiproc」· C语言 代码 · 共 1,122 行 · 第 1/2 页
C
1,122 行
if (--num_np_up == 0) { UNTIMEOUT(check_idle, NULL); 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"); }}/* * 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."); lcp_close(0, "Link inactive"); need_holdoff = 0; pppd_status = EXIT_IDLE_TIMEOUT; } 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"); lcp_close(0, "Connect time expired"); /* Close connection */ pppd_status = EXIT_CONNECT_TIME;}/* * auth_check_options - called to check authentication options. */intauth_check_options(){ lcp_options *wo = &lcp_wantoptions[0]; int status = 1; 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) { printf("auth_check_options: turning on\n"); auth_required = 1; default_auth = 1; } /* If authentication is required, ask peer for CHAP or PAP. */ if (auth_required) { if (!wo->neg_chap && !wo->neg_upap) { wo->neg_chap = 1; wo->neg_upap = 1; } } else { wo->neg_chap = 0; wo->neg_upap = 0; } /* * Check whether we have appropriate secrets to use * to authenticate the peer. */ lacks_ip = 0; can_auth = wo->neg_upap && (uselogin || have_pap_secret(&lacks_ip)); if (!can_auth && wo->neg_chap) { can_auth = have_chap_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.)"); status = 0; } return ( status );}/* * 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[0]; ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL)); ao->neg_chap = !refuse_chap && (passwd[0] != 0 || have_chap_secret(user, (explicit_remote? remote_name: NULL), 0, NULL)); if (go->neg_upap && !uselogin && !have_pap_secret(NULL)) go->neg_upap = 0; if (go->neg_chap) { if (!have_chap_secret((explicit_remote? remote_name: NULL), our_name, 1, NULL)) go->neg_chap = 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;{ char passwd[64], user[64]; if (pap_auth_hook) { slprintf(passwd, sizeof(passwd), "%.*v", passwdlen, apasswd); slprintf(user, sizeof(user), "%.*v", userlen, auser); return (*pap_auth_hook)(user, passwd/*, NULL, NULL, NULL*/) ? UPAP_AUTHACK : UPAP_AUTHNAK; } return UPAP_AUTHACK;#if 0 int ret = (int)UPAP_AUTHNAK; if (( userlen == 0 ) && ( passwdlen == 0 )) { ret = (int)UPAP_AUTHACK; } printf("check_passwd: %d\n", ret); return ret;#endif}/* * 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;{ return 0;}/* * 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;{ int ret = (int)0; /* * Check whether a plugin wants to supply this. */ if (pap_passwd_hook) { ret = (*pap_passwd_hook)(user, passwd); } return ( ret );}/* * 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;{ return 1;#if 0 int ret = (int)0; /* let the plugin decide, if there is one */ printf("have_pap_secret:\n"); if (pap_check_hook) { ret = (*pap_check_hook)(); } return ( ret );#endif}/* * 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;{ return 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;{ int len; char secbuf[MAXWORDLEN]; if (!am_server && passwd[0] != 0) { strlcpy(secbuf, passwd, sizeof(secbuf)); } else { return 0; } 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 voidset_allowed_addrs(unit, addrs, opts) int unit; struct wordlist *addrs; struct wordlist *opts;{ int n; struct wordlist *ap, **pap; 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; /* * Count the number of IP addresses given. */ for (n = 0, pap = &addrs; (ap = *pap) != NULL; pap = &ap->next) ++n; if (n == 0) return; ip = (struct permitted_ip *) malloc((n + 1) * sizeof(struct permitted_ip)); if (ip == 0) return; n = 0; for (ap = addrs; ap != NULL; ap = ap->next) { /* "-" means no addresses authorized, "*" means any address allowed */ ptr_word = ap->word; if (strcmp(ptr_word, "-") == 0) break; if (strcmp(ptr_word, "*") == 0) { ip[n].permit = 1; ip[n].base = ip[n].mask = 0; ++n; break; } ip[n].permit = 1; if (*ptr_word == '!') { ip[n].permit = 0; ++ptr_word; } mask = ~ (u_int32_t) 0; offset = 0; ptr_mask = strchr (ptr_word, '/'); if (ptr_mask != NULL) { int bit_count; char *endp; bit_count = (int) strtol (ptr_mask+1, &endp, 10); if (bit_count <= 0 || bit_count > 32) { warn("invalid address length %v in auth. address list", ptr_mask+1); continue; } bit_count = 32 - bit_count; /* # bits in host part */ if (*endp == '+') { offset = pppifunit + 1; ++endp; } if (*endp != 0) { warn("invalid address length syntax: %v", ptr_mask+1); continue; } *ptr_mask = '\0'; mask <<= bit_count; } hp = gethostbyname(ptr_word); if (hp != NULL && hp->h_addrtype == AF_INET) { a = *(u_int32_t *)hp->h_addr; } else { np = getnetbyname (ptr_word); if (np != NULL && np->n_addrtype == AF_INET) { a = htonl (*(u_int32_t *)np->n_net); if (ptr_mask == NULL) { /* calculate appropriate mask for net */ ah = ntohl(a); if (IN_CLASSA(ah)) mask = IN_CLASSA_NET; else if (IN_CLASSB(ah)) mask = IN_CLASSB_NET; else if (IN_CLASSC(ah)) mask = IN_CLASSC_NET; } } else { a = inet_addr (ptr_word); } } if (ptr_mask != NULL) *ptr_mask = '/'; if (a == (u_int32_t)-1L) { warn("unknown host %s in auth. address list", ap->word); continue; } if (offset != 0) { if (offset >= ~mask) { warn("interface unit %d too large for subnet %v", pppifunit, ptr_word); continue; } a = htonl((ntohl(a) & mask) + offset); mask = ~(u_int32_t)0; } ip[n].mask = htonl(mask); ip[n].base = a & ip[n].mask; ++n; if (~mask == 0 && suggested_ip == 0) suggested_ip = a; } ip[n].permit = 0; /* make the last entry forbid all addresses */ ip[n].base = 0; /* to terminate the list */ ip[n].mask = 0; addresses[unit] = ip; /* * If the address given for the peer isn't authorized, or if * the user hasn't given one, AND there is an authorized address * which is a single host, then use that if we find one. */ if (suggested_ip != 0 && (wo->hisaddr == 0 || !auth_ip_addr(unit, wo->hisaddr))) wo->hisaddr = suggested_ip;}/* * 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_int32_t addr;{#if 0 int ok;#endif /* don't allow loopback or multicast address */ if (bad_ip_adrs(addr)) return 0; return 1;#if 0 if (addresses[unit] != NULL) { ok = ip_addr_check(addr, addresses[unit]); if (ok >= 0) return ok; } if (auth_required) return 0; /* no addresses authorized */ return allow_any_ip || !have_route_to(addr);#endif}#if 0static intip_addr_check(addr, addrs) u_int32_t addr; struct permitted_ip *addrs;{ for (; ; ++addrs) if ((addr & addrs->mask) == addrs->base) return addrs->permit;}#endif/* * 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_int32_t addr;{ addr = ntohl(addr); return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET || IN_MULTICAST(addr) || IN_BADCLASS(addr);}/* * 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; }}/* * auth_script - execute a script with arguments * interface-name peer-name real-user tty speed */static voidauth_script(s) enum script_state s;{ switch (s) { case s_up: auth_script_state = s_up; if ( auth_linkup_hook ) { (*auth_linkup_hook)(); } break; case s_down: auth_script_state = s_down; if ( auth_linkdown_hook ) { (*auth_linkdown_hook)(); } break; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?