Ejemplo n.º 1
0
static const char *proxies_set(cmd_parms *cmd, void *cfg,
                               const char *arg)
{
    remoteip_config_t *config = ap_get_module_config(cmd->server->module_config,
                                                     &remoteip_module);
    remoteip_proxymatch_t *match;
    apr_status_t rv;
    char *ip = apr_pstrdup(cmd->temp_pool, arg);
    char *s = ap_strchr(ip, '/');
    if (s) {
        *s++ = '\0';
    }

    if (!config->proxymatch_ip) {
        config->proxymatch_ip = apr_array_make(cmd->pool, 1, sizeof(*match));
    }
    match = (remoteip_proxymatch_t *) apr_array_push(config->proxymatch_ip);
    match->internal = cmd->info;

    if (looks_like_ip(ip)) {
        /* Note s may be null, that's fine (explicit host) */
        rv = apr_ipsubnet_create(&match->ip, ip, s, cmd->pool);
    }
    else
    {
        apr_sockaddr_t *temp_sa;

        if (s) {
            return apr_pstrcat(cmd->pool, "RemoteIP: Error parsing IP ", arg,
                               " the subnet /", s, " is invalid for ",
                               cmd->cmd->name, NULL);
        }

        rv = apr_sockaddr_info_get(&temp_sa,  ip, APR_UNSPEC, 0,
                                   APR_IPV4_ADDR_OK, cmd->temp_pool);
        while (rv == APR_SUCCESS)
        {
            apr_sockaddr_ip_get(&ip, temp_sa);
            rv = apr_ipsubnet_create(&match->ip, ip, NULL, cmd->pool);
            if (!(temp_sa = temp_sa->next)) {
                break;
            }
            match = (remoteip_proxymatch_t *)
                    apr_array_push(config->proxymatch_ip);
            match->internal = cmd->info;
        }
    }

    if (rv != APR_SUCCESS) {
        char msgbuf[128];
        apr_strerror(rv, msgbuf, sizeof(msgbuf));
        return apr_pstrcat(cmd->pool, "RemoteIP: Error parsing IP ", arg,
                           " (", msgbuf, " error) for ", cmd->cmd->name, NULL);
    }

    return NULL;
}
Ejemplo n.º 2
0
/* be sure not to store any IPv4 address as a v4-mapped IPv6 address */
APR_DECLARE(apr_status_t) apr_ipsubnet_create(apr_ipsubnet_t **ipsub, const char *ipstr, 
                                              const char *mask_or_numbits, apr_pool_t *p)
{
    apr_status_t rv;
    char *endptr;
    long bits, maxbits = 32;

    /* filter out stuff which doesn't look remotely like an IP address; this helps 
     * callers like mod_access which have a syntax allowing hostname or IP address;
     * APR_EINVAL tells the caller that it was probably not intended to be an IP
     * address
     */
    if (!looks_like_ip(ipstr)) {
        return APR_EINVAL;
    }

    *ipsub = apr_pcalloc(p, sizeof(apr_ipsubnet_t));

    /* assume ipstr is an individual IP address, not a subnet */
    memset((*ipsub)->mask, 0xFF, sizeof (*ipsub)->mask);

    rv = parse_ip(*ipsub, ipstr, mask_or_numbits == NULL);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    if (mask_or_numbits) {
#if APR_HAVE_IPV6
        if ((*ipsub)->family == AF_INET6) {
            maxbits = 128;
        }
#endif
        bits = strtol(mask_or_numbits, &endptr, 10);
        if (*endptr == '\0' && bits > 0 && bits <= maxbits) {
            /* valid num-bits string; fill in mask appropriately */
            int cur_entry = 0;
            apr_int32_t cur_bit_value;

            memset((*ipsub)->mask, 0, sizeof (*ipsub)->mask);
            while (bits > 32) {
                (*ipsub)->mask[cur_entry] = 0xFFFFFFFF; /* all 32 bits */
                bits -= 32;
                ++cur_entry;
            }
            cur_bit_value = 0x80000000;
            while (bits) {
                (*ipsub)->mask[cur_entry] |= cur_bit_value;
                --bits;
                cur_bit_value /= 2;
            }
            (*ipsub)->mask[cur_entry] = htonl((*ipsub)->mask[cur_entry]);
        }
        else if (apr_inet_pton(AF_INET, mask_or_numbits, (*ipsub)->mask) == 1 &&
            (*ipsub)->family == AF_INET) {
            /* valid IPv4 netmask */
        }
        else {
            return APR_EBADMASK;
        }
    }

    fix_subnet(*ipsub);

    return APR_SUCCESS;
}