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

📄 auth.c

📁 自己精简过的PPPD代码。在嵌入中应用可以更好的发挥。比原先的小了很多
💻 C
📖 第 1 页 / 共 5 页
字号:
    /*     * Count the number of IP addresses given.     */    n = wordlist_count(addrs) + wordlist_count(noauth_addrs);    if (n == 0)	return;    ip = (struct permitted_ip *) malloc((n + 1) * sizeof(struct permitted_ip));    if (ip == 0)	return;    /* temporarily append the noauth_addrs list to addrs */    for (plink = &addrs; *plink != NULL; plink = &(*plink)->next)	;    *plink = noauth_addrs;    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 = ifunit + 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",		     ifunit, 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;    }    *plink = NULL;    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;	/*	 * Do we insist on this address?  No, if there are other	 * addresses authorized than the suggested one.	 */	if (n > 1)	    wo->accept_remote = 1;    }}#endif /* INCLUDE *//* * 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;{    int ok;    /* don't allow loopback or multicast address */    if (bad_ip_adrs(addr))	return 0;    if (allowed_address_hook) {	ok = allowed_address_hook(addr);	if (ok >= 0) return ok;    }    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 || privileged || !have_route_to(addr);}static intip_addr_check(addr, addrs)    u_int32_t addr;    struct permitted_ip *addrs;{    for (; ; ++addrs)	if ((addr & addrs->mask) == addrs->base)	    return addrs->permit;}/* * 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);}/* * some_ip_ok - check a wordlist to see if it authorizes any * IP address(es). */static intsome_ip_ok(addrs)    struct wordlist *addrs;{    for (; addrs != 0; addrs = addrs->next) {	if (addrs->word[0] == '-')	    break;	if (addrs->word[0] != '!')	    return 1;		/* some IP address is allowed */    }    return 0;}/* * auth_number - check whether the remote number is allowed to connect. * Returns 1 if authorized, 0 otherwise. */intauth_number(){    struct wordlist *wp = permitted_numbers;    int l;    /* Allow all if no authorization list. */    if (!wp)	return 1;    /* Allow if we have a match in the authorization list. */    while (wp) {	/* trailing '*' wildcard */	l = strlen(wp->word);	if ((wp->word)[l - 1] == '*')	    l--;	if (!strncasecmp(wp->word, remote_number, l))	    return 1;	wp = wp->next;    }    return 0;}#ifdef INCLUDE/* * check_access - complain if a secret file has too-liberal permissions. */static voidcheck_access(f, filename)    FILE *f;    char *filename;{    struct stat sbuf;    if (fstat(fileno(f), &sbuf) < 0) {	warn("cannot stat secret file %s: %m", filename);    } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) {	warn("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 up to a "--" (i.e. address authorization * info) are placed in a wordlist and returned in *addrs.  Any * following words (extra options) are placed in a wordlist and * returned in *opts. * We assume secret is NULL or points to MAXWORDLEN bytes of space. * Flags are non-zero if we need two colons in the secret in order to * match. */static intscan_authfile(f, client, server, secret, addrs, opts, filename, flags)    FILE *f;    char *client;    char *server;    char *secret;    struct wordlist **addrs;    struct wordlist **opts;    char *filename;    int flags;{    int newline, xxx;    int got_flag, best_flag;    FILE *sf;    struct wordlist *ap, *addr_list, *alist, **app;    char word[MAXWORDLEN];    char atfile[MAXWORDLEN];    char lsecret[MAXWORDLEN];    char *cp;    if (addrs != NULL)	*addrs = NULL;    if (opts != NULL)	*opts = 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 && 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 (!ISWILD(word)) {	    if (server != NULL && strcmp(word, server) != 0)		continue;	    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;	/*	 * SRP-SHA1 authenticator should never be reading secrets from	 * a file.  (Authenticatee may, though.)	 */	if (flags && ((cp = strchr(word, ':')) == NULL ||	    strchr(cp + 1, ':') == NULL))	    continue;	if (secret != NULL) {	    /*	     * Special syntax: @/pathname means read secret from file.	     */	    if (word[0] == '@' && word[1] == '/') {		strlcpy(atfile, word+1, sizeof(atfile));		if ((sf = fopen(atfile, "r")) == NULL) {		    warn("can't open indirect secret file %s", atfile);		    continue;		}		check_access(sf, atfile);		if (!getword(sf, word, &xxx, atfile)) {		    warn("no secret in indirect secret file %s", atfile);		    fclose(sf);		    continue;		}		fclose(sf);	    }	    strlcpy(lsecret, word, sizeof(lsecret));	}	/*	 * Now read address authorization info and make a wordlist.	 */	app = &alist;	for (;;) {	    if (!getword(f, word, &newline, filename) || newline)		break;	    ap = (struct wordlist *)		    malloc(sizeof(struct wordlist) + strlen(word) + 1);	    if (ap == NULL)		novm("authorized addresses");	    ap->word = (char *) (ap + 1);	    strcpy(ap->word, word);	    *app = ap;	    app = &ap->next;	}	*app = NULL;	/*	 * This is the best so far; remember it.	 */	best_flag = got_flag;	if (addr_list)	    free_wordlist(addr_list);	addr_list = alist;	if (secret != NULL)	    strlcpy(secret, lsecret, MAXWORDLEN);	if (!newline)	    break;    }    /* scan for a -- word indicating the start of options */    for (app = &addr_list; (ap = *app) != NULL; app = &ap->next)	if (strcmp(ap->word, "--") == 0)	    break;    /* ap = start of options */    if (ap != NULL) {	ap = ap->next;		/* first option */	free(*app);			/* free the "--" word */	*app = NULL;		/* terminate addr list */    }    if (opts != NULL)	*opts = ap;    else if (ap != NULL)	free_wordlist(ap);    if (addrs != NULL)	*addrs = addr_list;    else if (addr_list != NULL)	free_wordlist(addr_list);    return best_flag;}/* * wordlist_count - return the number of items in a wordlist */static intwordlist_count(wp)    struct wordlist *wp;{    int n;    for (n = 0; wp != NULL; wp = wp->next)	++n;    return n;}/* * 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;    }}#endif /* INCLUDE *//* * auth_script_done - called when the auth-up or auth-down script * has finished. */static voidauth_script_done(arg)    void *arg;{    auth_script_pid = 0;    switch (auth_script_state) {    case s_up:	if (auth_state == s_down) {	    auth_script_state = s_down;	    auth_script(_PATH_AUTHDOWN);	}	break;    case s_down:	if (auth_state == s_up) {	    auth_script_state = s_up;	    auth_script(_PATH_AUTHUP);	}	break;    }}/* * auth_script - execute a script with arguments * interface-name peer-name real-user tty speed */static voidauth_script(script)    char *script;{    char strspeed[32];    struct passwd *pw;    char struid[32];    char *user_name;    char *argv[8];    if ((pw = getpwuid(getuid())) != NULL && pw->pw_name != NULL)	user_name = pw->pw_name;    else {	slprintf(struid, sizeof(struid), "%d", getuid());	user_name = struid;    }    slprintf(strspeed, sizeof(strspeed), "%d", baud_rate);    argv[0] = script;    argv[1] = ifname;    argv[2] = peer_authname;    argv[3] = user_name;    argv[4] = devnam;    argv[5] = strspeed;    argv[6] = NULL;    auth_script_pid = run_program(script, argv, 0, auth_script_done, NULL, 0);}

⌨️ 快捷键说明

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