コード例 #1
0
ファイル: mod_rpaf-2.0.c プロジェクト: buzztaiki/mod_rpaf-0.6
static int change_remote_ip(request_rec *r) {
    const char *fwdvalue;
    char *val;
    rpaf_server_cfg *cfg = (rpaf_server_cfg *)ap_get_module_config(r->server->module_config,
                                                                   &rpaf_module);

    if (!cfg->enable)
        return DECLINED;

    if (cfg->remote_addr_env) {
        apr_table_set(r->subprocess_env, cfg->remote_addr_env, r->connection->remote_ip);
    }
    if (is_in_array(r->connection->remote_ip, cfg->proxy_ips) == 1) {
        /* check if cfg->headername is set and if it is use
           that instead of X-Forwarded-For by default */
        if (cfg->headername && (fwdvalue = apr_table_get(r->headers_in, cfg->headername))) {
            //
        } else if ((fwdvalue = apr_table_get(r->headers_in, "X-Forwarded-For"))) {
            //
        } else {
            return DECLINED;
        }

        if (fwdvalue) {
            rpaf_cleanup_rec *rcr = (rpaf_cleanup_rec *)apr_pcalloc(r->pool, sizeof(rpaf_cleanup_rec));
            apr_array_header_t *arr = apr_array_make(r->pool, 0, sizeof(char*));
            while (*fwdvalue && (val = ap_get_token(r->pool, &fwdvalue, 1))) {
                *(char **)apr_array_push(arr) = apr_pstrdup(r->pool, val);
                if (*fwdvalue != '\0')
                    ++fwdvalue;
            }
            rcr->old_ip = r->connection->remote_ip;
            rcr->old_family = r->connection->remote_addr->sa.sin.sin_family;
            rcr->r = r;
            apr_pool_cleanup_register(r->pool, (void *)rcr, rpaf_cleanup, apr_pool_cleanup_null);
            r->connection->remote_ip = apr_pstrdup(r->pool, extract_ip(arr, cfg->proxy_ips, cfg->recursive));
            r->connection->remote_addr->sa.sin.sin_addr.s_addr = apr_inet_addr(r->connection->remote_ip);
            r->connection->remote_addr->sa.sin.sin_family = AF_INET;
            if (cfg->sethostname) {
                const char *hostvalue;
                if ((hostvalue = apr_table_get(r->headers_in, "X-Forwarded-Host"))) {
                    /* 2.0 proxy frontend or 1.3 => 1.3.25 proxy frontend */
                    apr_table_set(r->headers_in, "Host", apr_pstrdup(r->pool, hostvalue));
                    r->hostname = apr_pstrdup(r->pool, hostvalue);
                    ap_update_vhost_from_headers(r);
                } else if ((hostvalue = apr_table_get(r->headers_in, "X-Host"))) {
                    /* 1.3 proxy frontend with mod_proxy_add_forward */
                    apr_table_set(r->headers_in, "Host", apr_pstrdup(r->pool, hostvalue));
                    r->hostname = apr_pstrdup(r->pool, hostvalue);
                    ap_update_vhost_from_headers(r);
                }
            }

        }
    }
    return DECLINED;
}
コード例 #2
0
ファイル: mod_rpaf.c プロジェクト: zakx/mod_rpaf
static int change_remote_ip(request_rec *r) {
    const char *fwdvalue;
    char *val;
    apr_port_t tmpport;
    apr_pool_t *tmppool;
    rpaf_server_cfg *cfg = (rpaf_server_cfg *)ap_get_module_config(r->server->module_config,
                                                                   &rpaf_module);

    if (!cfg->enable)
        return DECLINED;

    if (is_in_array(r->pool, r->connection->remote_ip, cfg->proxy_ips) == 1) {
        /* check if cfg->headername is set and if it is use
           that instead of X-Forwarded-For by default */
        if (cfg->headername && (fwdvalue = apr_table_get(r->headers_in, cfg->headername))) {
            //
        } else if ((fwdvalue = apr_table_get(r->headers_in, "X-Forwarded-For"))) {
            //
        } else {
            return DECLINED;
        }

        if (fwdvalue) {
            rpaf_cleanup_rec *rcr = (rpaf_cleanup_rec *)apr_pcalloc(r->pool, sizeof(rpaf_cleanup_rec));
            apr_array_header_t *arr = apr_array_make(r->pool, 0, sizeof(char*));
            while (*fwdvalue && (val = ap_get_token(r->pool, &fwdvalue, 1))) {
                *(char **)apr_array_push(arr) = apr_pstrdup(r->pool, val);
                if (*fwdvalue != '\0')
                    ++fwdvalue;
            }
            rcr->old_ip = apr_pstrdup(r->connection->pool, r->connection->remote_ip);
            rcr->r = r;
            apr_pool_cleanup_register(r->pool, (void *)rcr, rpaf_cleanup, apr_pool_cleanup_null);
            r->connection->remote_ip = apr_pstrdup(r->connection->pool, last_not_in_array(r->pool, arr, cfg->proxy_ips));
	    tmppool = r->connection->remote_addr->pool;
	    tmpport = r->connection->remote_addr->port;
	    memset(r->connection->remote_addr, '\0', sizeof(apr_sockaddr_t));
	    r->connection->remote_addr = NULL;
	    apr_sockaddr_info_get(&(r->connection->remote_addr), r->connection->remote_ip, APR_UNSPEC, tmpport, 0, tmppool);

            if (cfg->sethostname) {
                const char *hostvalue;
                if ((hostvalue = apr_table_get(r->headers_in, "X-Forwarded-Host")) ||
                    (hostvalue = apr_table_get(r->headers_in, "X-Host"))) {
                    apr_array_header_t *arr = apr_array_make(r->pool, 0, sizeof(char*));
                    while (*hostvalue && (val = ap_get_token(r->pool, &hostvalue, 1))) {
                        *(char **)apr_array_push(arr) = apr_pstrdup(r->pool, val);
                        if (*hostvalue != '\0')
                          ++hostvalue;
                    }

                    apr_table_set(r->headers_in, "Host", apr_pstrdup(r->pool, ((char **)arr->elts)[((arr->nelts)-1)]));
                    r->hostname = apr_pstrdup(r->pool, ((char **)arr->elts)[((arr->nelts)-1)]);
                    ap_update_vhost_from_headers(r);
                }
            }

            if (cfg->sethttps) {
                const char *httpsvalue;
                if ((httpsvalue = apr_table_get(r->headers_in, "X-Forwarded-HTTPS")) ||
                    (httpsvalue = apr_table_get(r->headers_in, "X-HTTPS"))) {
                    apr_table_set(r->subprocess_env, "HTTPS", apr_pstrdup(r->pool, httpsvalue));
                    r->server->server_scheme = cfg->https_scheme;
                } else {
                    r->server->server_scheme = cfg->orig_scheme;
                }
            }

             if (cfg->setport) {
                const char *portvalue;
                if ((portvalue = apr_table_get(r->headers_in, "X-Forwarded-Port")) ||
                    (portvalue = apr_table_get(r->headers_in, "X-Port"))) {
                    r->server->port    = atoi(portvalue);
                    r->parsed_uri.port = r->server->port;
                } else {
                    r->server->port = cfg->orig_port;
                }
            }
        }
    }
    return DECLINED;
}
コード例 #3
0
ファイル: h2_task.c プロジェクト: nickrace/mod_h2
static request_rec *h2_task_create_request(h2_task_env *env)
{
    conn_rec *conn = &env->c;
    request_rec *r;
    apr_pool_t *p;
    int access_status = HTTP_OK;    
    
    apr_pool_create(&p, conn->pool);
    apr_pool_tag(p, "request");
    r = apr_pcalloc(p, sizeof(request_rec));
    AP_READ_REQUEST_ENTRY((intptr_t)r, (uintptr_t)conn);
    r->pool            = p;
    r->connection      = conn;
    r->server          = conn->base_server;
    
    r->user            = NULL;
    r->ap_auth_type    = NULL;
    
    r->allowed_methods = ap_make_method_list(p, 2);
    
    r->headers_in = apr_table_copy(r->pool, env->headers);
    r->trailers_in     = apr_table_make(r->pool, 5);
    r->subprocess_env  = apr_table_make(r->pool, 25);
    r->headers_out     = apr_table_make(r->pool, 12);
    r->err_headers_out = apr_table_make(r->pool, 5);
    r->trailers_out    = apr_table_make(r->pool, 5);
    r->notes           = apr_table_make(r->pool, 5);
    
    r->request_config  = ap_create_request_config(r->pool);
    /* Must be set before we run create request hook */
    
    r->proto_output_filters = conn->output_filters;
    r->output_filters  = r->proto_output_filters;
    r->proto_input_filters = conn->input_filters;
    r->input_filters   = r->proto_input_filters;
    ap_run_create_request(r);
    r->per_dir_config  = r->server->lookup_defaults;
    
    r->sent_bodyct     = 0;                      /* bytect isn't for body */
    
    r->read_length     = 0;
    r->read_body       = REQUEST_NO_BODY;
    
    r->status          = HTTP_OK;  /* Until further notice */
    r->header_only     = 0;
    r->the_request     = NULL;
    
    /* Begin by presuming any module can make its own path_info assumptions,
     * until some module interjects and changes the value.
     */
    r->used_path_info = AP_REQ_DEFAULT_PATH_INFO;
    
    r->useragent_addr = conn->client_addr;
    r->useragent_ip = conn->client_ip;
    
    ap_run_pre_read_request(r, conn);
    
    /* Time to populate r with the data we have. */
    r->request_time = apr_time_now();
    r->the_request = apr_psprintf(r->pool, "%s %s HTTP/1.1", 
                                  env->method, env->path);
    r->method = env->method;
    /* Provide quick information about the request method as soon as known */
    r->method_number = ap_method_number_of(r->method);
    if (r->method_number == M_GET && r->method[0] == 'H') {
        r->header_only = 1;
    }

    ap_parse_uri(r, env->path);
    r->protocol = (char*)"HTTP/1.1";
    r->proto_num = HTTP_VERSION(1, 1);
    
    r->hostname = env->authority;
    
    /* update what we think the virtual host is based on the headers we've
     * now read. may update status.
     */
    ap_update_vhost_from_headers(r);
    
    /* we may have switched to another server */
    r->per_dir_config = r->server->lookup_defaults;
    
    /*
     * Add the HTTP_IN filter here to ensure that ap_discard_request_body
     * called by ap_die and by ap_send_error_response works correctly on
     * status codes that do not cause the connection to be dropped and
     * in situations where the connection should be kept alive.
     */
    ap_add_input_filter_handle(ap_http_input_filter_handle,
                               NULL, r, r->connection);
    
    if (access_status != HTTP_OK
        || (access_status = ap_run_post_read_request(r))) {
        /* Request check post hooks failed. An example of this would be a
         * request for a vhost where h2 is disabled --> 421.
         */
        h2_task_die(env, access_status, r);
        ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
        ap_run_log_transaction(r);
        r = NULL;
        goto traceout;
    }
    
    AP_READ_REQUEST_SUCCESS((uintptr_t)r, (char *)r->method, 
                            (char *)r->uri, (char *)r->server->defn_name, 
                            r->status);
    return r;
traceout:
    AP_READ_REQUEST_FAILURE((uintptr_t)r);
    return r;
}
コード例 #4
0
ファイル: mod_rpaf.c プロジェクト: taladar/mod_rpaf
static int rpaf_post_read_request(request_rec *r) {
    char *fwdvalue, *val, *mask, *last_val;
    int i;
    apr_port_t tmpport;
    apr_pool_t *tmppool;
    const char *header_ip = NULL, *header_host = NULL, *header_https = NULL, *header_port = NULL;
    rpaf_server_cfg *cfg = (rpaf_server_cfg *)ap_get_module_config(r->server->module_config,
                                                                   &rpaf_module);

    if (!cfg->enable)
        return DECLINED;

    /* this overcomes an issue when mod_rewrite causes this to get called again
       and the environment value is lost for HTTPS. This is the only thing that
       is lost and we do not need to process any further after restoring the
       value. Note that this check uses the *per-request* note - otherwise we
       would shortcut here for every subsequent request */
    const char *rpaf_https = apr_table_get(r->notes, "rpaf_https");
    if (rpaf_https) {
        apr_table_set(r->subprocess_env, "HTTPS", rpaf_https);
        return DECLINED;
    }

    /* check if the remote_addr is in the allowed proxy IP list */
    if (is_in_array(r->DEF_ADDR, cfg->proxy_ips) != 1) {
        if (cfg->forbid_if_not_proxy)
            return HTTP_FORBIDDEN;
        return DECLINED;
    }

    /* TODO: We should not just assume that we should fallback to
       X-Forwarded-For as this could pose a security risk, keeping
       this for now to keep our behaviour consistant */
    header_ip = cfg->headername;
    if (header_ip)
      fwdvalue = (char *)apr_table_get(r->headers_in, header_ip);
    if (!header_ip || !fwdvalue)
    {
      header_ip = "X-Forwarded-For";
      fwdvalue  = (char *)apr_table_get(r->headers_in, header_ip);
    }

    /* if there was no forwarded for header then we dont do anything */
    if (!fwdvalue)
        return DECLINED;

    /* split up the list of forwarded IPs */
    apr_array_header_t *arr = apr_array_make(r->pool, 4, sizeof(char *));
    while ((val = strsep(&fwdvalue, ",")) != NULL) {
        /* strip leading and trailing whitespace */
        while(isspace(*val))
            ++val;
        for (i = strlen(val) - 1; i > 0 && isspace(val[i]); i--)
            val[i] = '\0';
        if (rpaf_looks_like_ip(val))
            *(char **)apr_array_push(arr) = apr_pstrdup(r->pool, val);
    }

    /* if there were no IPs, then there is nothing to do */
    if (apr_is_empty_array(arr))
        return DECLINED;

    /* get the last IP and check if it is in our list of proxies */
    if ((last_val = last_not_in_array(r, arr, cfg->proxy_ips)) == NULL)
        return DECLINED;

    /* if we are cleaning up the headers then we need to correct the forwarded IP list */
    if (cfg->clean_headers)
    {
        /* pop the proxy's IP from the list */
        apr_array_pop(arr);
        if (apr_is_empty_array(arr))
            apr_table_unset(r->headers_in, header_ip);
        else {
            char *ip_list = apr_array_pstrcat(r->pool, arr, ',');
            apr_table_set(r->headers_in, header_ip, ip_list);
        }
    }

    rpaf_cleanup_rec *rcr = (rpaf_cleanup_rec *)apr_pcalloc(r->pool, sizeof(rpaf_cleanup_rec));
    rcr->old_ip = apr_pstrdup(r->DEF_POOL, r->DEF_IP);
    rcr->r = r;
    apr_pool_cleanup_register(r->pool, (void *)rcr, rpaf_cleanup, apr_pool_cleanup_null);
    r->DEF_IP = apr_pstrdup(r->DEF_POOL, last_val);
    memcpy(&rcr->old_addr, r->DEF_ADDR, sizeof(apr_sockaddr_t));

    tmppool = r->DEF_ADDR->pool;
    tmpport = r->DEF_ADDR->port;
    apr_sockaddr_t *tmpsa;
    int ret = apr_sockaddr_info_get(&tmpsa, r->DEF_IP, APR_UNSPEC, tmpport, 0, tmppool);
    if (ret == APR_SUCCESS)
        memcpy(r->DEF_ADDR, tmpsa, sizeof(apr_sockaddr_t));
    if (cfg->sethostname) {
        const char *hostvalue;
        header_host = "X-Forwarded-Host";
        hostvalue   = apr_table_get(r->headers_in, header_host);
        if (!hostvalue) {
            header_host = "X-Host";
            hostvalue   = apr_table_get(r->headers_in, header_host);
        }

        if (!hostvalue) {
            header_host = NULL;
        } else {
            apr_array_header_t *arr = apr_array_make(r->pool, 0, sizeof(char*));
            while (*hostvalue && (val = ap_get_token(r->pool, &hostvalue, 1))) {
                *(char **)apr_array_push(arr) = apr_pstrdup(r->pool, val);
                if (*hostvalue != '\0')
                  ++hostvalue;
            }

            apr_table_set(r->headers_in, "Host", apr_pstrdup(r->pool, ((char **)arr->elts)[((arr->nelts)-1)]));
            r->hostname = apr_pstrdup(r->pool, ((char **)arr->elts)[((arr->nelts)-1)]);
            ap_update_vhost_from_headers(r);
        }
    }

    if (cfg->sethttps) {
        const char *httpsvalue, *scheme;
        header_https = "X-Forwarded-HTTPS";
        httpsvalue   = apr_table_get(r->headers_in, header_https);
        if (!httpsvalue) {
            header_https = "X-HTTPS";
            httpsvalue   = apr_table_get(r->headers_in, header_https);
        }

        if (!httpsvalue) {
            header_https = "X-Forwarded-Proto";
            httpsvalue   = apr_table_get(r->headers_in, header_https);
            if (!httpsvalue) {
              header_https = "X-Forwarded-Protocol";
              httpsvalue   = apr_table_get(r->headers_in, header_https);
            }
            if (httpsvalue) {
                if (strcmp(httpsvalue, cfg->https_scheme) == 0) {
                    /* set a per-request note to get around an issue with mod_rewrite
                       (explained in an earlier comment), and a per-connection note
                       to allow our version of ssl_is_https() to work.
                     */
                    apr_table_set(r->notes, "rpaf_https", "on");
                    apr_table_set(r->connection->notes, "rpaf_https", "on");
                    apr_table_set(r->subprocess_env   , "HTTPS"     , "on");
                    scheme = cfg->https_scheme;
                } else {
                    scheme = cfg->orig_scheme;
                }
            } else {
                header_https = NULL;
                scheme       = cfg->orig_scheme;
            }
        } else {
            if(strcmp(httpsvalue, "on") == 0 || strcmp(httpsvalue, "On") == 0) {
              apr_table_set(r->notes, "rpaf_https", "on");
              apr_table_set(r->connection->notes, "rpaf_https", "on");
              apr_table_set(r->subprocess_env   , "HTTPS"     , "on");
              scheme = cfg->https_scheme;
            } else {
              scheme = cfg->orig_scheme;
            }
        }

        #if AP_SERVER_MINORVERSION_NUMBER > 1 && AP_SERVER_PATCHLEVEL_NUMBER > 2
        r->server->server_scheme = scheme;
        #endif
    }

     if (cfg->setport) {
        const char *portvalue;
        header_port = "X-Forwarded-Port";
        portvalue   = apr_table_get(r->headers_in, header_port);
        if (!portvalue) {
            header_port = "X-Port";
            portvalue   = apr_table_get(r->headers_in, header_port);
        }

        if (!portvalue) {
            header_port     = NULL;
            r->server->port = cfg->orig_port;
        } else {
            r->server->port    = atoi(portvalue);
            r->parsed_uri.port = r->server->port;
        }
    }

    if (cfg->clean_headers) {
        if (header_host ) apr_table_unset(r->headers_in, header_host );
        if (header_https) apr_table_unset(r->headers_in, header_https);
        if (header_port ) apr_table_unset(r->headers_in, header_port );
    }

    return DECLINED;
}
コード例 #5
0
ファイル: mod_rpaf.c プロジェクト: joshboon/mod_rpaf
static int rpaf_post_read_request(request_rec *r) {
    char *fwdvalue, *val, *mask, *last_val;
    int i;
    apr_port_t tmpport;
    apr_pool_t *tmppool;
    rpaf_server_cfg *cfg = (rpaf_server_cfg *)ap_get_module_config(r->server->module_config,
                                                                   &rpaf_module);

    if (!cfg->enable)
        return DECLINED;

    /* this overcomes an issue when mod_rewrite causes this to get called again
       and the environment value is lost for HTTPS. This is the only thing that
       is lost and we do not need to process any further after restoring the
       value. */
    const char *rpaf_https = apr_table_get(r->connection->notes, "rpaf_https");
    if (rpaf_https) {
        apr_table_set(r->subprocess_env, "HTTPS", rpaf_https);
        return DECLINED;
    }

    /* check if the client_addr is in the allowed proxy IP list */
    if (is_in_array(r->connection->client_addr, cfg->proxy_ips) != 1) {
        if (cfg->forbid_if_not_proxy)
            return HTTP_FORBIDDEN;
        return DECLINED;
    }

    /* check if cfg->headername is set and if it is use
       that instead of X-Forwarded-For by default */
    if (cfg->headername && (fwdvalue = (char *)apr_table_get(r->headers_in, cfg->headername))) {
        //
    } else if (cfg->headername == NULL && (fwdvalue = (char *)apr_table_get(r->headers_in, "X-Forwarded-For"))) {
        //
    } else {
        return DECLINED;
    }

    /* if there was no forwarded for header then we dont do anything */
    if (!fwdvalue)
        return DECLINED;

    apr_array_header_t *arr = apr_array_make(r->pool, 4, sizeof(char *));

    while ((val = strsep(&fwdvalue, ",")) != NULL) {
        /* strip leading and trailing whitespace */
        while(isspace(*val))
            ++val;
        for (i = strlen(val) - 1; i > 0 && isspace(val[i]); i--)
            val[i] = '\0';
        if (rpaf_looks_like_ip(val))
            *(char **)apr_array_push(arr) = apr_pstrdup(r->pool, val);
    }

    if (arr->nelts == 0)
        return DECLINED;

    if ((last_val = last_not_in_array(r, arr, cfg->proxy_ips)) == NULL)
        return DECLINED;

    rpaf_cleanup_rec *rcr = (rpaf_cleanup_rec *)apr_pcalloc(r->pool, sizeof(rpaf_cleanup_rec));
    rcr->old_ip = apr_pstrdup(r->connection->pool, r->connection->client_ip);
    rcr->r = r;
    apr_pool_cleanup_register(r->pool, (void *)rcr, rpaf_cleanup, apr_pool_cleanup_null);
    r->connection->client_ip = apr_pstrdup(r->connection->pool, last_val);

    tmppool = r->connection->client_addr->pool;
    tmpport = r->connection->client_addr->port;
    apr_sockaddr_t *tmpsa;
    int ret = apr_sockaddr_info_get(&tmpsa, r->connection->client_ip, APR_UNSPEC, tmpport, 0, tmppool);
    if (ret == APR_SUCCESS)
        memcpy(r->connection->client_addr, tmpsa, sizeof(apr_sockaddr_t));
    if (cfg->sethostname) {
        const char *hostvalue;
        if ((hostvalue = apr_table_get(r->headers_in, "X-Forwarded-Host")) ||
            (hostvalue = apr_table_get(r->headers_in, "X-Host"))) {
            apr_array_header_t *arr = apr_array_make(r->pool, 0, sizeof(char*));
            while (*hostvalue && (val = ap_get_token(r->pool, &hostvalue, 1))) {
                *(char **)apr_array_push(arr) = apr_pstrdup(r->pool, val);
                if (*hostvalue != '\0')
                  ++hostvalue;
            }

            apr_table_set(r->headers_in, "Host", apr_pstrdup(r->pool, ((char **)arr->elts)[((arr->nelts)-1)]));
            r->hostname = apr_pstrdup(r->pool, ((char **)arr->elts)[((arr->nelts)-1)]);
            ap_update_vhost_from_headers(r);
        }
    }

    if (cfg->sethttps) {
        const char *httpsvalue, *scheme;
        if ((httpsvalue = apr_table_get(r->headers_in, "X-Forwarded-HTTPS")) ||
            (httpsvalue = apr_table_get(r->headers_in, "X-HTTPS"))) {
            apr_table_set(r->connection->notes, "rpaf_https", httpsvalue);
            apr_table_set(r->subprocess_env   , "HTTPS"     , httpsvalue);

            scheme = cfg->https_scheme;
        } else if ((httpsvalue = apr_table_get(r->headers_in, "X-Forwarded-Proto"))
                   && (strcmp(httpsvalue, cfg->https_scheme) == 0)) {
            apr_table_set(r->connection->notes, "rpaf_https", "on");
            apr_table_set(r->subprocess_env   , "HTTPS"     , "on");
            scheme = cfg->https_scheme;
        } else {
            scheme = cfg->orig_scheme;
        }
        #if AP_SERVER_MINORVERSION_NUMBER > 1 && AP_SERVER_PATCHLEVEL_NUMBER > 2
        r->server->server_scheme = scheme;
        #endif
    }

     if (cfg->setport) {
        const char *portvalue;
        if ((portvalue = apr_table_get(r->headers_in, "X-Forwarded-Port")) ||
            (portvalue = apr_table_get(r->headers_in, "X-Port"))) {
            r->server->port    = atoi(portvalue);
            r->parsed_uri.port = r->server->port;
        } else {
            r->server->port = cfg->orig_port;
        }
    }

    return DECLINED;
}