Пример #1
0
/*
 * Parses a host of the form <address>[:port]
 * paddr is used to create a list in the order of input
 * **paddr is the ->next pointer of the last entry (or s->addrs)
 * *paddr is the variable used to keep track of **paddr between calls
 * port is the default port to assume
 */
static const char *get_addresses(pool *p, char *w, server_addr_rec ***paddr,
			    unsigned port)
{
    struct hostent *hep;
    unsigned long my_addr;
    server_addr_rec *sar;
    char *t;
    int i, is_an_ip_addr;

    if (*w == 0)
	return NULL;

    t = strchr(w, ':');
    if (t) {
	if (strcmp(t + 1, "*") == 0) {
	    port = 0;
	}
	else if ((i = atoi(t + 1))) {
	    port = i;
	}
	else {
	    return ":port must be numeric";
	}
	*t = 0;
    }

    is_an_ip_addr = 0;
    if (strcmp(w, "*") == 0) {
	my_addr = htonl(INADDR_ANY);
	is_an_ip_addr = 1;
    }
    else if (strcasecmp(w, "_default_") == 0
	     || strcmp(w, "255.255.255.255") == 0) {
	my_addr = DEFAULT_VHOST_ADDR;
	is_an_ip_addr = 1;
    }
    else if ((my_addr = ap_inet_addr(w)) != INADDR_NONE) {
	is_an_ip_addr = 1;
    }
    if (is_an_ip_addr) {
	sar = ap_pcalloc(p, sizeof(server_addr_rec));
	**paddr = sar;
	*paddr = &sar->next;
	sar->host_addr.s_addr = my_addr;
	sar->host_port = port;
	sar->virthost = ap_pstrdup(p, w);
	if (t != NULL)
	    *t = ':';
	return NULL;
    }

    hep = gethostbyname(w);

    if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
	ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
	    "Cannot resolve host name %s --- ignoring!", w);
	if (t != NULL)
	    *t = ':';
	return NULL;
    }

    for (i = 0; hep->h_addr_list[i]; ++i) {
	sar = ap_pcalloc(p, sizeof(server_addr_rec));
	**paddr = sar;
	*paddr = &sar->next;
	sar->host_addr = *(struct in_addr *) hep->h_addr_list[i];
	sar->host_port = port;
	sar->virthost = ap_pstrdup(p, w);
    }

    if (t != NULL)
	*t = ':';
    return NULL;
}
Пример #2
0
static const char *allow_cmd(cmd_parms *cmd, void *dv, char *from, char *where)
{
    access_dir_conf *d = (access_dir_conf *) dv;
    allowdeny *a;
    char *s;

    if (strcasecmp(from, "from"))
	return "allow and deny must be followed by 'from'";

    a = (allowdeny *) ap_push_array(cmd->info ? d->allows : d->denys);
    a->x.from = where;
    a->limited = cmd->limited;

    if (!strncasecmp(where, "env=", 4)) {
	a->type = T_ENV;
	a->x.from += 4;

    }
    else if (!strcasecmp(where, "all")) {
	a->type = T_ALL;

    }
    else if ((s = strchr(where, '/'))) {
	struct in_addr mask;

	a->type = T_IP;
	/* trample on where, we won't be using it any more */
	*s++ = '\0';

	if (!is_ip(where)
	    || (a->x.ip.net.s_addr = ap_inet_addr(where)) == INADDR_NONE) {
	    a->type = T_FAIL;
	    return "syntax error in network portion of network/netmask";
	}

	/* is_ip just tests if it matches [\d.]+ */
	if (!is_ip(s)) {
	    a->type = T_FAIL;
	    return "syntax error in mask portion of network/netmask";
	}
	/* is it in /a.b.c.d form? */
	if (strchr(s, '.')) {
	    mask.s_addr = ap_inet_addr(s);
	    if (mask.s_addr == INADDR_NONE) {
		a->type = T_FAIL;
		return "syntax error in mask portion of network/netmask";
	    }
	}
	else {
	    int i;

	    /* assume it's in /nnn form */
	    i = atoi(s);
	    if (i > 32 || i <= 0) {
		a->type = T_FAIL;
		return "invalid mask in network/netmask";
	    }
	    mask.s_addr = 0xFFFFFFFFUL << (32 - i);
	    mask.s_addr = htonl(mask.s_addr);
	}
	a->x.ip.mask = mask;
        a->x.ip.net.s_addr  = (a->x.ip.net.s_addr & mask.s_addr);   /* pjr - This fixes PR 4770 */
    }
    else if (ap_isdigit(*where) && is_ip(where)) {
	/* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
	int shift;
	char *t;
	int octet;

	a->type = T_IP;
	/* parse components */
	s = where;
	a->x.ip.net.s_addr = 0;
	a->x.ip.mask.s_addr = 0;
	shift = 24;
	while (*s) {
	    t = s;
	    if (!ap_isdigit(*t)) {
		a->type = T_FAIL;
		return "invalid ip address";
	    }
	    while (ap_isdigit(*t)) {
		++t;
	    }
	    if (*t == '.') {
		*t++ = 0;
	    }
	    else if (*t) {
		a->type = T_FAIL;
		return "invalid ip address";
	    }
	    if (shift < 0) {
		a->type = T_FAIL;
		return "invalid ip address, only 4 octets allowed";
	    }
	    octet = atoi(s);
	    if (octet < 0 || octet > 255) {
		a->type = T_FAIL;
		return "each octet must be between 0 and 255 inclusive";
	    }
	    a->x.ip.net.s_addr |= (unsigned int)octet << shift;
	    a->x.ip.mask.s_addr |= 0xFFUL << shift;
	    s = t;
	    shift -= 8;
	}
	a->x.ip.net.s_addr = ntohl(a->x.ip.net.s_addr);
	a->x.ip.mask.s_addr = ntohl(a->x.ip.mask.s_addr);
    }
    else {
	a->type = T_HOST;
    }

    return NULL;
}