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 + -
显示快捷键?