コード例 #1
0
ファイル: mod_rpaf.c プロジェクト: taladar/mod_rpaf
static char *last_not_in_array(request_rec *r, apr_array_header_t *forwarded_for,
                               apr_array_header_t *proxy_ips) {
    apr_sockaddr_t *sa;
    apr_status_t rv;
    char **fwd_ips, *proxy_list;
    int i, earliest_legit_i = 0;

    proxy_list = apr_pstrdup(r->pool, r->DEF_IP);
    fwd_ips = (char **)forwarded_for->elts;

    for (i = (forwarded_for->nelts); i > 0; ) {
        i--;
        rv = apr_sockaddr_info_get(&sa, fwd_ips[i], APR_UNSPEC, 0, 0, r->pool);
        if (rv == APR_SUCCESS) {
            earliest_legit_i = i;
            if (!is_in_array(sa, proxy_ips))
                break;

            proxy_list = apr_pstrcat(r->pool, proxy_list, ", ", fwd_ips[i], NULL);
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
                          "mod_rpaf: forwarded-for list entry of %s is not a valid IP", fwd_ips[i]);
        }
    }

    if (i > 0 || rv == APR_SUCCESS || earliest_legit_i) {
        /* remoteip-proxy-ip_list r->notes entry is forward compatible with Apache2.4 mod_remoteip*/
        apr_table_set(r->notes, "remoteip-proxy-ip-list", proxy_list);
        return fwd_ips[earliest_legit_i];
    }
    else {
        return NULL;
    }
}
コード例 #2
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;
}
コード例 #3
0
ファイル: mod_rpaf.c プロジェクト: zakx/mod_rpaf
static char* last_not_in_array(apr_pool_t *pool,
                               apr_array_header_t *forwarded_for,
                               apr_array_header_t *proxy_ips) {
    int i;
    for (i = (forwarded_for->nelts)-1; i > 0; i--) {
        if (!is_in_array(pool, ((char **)forwarded_for->elts)[i], proxy_ips))
           break;
    }
    return ((char **)forwarded_for->elts)[i];
}
コード例 #4
0
ファイル: mod_rpaf-2.0.c プロジェクト: buzztaiki/mod_rpaf-0.6
static char *extract_ip(apr_array_header_t *arr, apr_array_header_t *proxy_ips, int recursive) {
    int i;
    char **ips = (char **)arr->elts;
    int len = arr->nelts;
    ap_assert(len >= 0);

    if (!recursive) return ips[len-1];
    for (i = len-1; i >= 0; i--) {
        if (!is_in_array(ips[i], proxy_ips)) {
            return ips[i];
        }
    }
    return ips[0];
}
コード例 #5
0
void put_doc(Map_t *map, char *key, int docID) {

  /* Daca bucketul este gol, insereaza primul nod */
  Node_t *bucket = map->buckets[hash((unsigned char*)key) % map->size];
  if (!bucket) {
    bucket = (Node_t*)malloc(sizeof(Node_t));
    bucket->data = initialize_entry(key, docID);
    bucket->next = NULL;
    map->buckets[hash((unsigned char*)key) % map->size] = bucket;
  }

  /* Altfel, adauga docID la Array_t-ul corespunzator cheii;
   * creeaza o noua intrare daca cheia nu exista */
  else {
    int found = 0;
    int pos;
    Node_t *prev;
    prev = bucket;
    while (bucket) {
      if (strcmp(bucket->data->word, key) == 0) {
        found = 1;
        if (!is_in_array(bucket->data->documents, docID)) {
          if (bucket->data->documents.n == bucket->data->documents.cap - 1) {
            bucket->data->documents.cap *= 2;
            bucket->data->documents.v = realloc(bucket->data->documents.v, 
                                        bucket->data->documents.cap);
          }
          bucket->data->documents.n += 1;
          pos = bucket->data->documents.n;
          bucket->data->documents.v[pos] = docID;
        }
        break;
      }
      prev = bucket;
      bucket = bucket->next;
    }
    if (!found) {
      Node_t *new_node = (Node_t*)malloc(sizeof(Node_t));
      new_node->data = initialize_entry(key, docID);
      new_node->next = NULL;
      prev->next = new_node;
    }
  }
}
コード例 #6
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;
}
コード例 #7
0
ファイル: bloom-test.c プロジェクト: Gurut/gross
int
main(int argc, char *argv[])
{
	int i, j, k;
	double c = 0.001;
	int error_count = 0;
	int tmperr = 0;
	char test[512] = { 0x00 };
	char buf[MAXLINELEN];
	gross_ctx_t myctx = { 0x00 };

	bloom_filter_t *bf;
	bloom_filter_t *bf2;

	bloom_filter_group_t *bfg;

	bloom_ring_queue_t *brq;

	ctx = &myctx;
        memset(ctx, 0, sizeof(gross_ctx_t));
	
	printf("Check: bloom\n");

	printf("  Checking optimal size calculations...");
	fflush(stdout);
	tmperr = error_count;
	if (optimal_size(1000, c) != 10) {
		error_count++;
		if (argc > 2)
			printf("  Error: size 1000\n");
	}
	if (optimal_size(2000, c) != 11) {
		error_count++;
		if (argc > 2)
			printf("  Error: size 2000\n");
	}
	if (optimal_size(3000, c) != 12) {
		error_count++;
		if (argc > 2)
			printf("  Error: size 3000\n");
	}
	if (optimal_size(4000, c) != 12) {
		error_count++;
		if (argc > 2)
			printf("  Error: size 4000\n");
	}
	if (optimal_size(5000, c) != 13) {
		error_count++;
		if (argc > 2)
			printf("  Error: size 5000\n");
	}
	if (optimal_size(8000, c) != 13) {
		error_count++;
		if (argc > 2)
			printf("  Error: size 8000\n");
	}
	if (optimal_size(9000, c) != 14) {
		error_count++;
		if (argc > 2)
			printf("  Error: size 9000\n");
	}
	if (optimal_size(16000, c) != 14) {
		error_count++;
		if (argc > 2)
			printf("  Error: size 16000\n");
	}
	if (optimal_size(17000, c) != 15) {
		error_count++;
		if (argc > 2)
			printf("  Error: size 17000\n");
	}
	if (optimal_size(32000, c) != 15) {
		error_count++;
		if (argc > 2)
			printf("  Error: size 32000\n");
	}
	if (optimal_size(33000, c) != 16) {
		error_count++;
		if (argc > 2)
			printf("  Error: size 33000\n");
	}
	if (optimal_size(65000, c) != 16) {
		error_count++;
		if (argc > 2)
			printf("  Error: size 65000\n");
	}
	if (optimal_size(66000, c) != 17) {
		error_count++;
		if (argc > 2)
			printf("  Error: size 66000\n");
	}
	if (optimal_size(131000, c) != 17) {
		error_count++;
		if (argc > 2)
			printf("  Error: size 131000\n");
	}
	if (optimal_size(132000, c) != 18) {
		error_count++;
		if (argc > 2)
			printf("  Error: size 132000\n");
	}
	if (optimal_size(262000, c) != 18) {
		error_count++;
		if (argc > 2)
			printf("  Error: size 262000\n");
	}
	if (optimal_size(263000, c) != 19) {
		error_count++;
		if (argc > 2)
			printf("  Error: size 263000\n");
	}
	if (optimal_size(524000, c) != 19) {
		error_count++;
		if (argc > 2)
			printf("  Error: size 524000\n");
	}
	if (optimal_size(525000, c) != 20) {
		error_count++;
		if (argc > 2)
			printf("  Error: size 525000\n");
	}
	if (optimal_size(1048000, c) != 20) {
		error_count++;
		if (argc > 2)
			printf("  Error: size 1048000\n");
	}
	if (optimal_size(1049000, c) != 21) {
		error_count++;
		if (argc > 2)
			printf("  Error: size 1049000\n");
	}
	PRINTSTATUS;
	
	printf("  Testing with a 7-bit filter...");
	fflush(stdout);
	tmperr = error_count;
	if (argc > 1 && strcmp(argv[1], "visualize") == 0) {
		printf("\n");
		/* 7-bit filter */
		bf = create_bloom_filter(7);
		for (i = 0; i < 83; i++) {
			sprintf(test, "%d", i);
			insert_digest(bf, sha256_string(test));
			debug_print_filter(bf, TRUE);
		}
		release_bloom_filter(bf);
	}

	/* Test insertion with a 7-bit filter */
	bf = create_bloom_filter(7);
	for (i = 0; i < 16; i++) {
		sprintf(test, "%d", i);
		insert_digest(bf, sha256_string(test));
		if (!is_in_array(bf, sha256_string(test))) {
			error_count++;
			if (argc > 2)
				printf("\nError: %s not in array", test);
		}
	}

	/* Test false positives */
	for (i = 17; i < 32; i++) {
		sprintf(test, "%d", i);
		if (is_in_array(bf, sha256_string(test))) {
			error_count++;
			if (argc > 2)
				printf("\nError: %s is in array", test);
		}
	}
	release_bloom_filter(bf);
	PRINTSTATUS;

	printf("  Testing merging of filters...");
	fflush(stdout);
	tmperr = error_count;
	/* Test filter merge */

	bf = create_bloom_filter(7);
	bf2 = create_bloom_filter(7);

	if (is_in_array(bf, sha256_string("omena"))) {
		error_count++;
		if (argc > 2)
			printf("\nError: 'omena' in array bf");
	}			/* initially empty */
	insert_digest(bf, sha256_string("omena"));

	if (argc > 1 && strcmp(argv[1], "visualize") == 0) {
		printf("\nbf after 'omena': ");
		debug_print_filter(bf, FALSE);
	}

	if (is_in_array(bf2, sha256_string("omena"))) {
		error_count++;
		if (argc > 2)
			printf("\nError: 'omena' in array bf2");
	}			/* so is the other one */
	insert_digest(bf2, sha256_string("luumu"));
	if (argc > 1 && strcmp(argv[1], "visualize") == 0) {
		printf("\nbf2 after 'luumu': ");
		debug_print_filter(bf2, FALSE);
	}

	bf2 = add_filter(bf2, bf);
	if (!is_in_array(bf2, sha256_string("omena"))) {
		error_count++;
		if (argc > 2)
			printf("\nError: 'omena' not in array bf2");
	}			/* bf2 should now contain omena */
	if (is_in_array(bf2, sha256_string("appelsiini"))) {
		error_count++;
		if (argc > 2)
			printf("\nError: 'appelsiini' in array bf2");
	}			/* ... but not appelsiini */
	if (argc > 1 && strcmp(argv[1], "visualize") == 0) {
		printf("\nbf2 after merge: ");
		debug_print_filter(bf2, FALSE);
	}

	release_bloom_filter(bf);
	release_bloom_filter(bf2);
	PRINTSTATUS;

	printf("  Testing filter groups...");
	fflush(stdout);
	tmperr = error_count;
	bfg = create_bloom_filter_group(8, 8);	/* 8 filters of 8bit length */

	j = 64;
	for (i = 0; i < j; i++) {
		sprintf(test, "%d", i);
		insert_digest_to_group_member(bfg, (i % (bfg->group_size - 1)) + 1, sha256_string(test));	/* add digests to group members 1..group_size leaving member 0 untouched */
	}

	for (i = 1; i < bfg->group_size; i++) {
		bfg->filter_group[0] = add_filter(bfg->filter_group[0], bfg->filter_group[i]);
	}

	for (i = 0; i < j; i++) {
		sprintf(test, "%d", i);
		if (!is_in_array(bfg->filter_group[0], sha256_string(test))) {
			error_count++;
			if (argc > 2)
				printf("\nError: %s not in array bfg[0]", test);
		}
	}

	if (argc > 1 && strcmp(argv[1], "visualize") == 0) {
		printf("\nbfg[0]: ");
		debug_print_filter(bfg->filter_group[0], FALSE);
	}

	release_bloom_filter_group(bfg);
	PRINTSTATUS;

	printf("  Testing rings...");
	fflush(stdout);
	tmperr = error_count;

	/* Ring queue test */
	/* Ring of 8 10-bit filters */
	brq = build_bloom_ring(8, 21);
	k = 128;

	/* Init */
	for (i = 0; i < k; i++) {
		if (i % (k / 8) == 0)
			rotate_bloom_ring_queue(brq);

		sprintf(test, "%d", i);
		insert_digest_bloom_ring_queue(brq, sha256_string(test));
	}

	/* Test for all inclusion */
	for (i = 0; i < k; i++) {
		sprintf(test, "%d", i);
		if (!is_in_ring_queue(brq, sha256_string(test))) {
			error_count++;
			if (argc > 2)
				printf("\nError: %s not in brq", test);
		}
	}

	/* Test with removal */
	for (i = 0; i < (k / 8); i++) {
		rotate_bloom_ring_queue(brq);
		for (j = i; j < (i + 1) * (k / 8); j++) {
			sprintf(test, "%d", i);
			if (is_in_ring_queue(brq, sha256_string(test))) {
				error_count++;
				if (argc > 2)
					printf("\nError: %s in brq", test);
			}
		}

		for (j = (i + 1) * (k / 8); j < (k / 8); j++) {
			sprintf(test, "%d", i);
			if (!is_in_ring_queue(brq, sha256_string(test))) {
				error_count++;
				if (argc > 2)
					printf("\nError: %s not in brq after removal", test);
			}
		}

	}
	PRINTSTATUS;

	snprintf(buf, MAXLINELEN - 1, "/tmp/test.state.%d", getpid());
	ctx->config.statefile = strdup(buf);
	ctx->config.num_bufs = 8;
	ctx->config.filter_size = 21;
	printf("  Testing statefile %s...", buf);
	fflush(stdout);
	tmperr = error_count;
	create_statefile();

	/* Ring queue test */
	/* Ring of 8 10-bit filters */
	brq = build_bloom_ring(8, 21);
	k = 128;

	/* Init */
	for (i = 0; i < k; i++) {
		if (i % (k / 8) == 0)
			rotate_bloom_ring_queue(brq);

		sprintf(test, "%d", i);
		insert_digest_bloom_ring_queue(brq, sha256_string(test));
	}

	/* Test for all inclusion */
	for (i = 0; i < k; i++) {
		sprintf(test, "%d", i);
		if (!is_in_ring_queue(brq, sha256_string(test))) {
			error_count++;
			if (argc > 2)
				printf("\nError: %s not in brq", test);
		}
	}

	/* Test with removal */
	for (i = 0; i < (k / 8); i++) {
		rotate_bloom_ring_queue(brq);
		for (j = i; j < (i + 1) * (k / 8); j++) {
			sprintf(test, "%d", i);
			if (is_in_ring_queue(brq, sha256_string(test))) {
				error_count++;
				if (argc > 2)
					printf("\nError: %s in brq", test);
			}
		}

		for (j = (i + 1) * (k / 8); j < (k / 8); j++) {
			sprintf(test, "%d", i);
			if (!is_in_ring_queue(brq, sha256_string(test))) {
				error_count++;
				if (argc > 2)
					printf("\nError: %s not in brq after removal", test);
			}
		}

	}
	release_bloom_ring_queue(brq);
	if (unlink(ctx->config.statefile))
		perror("unlink");
	Free(ctx->config.statefile);
	ctx->config.statefile = NULL;
	ctx->config.num_bufs = 8;
	ctx->config.filter_size = 21;
	PRINTSTATUS;

	printf("  Stress test...");
	fflush(stdout);
	tmperr = error_count;
	/* Stress test */
	brq = build_bloom_ring(10, 22);
	for (i = 0; i < 1000000; i++) {
		if ((i % 100000) == 0)
			rotate_bloom_ring_queue(brq);
		sprintf(test, "%d", i);
		insert_digest_bloom_ring_queue(brq, sha256_string(test));
	}

	for (i = 0; i < 1000000; i++) {
		sprintf(test, "%d", i);
		if (!is_in_ring_queue(brq, sha256_string(test))) {
			error_count++;
			if (argc > 2)
				printf("\nError: %s not in brq after removal", test);
		}
	}
	release_bloom_ring_queue(brq);

	PRINTSTATUS;
	
	if (error_count)
		printf("  Total error count: %d\n", error_count);

	return error_count > 0;
}
コード例 #8
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;
}
コード例 #9
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;
}