@@ -1,730 +0,0 @@
-/* ====================================================================
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2004 MaxMind LLC. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes software developed by the
- * MaxMind (http://www.maxmind.com/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "MaxMind" and "GeoIP" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact support@maxmind.com.
- *
- * 5. Products derived from this software may not be called "GeoIP",
- * nor may "MaxMind" appear in their name, without prior written
- * permission of the MaxMind.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- */
-
-/* geoip module
- *
- * Version 1.2.1
- *
- * This module sets an environment variable to the remote country
- * based on the requestor's IP address. It uses the GeoIP library
- * to lookup the country by IP address.
- *
- * Copyright 2004, MaxMind LLC
- * July 12th 2004
- *
- * Initial port Contributed by Corris Randall <corris@cpan.org>
- *
- */
-
-#include "httpd.h"
-#include "http_config.h"
-#include "http_protocol.h"
-#include "http_log.h"
-#include "ap_config.h"
-#include "apr_strings.h"
-#include <GeoIP.h>
-#include <GeoIPCity.h>
-
-typedef struct {
- int GeoIPEnabled;
-} geoip_dir_config_rec;
-
-typedef struct {
- GeoIP **gips;
- int numGeoIPFiles;
- char **GeoIPFilenames;
- int GeoIPEnabled;
- int GeoIPEnableUTF8;
- char GeoIPOutput;
- int GeoIPFlags;
- int *GeoIPFlags2;
- int scanProxyHeaders;
-} geoip_server_config_rec;
-
-static const int GEOIP_NONE = 0;
-static const int GEOIP_DEFAULT = 1;
-static const int GEOIP_NOTES = 2;
-static const int GEOIP_ENV = 4;
-static const int GEOIP_ALL = 6;
-static const int GEOIP_INIT = 7;
-
-static const int GEOIP_UNKNOWN = -1;
-
-char dmacodestr[100];
-char areacodestr[100];
-char latstr[100];
-char lonstr[100];
-const char *netspeedstring;
-
-module AP_MODULE_DECLARE_DATA geoip_module;
-
-/* create a disabled directory entry */
-
-static void *geoip_create_dir_config(apr_pool_t *p, char *d)
-{
-
- geoip_dir_config_rec *dcfg;
-
- dcfg = (geoip_dir_config_rec *) apr_pcalloc(p, sizeof(geoip_dir_config_rec));
- dcfg->GeoIPEnabled = 0;
-
- return dcfg;
-}
-
-
-/* create a standard disabled server entry */
-
-static void *create_geoip_server_config( apr_pool_t *p, server_rec *d )
-{
- geoip_server_config_rec *conf = apr_pcalloc(p, sizeof(geoip_server_config_rec));
- if (!conf){
- return NULL;
- }
-
- conf->gips = NULL;
- conf->numGeoIPFiles = 0;
- conf->GeoIPFilenames = NULL;
- conf->GeoIPEnabled = 0;
- conf->GeoIPEnableUTF8 = 0;
- conf->GeoIPOutput = GEOIP_INIT;
- conf->GeoIPFlags = GEOIP_STANDARD;
- conf->GeoIPFlags2 = NULL;
- conf->scanProxyHeaders = 0;
- return (void *)conf;
-}
-
-
-static apr_status_t
-geoip_cleanup(void *cfgdata)
-{
- int i;
- geoip_server_config_rec *cfg = (geoip_server_config_rec *) cfgdata;
- if (cfg->gips) {
- for (i = 0; i < cfg->numGeoIPFiles; i++) {
- if (cfg->gips[i]) {
- GeoIP_delete(cfg->gips[i]);
- cfg->gips[i] = NULL;
- }
- }
- free(cfg->gips);
- cfg->gips = NULL;
- }
- return APR_SUCCESS;
-}
-
-/* initialize geoip once per server ( even virtal server! ) */
-static void
-geoip_server_init(apr_pool_t * p, server_rec * s)
-{
- geoip_server_config_rec *cfg;
- int i;
- cfg = (geoip_server_config_rec *)
- ap_get_module_config(s->module_config, &geoip_module);
-
- if (!cfg->gips) {
- if (cfg->GeoIPFilenames != NULL) {
- cfg->gips = malloc(sizeof(GeoIP *) * cfg->numGeoIPFiles);
- for (i = 0; i < cfg->numGeoIPFiles; i++) {
- cfg->gips[i] = GeoIP_open(cfg->GeoIPFilenames[i], (cfg->GeoIPFlags2[i] == GEOIP_UNKNOWN) ? cfg->GeoIPFlags : cfg->GeoIPFlags2[i]);
-
- if (cfg->gips[i]) {
- if (cfg->GeoIPEnableUTF8) {
- GeoIP_set_charset(cfg->gips[i], GEOIP_CHARSET_UTF8);
- }
- }
- else {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "[mod_geoip]: Error while opening data file %s", cfg->GeoIPFilenames[i]);
- continue;
- }
- }
- }
- else {
- cfg->gips = malloc(sizeof(GeoIP *));
- cfg->gips[0] = GeoIP_new(GEOIP_STANDARD);
- if (!cfg->gips[0]) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "[mod_geoip]: Error while opening data file");
- }
- cfg->numGeoIPFiles = 1;
- }
- }
-
- apr_pool_cleanup_register(p, (void *) cfg, geoip_cleanup, geoip_cleanup);
-
-}
-
-
-static void
-geoip_child_init(apr_pool_t * p, server_rec * s)
-{
- geoip_server_config_rec *cfg;
- int i, flags;
-
- cfg = (geoip_server_config_rec *)
- ap_get_module_config(s->module_config, &geoip_module);
-
- if (cfg->gips) {
- if (cfg->GeoIPFilenames != NULL) {
- for (i = 0; i < cfg->numGeoIPFiles; i++) {
- flags = (cfg->GeoIPFlags2[i] == GEOIP_UNKNOWN) ? cfg->GeoIPFlags : cfg->GeoIPFlags2[i];
- if (flags & (GEOIP_MEMORY_CACHE | GEOIP_MMAP_CACHE))
- continue;
- if (cfg->gips[i]) {
- GeoIP_delete(cfg->gips[i]);
- }
- cfg->gips[i] = GeoIP_open(cfg->GeoIPFilenames[i], flags);
-
- if (cfg->gips[i]) {
- if (cfg->GeoIPEnableUTF8) {
- GeoIP_set_charset(cfg->gips[i], GEOIP_CHARSET_UTF8);
- }
- }
- else {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "[mod_geoip]: Error while opening data file %s", cfg->GeoIPFilenames[i]);
- continue;
- }
- }
- }
- else {
- if (cfg->gips[0])
- GeoIP_delete(cfg->gips[0]);
- cfg->gips[0] = GeoIP_new(GEOIP_STANDARD);
- if (!cfg->gips[0]) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "[mod_geoip]: Error while opening data file");
- }
- cfg->numGeoIPFiles = 1;
- }
- }
-}
-
-/* map into the first apache */
-static int
-geoip_post_config(
- apr_pool_t * p, apr_pool_t * plog,
- apr_pool_t * ptemp, server_rec * s)
-{
-
- geoip_server_init(p, s);
- return OK;
-}
-
-
-static int geoip_header_parser(request_rec *r);
-
-static int geoip_post_read_request(request_rec *r){
- geoip_server_config_rec *cfg;
- cfg = ap_get_module_config(r->server->module_config, &geoip_module);
-
- if ( !cfg )
- return DECLINED;
-
- if ( !cfg->GeoIPEnabled )
- return DECLINED;
-
- return geoip_header_parser(r);
-}
-
-
-static int
-geoip_per_dir(request_rec * r)
-{
-
- geoip_dir_config_rec *dcfg;
-
- geoip_server_config_rec *cfg =
- ap_get_module_config(r->server->module_config, &geoip_module);
- if (cfg && cfg->GeoIPEnabled)
- return DECLINED;
-
- dcfg = ap_get_module_config(r->per_dir_config, &geoip_module);
- if (!dcfg)
- return DECLINED;
-
- if (!dcfg->GeoIPEnabled)
- return DECLINED;
-
- return geoip_header_parser(r);
-}
-
-
-static int
-geoip_header_parser(request_rec * r)
-{
- char *orgorisp;
- char *ipaddr;
- short int country_id;
- GeoIP *gip;
- const char *continent_code;
- const char *country_code;
- const char *country_name;
- const char *region_name;
-
- geoip_server_config_rec *cfg;
-
- unsigned char databaseType;
- GeoIPRecord *gir;
- GeoIPRegion *giregion;
- int i;
- int netspeed;
- /* For splitting proxy headers */
- char *ipaddr_ptr = 0;
- char *comma_ptr;
- cfg = ap_get_module_config(r->server->module_config, &geoip_module);
-
- if (!cfg)
- return DECLINED;
-
- if (!cfg->scanProxyHeaders) {
- ipaddr = r->connection->remote_ip;
- }
- else {
- ap_add_common_vars(r);
- if (apr_table_get(r->subprocess_env, "HTTP_CLIENT_IP")) {
- ipaddr_ptr = (char *) apr_table_get(r->subprocess_env, "HTTP_CLIENT_IP");
- }
- else if (apr_table_get(r->subprocess_env, "HTTP_X_FORWARDED_FOR")) {
- ipaddr_ptr = (char *) apr_table_get(r->subprocess_env, "HTTP_X_FORWARDED_FOR");
- }
- else if (apr_table_get(r->headers_in, "X-Forwarded-For")) {
- ipaddr_ptr = (char *) apr_table_get(r->headers_in, "X-Forwarded-For");
- }
- else if (apr_table_get(r->subprocess_env, "HTTP_REMOTE_ADDR")) {
- ipaddr_ptr = (char *) apr_table_get(r->subprocess_env, "HTTP_REMOTE_ADDR");
- }
- if (!ipaddr_ptr) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r->server, "[mod_geoip]: Error while getting ipaddr from proxy headers. Using REMOTE_ADDR.");
- ipaddr = r->connection->remote_ip;
- }
- else {
- ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r->server, "[mod_geoip]: IPADDR_PTR: %s", ipaddr_ptr);
- /*
- * Check to ensure that the HTTP_CLIENT_IP or
- * X-Forwarded-For header is not a comma separated
- * list of addresses, which would cause mod_geoip to
- * return no country code. If the header is a comma
- * separated list, return the first IP address in the
- * list, which is (hopefully!) the real client IP.
- */
- ipaddr = (char *) calloc(16, sizeof(char));
- strncpy(ipaddr, ipaddr_ptr, 15);
- comma_ptr = strchr(ipaddr, ',');
- if (comma_ptr != 0)
- *comma_ptr = '\0';
- }
- }
-
-/* this block should be removed! */
-#if 1
- if (!cfg->gips) {
- if (cfg->GeoIPFilenames != NULL) {
- cfg->gips = malloc(sizeof(GeoIP *) * cfg->numGeoIPFiles);
- for (i = 0; i < cfg->numGeoIPFiles; i++) {
- cfg->gips[i] = GeoIP_open(cfg->GeoIPFilenames[i], (cfg->GeoIPFlags2[i] == GEOIP_UNKNOWN) ? cfg->GeoIPFlags : cfg->GeoIPFlags2[i]);
-
- if (cfg->gips[i]) {
- if (cfg->GeoIPEnableUTF8) {
- GeoIP_set_charset(cfg->gips[i], GEOIP_CHARSET_UTF8);
- }
- }
- else {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "[mod_geoip]: Error while opening data file %s", cfg->GeoIPFilenames[i]);
- return DECLINED;
- }
- }
- }
- else {
- cfg->gips = malloc(sizeof(GeoIP *));
- cfg->gips[0] = GeoIP_new(GEOIP_STANDARD);
- if (!cfg->gips[0]) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "[mod_geoip]: Error while opening data file");
- return DECLINED;
- }
- cfg->numGeoIPFiles = 1;
- }
- }
-#endif
-
- if (cfg->GeoIPOutput & GEOIP_NOTES) {
- apr_table_setn(r->notes, "GEOIP_ADDR", ipaddr);
- }
- if (cfg->GeoIPOutput & GEOIP_ENV) {
- apr_table_setn(r->subprocess_env, "GEOIP_ADDR", ipaddr);
- }
-
- for (i = 0; i < cfg->numGeoIPFiles; i++) {
-
- /*
- * skip database handles that can not be opned for some
- * reason
- */
- if (cfg->gips[i] == NULL)
- continue;
-
- databaseType = cfg->gips[i] ? GeoIP_database_edition(cfg->gips[i]) : -1; /* -1 is "magic value"
- * in case file not
- * found */
- switch (databaseType) {
- case GEOIP_NETSPEED_EDITION:
- netspeed = GeoIP_id_by_addr(cfg->gips[i], ipaddr);
- if (netspeed == GEOIP_UNKNOWN_SPEED) {
- netspeedstring = "unknown";
- }
- else if (netspeed == GEOIP_DIALUP_SPEED) {
- netspeedstring = "dialup";
- }
- else if (netspeed == GEOIP_CABLEDSL_SPEED) {
- netspeedstring = "cabledsl";
- }
- else if (netspeed == GEOIP_CORPORATE_SPEED) {
- netspeedstring = "corporate";
- }
- if (cfg->GeoIPOutput & GEOIP_NOTES) {
- apr_table_setn(r->notes, "GEOIP_NETSPEED", netspeedstring);
- }
- if (cfg->GeoIPOutput & GEOIP_ENV) {
- apr_table_setn(r->subprocess_env, "GEOIP_NETSPEED", netspeedstring);
- }
- break;
- case GEOIP_COUNTRY_EDITION:
- /* Get the Country ID */
- country_id = GeoIP_country_id_by_addr(cfg->gips[i], ipaddr);
-
- if ( country_id > 0 ) {
- /* Lookup the Code and the Name with the ID */
- continent_code = GeoIP_country_continent[country_id];
- country_code = GeoIP_country_code[country_id];
- country_name = GeoIP_country_name[country_id];
-
- if (cfg->numGeoIPFiles == 0) {
- cfg->numGeoIPFiles = 0;
- }
- if (cfg->GeoIPFilenames == 0) {
- cfg->GeoIPFilenames = 0;
- }
- /* Set it for our user */
- if (cfg->GeoIPOutput & GEOIP_NOTES) {
- apr_table_setn(r->notes, "GEOIP_CONTINENT_CODE", continent_code);
- apr_table_setn(r->notes, "GEOIP_COUNTRY_CODE", country_code);
- apr_table_setn(r->notes, "GEOIP_COUNTRY_NAME", country_name);
- }
- if (cfg->GeoIPOutput & GEOIP_ENV) {
- apr_table_setn(r->subprocess_env, "GEOIP_CONTINENT_CODE", continent_code);
- apr_table_setn(r->subprocess_env, "GEOIP_COUNTRY_CODE", country_code);
- apr_table_setn(r->subprocess_env, "GEOIP_COUNTRY_NAME", country_name);
- }
- }
- break;
- case GEOIP_REGION_EDITION_REV0:
- case GEOIP_REGION_EDITION_REV1:
- giregion = GeoIP_region_by_name(cfg->gips[i], ipaddr);
- if (giregion != NULL) {
- if (cfg->GeoIPOutput & GEOIP_NOTES) {
- apr_table_set(r->notes, "GEOIP_COUNTRY_CODE", giregion->country_code);
- apr_table_set(r->notes, "GEOIP_REGION", giregion->region);
- }
- if (cfg->GeoIPOutput & GEOIP_ENV) {
- apr_table_set(r->subprocess_env, "GEOIP_COUNTRY_CODE", giregion->country_code);
- apr_table_set(r->subprocess_env, "GEOIP_REGION", giregion->region);
- }
- GeoIPRegion_delete(giregion);
- }
- break;
- case GEOIP_CITY_EDITION_REV0:
- case GEOIP_CITY_EDITION_REV1:
- gir = GeoIP_record_by_addr(cfg->gips[i], ipaddr);
- if (gir != NULL) {
- sprintf(dmacodestr, "%d", gir->dma_code);
- sprintf(areacodestr, "%d", gir->area_code);
- if (cfg->GeoIPOutput & GEOIP_NOTES) {
- apr_table_setn(r->notes, "GEOIP_CONTINENT_CODE", gir->continent_code);
- apr_table_setn(r->notes, "GEOIP_COUNTRY_CODE", gir->country_code);
- apr_table_setn(r->notes, "GEOIP_COUNTRY_NAME", gir->country_name);
- if (gir->region != NULL) {
- apr_table_set(r->notes, "GEOIP_REGION", gir->region);
- region_name = gip->GeoIP_region_name_by_code(gir->country_code, gir->region);
- if ( region_name != NULL ){
- apr_table_set(r->notes, "GEOIP_REGION_NAME", region_name);
- }
- }
- if (gir->city != NULL) {
- apr_table_set(r->notes, "GEOIP_CITY", gir->city);
- }
- apr_table_setn(r->notes, "GEOIP_DMA_CODE", dmacodestr);
- apr_table_setn(r->notes, "GEOIP_AREA_CODE", areacodestr);
- }
- if (cfg->GeoIPOutput & GEOIP_ENV) {
- apr_table_setn(r->subprocess_env, "GEOIP_CONTINENT_CODE", gir->continent_code);
- apr_table_setn(r->subprocess_env, "GEOIP_COUNTRY_CODE", gir->country_code);
- apr_table_setn(r->subprocess_env, "GEOIP_COUNTRY_NAME", gir->country_name);
- if (gir->region != NULL) {
- apr_table_set(r->subprocess_env, "GEOIP_REGION", gir->region);
- region_name = gip->GeoIP_region_name_by_code(gir->country_code, gir->region);
- if ( region_name != NULL ){
- apr_table_set(r->subprocess_env, "GEOIP_REGION_NAME", region_name);
- }
- }
- if (gir->city != NULL) {
- apr_table_set(r->subprocess_env, "GEOIP_CITY", gir->city);
- }
- apr_table_setn(r->subprocess_env, "GEOIP_DMA_CODE", dmacodestr);
- apr_table_setn(r->subprocess_env, "GEOIP_AREA_CODE", areacodestr);
- }
- sprintf(latstr, "%f", gir->latitude);
- sprintf(lonstr, "%f", gir->longitude);
- if (cfg->GeoIPOutput & GEOIP_NOTES) {
- apr_table_setn(r->notes, "GEOIP_LATITUDE", latstr);
- }
- if (cfg->GeoIPOutput & GEOIP_ENV) {
- apr_table_setn(r->subprocess_env, "GEOIP_LATITUDE", latstr);
- }
- if (cfg->GeoIPOutput & GEOIP_NOTES) {
- apr_table_setn(r->notes, "GEOIP_LONGITUDE", lonstr);
- }
- if (cfg->GeoIPOutput & GEOIP_ENV) {
- apr_table_setn(r->subprocess_env, "GEOIP_LONGITUDE", lonstr);
- }
- if (gir->postal_code != NULL) {
- if (cfg->GeoIPOutput & GEOIP_NOTES) {
- apr_table_set(r->notes, "GEOIP_POSTAL_CODE", gir->postal_code);
- }
- if (cfg->GeoIPOutput & GEOIP_ENV) {
- apr_table_set(r->subprocess_env, "GEOIP_POSTAL_CODE", gir->postal_code);
- }
- }
- GeoIPRecord_delete(gir);
- }
- break;
- case GEOIP_ORG_EDITION:
- orgorisp = GeoIP_name_by_addr(cfg->gips[i], ipaddr);
- if (orgorisp != NULL) {
- if (cfg->GeoIPOutput & GEOIP_NOTES) {
- apr_table_setn(r->notes, "GEOIP_ORGANIZATION", orgorisp);
- }
- if (cfg->GeoIPOutput & GEOIP_ENV) {
- apr_table_setn(r->subprocess_env, "GEOIP_ORGANIZATION", orgorisp);
- }
- }
- break;
- case GEOIP_ISP_EDITION:
- orgorisp = GeoIP_name_by_addr(cfg->gips[i], ipaddr);
- if (orgorisp != NULL) {
- if (cfg->GeoIPOutput & GEOIP_NOTES) {
- apr_table_setn(r->notes, "GEOIP_ISP", orgorisp);
- }
- if (cfg->GeoIPOutput & GEOIP_ENV) {
- apr_table_setn(r->subprocess_env, "GEOIP_ISP", orgorisp);
- }
- }
- break;
- }
- }
-
- return OK;
-}
-
-
-static const char *geoip_scanproxy(cmd_parms *cmd, void *dummy, int arg)
-{
- geoip_server_config_rec *conf = (geoip_server_config_rec *)
- ap_get_module_config(cmd->server->module_config, &geoip_module);
-
- if (!conf)
- return "mod_geoip: server structure not allocated";
-
- conf->scanProxyHeaders = arg;
- return NULL;
-}
-
-static const char *
-set_geoip_enable(cmd_parms * cmd, void *dummy, int arg)
-{
- geoip_server_config_rec *conf;
-
- /* is per directory config? */
- if (cmd->path) {
- geoip_dir_config_rec *dcfg = dummy;
- dcfg->GeoIPEnabled = arg;
- return NULL;
- }
- /* no then it is server config */
- conf = (geoip_server_config_rec *)
- ap_get_module_config(cmd->server->module_config, &geoip_module);
-
- if (!conf)
- return "mod_geoip: server structure not allocated";
-
- conf->GeoIPEnabled = arg;
- return NULL;
-}
-
-static const char *set_geoip_enable_utf8(cmd_parms *cmd, void *dummy, int arg)
-{
- geoip_server_config_rec *conf = (geoip_server_config_rec *)
- ap_get_module_config(cmd->server->module_config, &geoip_module);
-
- if (!conf)
- return "mod_geoip: server structure not allocated";
-
- conf->GeoIPEnableUTF8 = arg;
- return NULL;
-}
-
-
-static const char *set_geoip_filename(cmd_parms *cmd, void *dummy, const char *filename,const char *arg2)
-{
- int i;
- geoip_server_config_rec *conf = (geoip_server_config_rec *)
- ap_get_module_config(cmd->server->module_config, &geoip_module);
-
- if ( ! filename )
- return NULL;
-
- i = conf->numGeoIPFiles;
- conf->numGeoIPFiles++;
- conf->GeoIPFilenames = realloc(conf->GeoIPFilenames, conf->numGeoIPFiles * sizeof(char *));
- conf->GeoIPFilenames[i] = (char *)apr_pstrdup(cmd->pool,filename);
- conf->GeoIPFlags2 = realloc(conf->GeoIPFlags2, conf->numGeoIPFiles * sizeof(int));
- if (arg2 == NULL){
- conf->GeoIPFlags2[i] = GEOIP_UNKNOWN;
- } else if (!strcmp(arg2, "Standard")){
- conf->GeoIPFlags2[i] = GEOIP_STANDARD;
- } else if (!strcmp(arg2, "MemoryCache")){
- conf->GeoIPFlags2[i] = GEOIP_MEMORY_CACHE;
- } else if (!strcmp(arg2, "CheckCache")){
- conf->GeoIPFlags2[i] = GEOIP_CHECK_CACHE;
- } else if (!strcmp(arg2, "IndexCache")){
- conf->GeoIPFlags2[i] = GEOIP_INDEX_CACHE;
- } else if (!strcmp(arg2, "MMapCache")){
- conf->GeoIPFlags2[i] = GEOIP_MMAP_CACHE;
- }
- return NULL;
-}
-
-static const char *set_geoip_output(cmd_parms *cmd, void *dummy,const char *arg) {
- geoip_server_config_rec *cfg = (geoip_server_config_rec *) ap_get_module_config(cmd->server->module_config, &geoip_module);
-
- if (cfg->GeoIPOutput & GEOIP_DEFAULT) {
- /* was set to default, clear so can be reset with user specified values */
- cfg->GeoIPOutput = GEOIP_NONE;
- }
- if (!strcmp(arg, "Notes")) {
- cfg->GeoIPOutput |= GEOIP_NOTES;
- } else if (!strcmp(arg, "Env")) {
- cfg->GeoIPOutput |= GEOIP_ENV;
- } else if (!strcmp(arg, "All")) {
- cfg->GeoIPOutput |= GEOIP_ALL;
- }
- return NULL;
-}
-
-static void *make_geoip(apr_pool_t *p, server_rec *d)
-{
- geoip_server_config_rec *dcfg;
-
- dcfg = (geoip_server_config_rec *) apr_pcalloc(p, sizeof(geoip_server_config_rec));
- dcfg->gips = NULL;
- dcfg->numGeoIPFiles = 0;
- dcfg->GeoIPFilenames = NULL;
- dcfg->GeoIPEnabled = 0;
- dcfg->GeoIPEnableUTF8 = 0;
- dcfg->GeoIPOutput = GEOIP_INIT;
- dcfg->GeoIPFlags = GEOIP_STANDARD;
- dcfg->GeoIPFlags2 = NULL;
- return dcfg;
-}
-
-
-static const command_rec geoip_cmds[] =
-{
- AP_INIT_FLAG("GeoIPScanProxyHeaders", geoip_scanproxy, NULL, RSRC_CONF, "Get IP from HTTP_CLIENT IP or X-Forwarded-For"),
- AP_INIT_FLAG("GeoIPEnable", set_geoip_enable, NULL, RSRC_CONF | OR_FILEINFO, "Turn on mod_geoip"),
- AP_INIT_FLAG("GeoIPEnableUTF8", set_geoip_enable_utf8, NULL, RSRC_CONF, "Turn on utf8 characters for city names"),
- AP_INIT_TAKE12("GeoIPDBFile", set_geoip_filename, NULL, RSRC_CONF, "Path to GeoIP Data File"),
- AP_INIT_ITERATE("GeoIPOutput", set_geoip_output, NULL, RSRC_CONF, "Specify output method(s)"),
- {NULL}
-};
-
-
-static void geoip_register_hooks(apr_pool_t *p)
-{
- /* make sure we run before mod_rewrite's handler */
- static const char * const aszSucc[]={ "mod_setenvif.c", "mod_rewrite.c", NULL };
-
- /* we have two entry points, the header_parser hook, right before
- * the authentication hook used for Dirctory specific enabled geoiplookups
- * or right before directory rewrite rules.
- */
- ap_hook_header_parser( geoip_per_dir, NULL, aszSucc, APR_HOOK_FIRST );
-
- /* and the servectly wide hook, after reading the request. Perfecly
- * suitable to serve serverwide mod_rewrite actions
- */
- ap_hook_post_read_request( geoip_post_read_request, NULL, aszSucc, APR_HOOK_MIDDLE );
-
- /* setup our childs GeoIP database once for every child */
- ap_hook_child_init( geoip_child_init, NULL, NULL, APR_HOOK_MIDDLE );
-
-
- /* static const char * const list[]={ "mod_geoip.c", NULL }; */
- /* mmap the database(s) into the master process */
- ap_hook_post_config( geoip_post_config, NULL, NULL, APR_HOOK_MIDDLE );
-
-}
-
-
-/* Dispatch list for API hooks */
-module AP_MODULE_DECLARE_DATA geoip_module = {
- STANDARD20_MODULE_STUFF,
- geoip_create_dir_config, /* create per-dir config structures */
- NULL, /* merge per-dir config structures */
- make_geoip, /* create per-server config structures */
- NULL, /* merge per-server config structures */
- geoip_cmds, /* table of config file commands */
- geoip_register_hooks /* register hooks */
-};
-
|
@@ -49,7 +49,7 @@
/* geoip module
*
- * Version 1.2.5
+ * Version 1.2.7
*
* This module sets an environment variable to the remote country
* based on the requestor's IP address. It uses the GeoIP library
@@ -85,6 +85,7 @@
int GeoIPFlags;
int *GeoIPFlags2;
int scanProxyHeaders;
+ int use_last_x_forwarded_for_ip;
} geoip_server_config_rec;
static const int GEOIP_NONE = 0;
@@ -96,7 +97,7 @@
static const int GEOIP_UNKNOWN = -1;
-char dmacodestr[100];
+char metrocodestr[100];
char areacodestr[100];
char latstr[100];
char lonstr[100];
@@ -136,6 +137,7 @@
conf->GeoIPFlags = GEOIP_STANDARD;
conf->GeoIPFlags2 = NULL;
conf->scanProxyHeaders = 0;
+ conf->use_last_x_forwarded_for_ip = 0;
return (void *)conf;
}
@@ -342,20 +344,29 @@
}
else {
ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r->server, "[mod_geoip]: IPADDR_PTR: %s", ipaddr_ptr);
- /*
- * Check to ensure that the HTTP_CLIENT_IP or
- * X-Forwarded-For header is not a comma separated
- * list of addresses, which would cause mod_geoip to
- * return no country code. If the header is a comma
- * separated list, return the first IP address in the
- * list, which is (hopefully!) the real client IP.
- */
- ipaddr = (char *) calloc(16, sizeof(char));
- strncpy(ipaddr, ipaddr_ptr, 15);
- comma_ptr = strchr(ipaddr, ',');
- if (comma_ptr != 0)
- *comma_ptr = '\0';
- }
+ /*
+ * Check to ensure that the HTTP_CLIENT_IP or
+ * X-Forwarded-For header is not a comma separated
+ * list of addresses, which would cause mod_geoip to
+ * return no country code. If the header is a comma
+ * separated list, return the first IP address in the
+ * list, which is (hopefully!) the real client IP.
+ */
+ ipaddr = (char *) calloc(8*4+7+1, sizeof(char));
+
+ if (cfg->use_last_x_forwarded_for_ip ){
+ comma_ptr = strrchr(ipaddr_ptr, ',');
+ if ( comma_ptr ) {
+ /* skip over whitespace */
+ ipaddr_ptr = comma_ptr + strspn(comma_ptr, ", \t");
+ }
+ }
+
+ strncpy(ipaddr, ipaddr_ptr, 8*4+7);
+ comma_ptr = strchr(ipaddr, ',');
+ if (comma_ptr != 0)
+ *comma_ptr = '\0';
+ }
}
/* this block should be removed! */
@@ -409,6 +420,18 @@
* in case file not
* found */
switch (databaseType) {
+ case GEOIP_NETSPEED_EDITION_REV1:
+ orgorisp = GeoIP_name_by_addr(cfg->gips[i], ipaddr);
+ if (orgorisp != NULL) {
+ if (cfg->GeoIPOutput & GEOIP_NOTES) {
+ apr_table_setn(r->notes, "GEOIP_NETSPEED", orgorisp);
+ }
+ if (cfg->GeoIPOutput & GEOIP_ENV) {
+ apr_table_setn(r->subprocess_env, "GEOIP_NETSPEED", orgorisp);
+ }
+ }
+ break;
+
case GEOIP_NETSPEED_EDITION:
netspeed = GeoIP_id_by_addr(cfg->gips[i], ipaddr);
if (netspeed == GEOIP_UNKNOWN_SPEED) {
@@ -430,6 +453,35 @@
apr_table_setn(r->subprocess_env, "GEOIP_NETSPEED", netspeedstring);
}
break;
+ case GEOIP_COUNTRY_EDITION_V6:
+ /* Get the Country ID */
+ country_id = GeoIP_country_id_by_addr_v6(cfg->gips[i], ipaddr);
+
+ if ( country_id > 0 ) {
+ /* Lookup the Code and the Name with the ID */
+ continent_code = GeoIP_country_continent[country_id];
+ country_code = GeoIP_country_code[country_id];
+ country_name = GeoIP_country_name[country_id];
+
+ if (cfg->numGeoIPFiles == 0) {
+ cfg->numGeoIPFiles = 0;
+ }
+ if (cfg->GeoIPFilenames == 0) {
+ cfg->GeoIPFilenames = 0;
+ }
+ /* Set it for our user */
+ if (cfg->GeoIPOutput & GEOIP_NOTES) {
+ apr_table_setn(r->notes, "GEOIP_CONTINENT_CODE_V6", continent_code);
+ apr_table_setn(r->notes, "GEOIP_COUNTRY_CODE_V6", country_code);
+ apr_table_setn(r->notes, "GEOIP_COUNTRY_NAME_V6", country_name);
+ }
+ if (cfg->GeoIPOutput & GEOIP_ENV) {
+ apr_table_setn(r->subprocess_env, "GEOIP_CONTINENT_CODE_V6", continent_code);
+ apr_table_setn(r->subprocess_env, "GEOIP_COUNTRY_CODE_V6", country_code);
+ apr_table_setn(r->subprocess_env, "GEOIP_COUNTRY_NAME_V6", country_name);
+ }
+ }
+ break;
case GEOIP_COUNTRY_EDITION:
/* Get the Country ID */
country_id = GeoIP_country_id_by_addr(cfg->gips[i], ipaddr);
@@ -491,6 +543,74 @@
GeoIPRegion_delete(giregion);
}
break;
+ case GEOIP_CITY_EDITION_REV0_V6:
+ case GEOIP_CITY_EDITION_REV1_V6:
+ gir = GeoIP_record_by_addr_v6(cfg->gips[i], ipaddr);
+ if (gir != NULL) {
+ if ( gir->country_code != NULL ) {
+ region_name = GeoIP_region_name_by_code(gir->country_code, gir->region);
+ }
+ sprintf(metrocodestr, "%d", gir->dma_code);
+ sprintf(areacodestr, "%d", gir->area_code);
+ if (cfg->GeoIPOutput & GEOIP_NOTES) {
+ apr_table_setn(r->notes, "GEOIP_CONTINENT_CODE_V6", gir->continent_code);
+ apr_table_setn(r->notes, "GEOIP_COUNTRY_CODE_V6", gir->country_code);
+ apr_table_setn(r->notes, "GEOIP_COUNTRY_NAME_V6", gir->country_name);
+ if (gir->region != NULL) {
+ apr_table_set(r->notes, "GEOIP_REGION_V6", gir->region);
+ if ( region_name != NULL ){
+ apr_table_set(r->notes, "GEOIP_REGION_NAME_V6", region_name);
+ }
+ }
+ if (gir->city != NULL) {
+ apr_table_set(r->notes, "GEOIP_CITY_V6", gir->city);
+ }
+ apr_table_setn(r->notes, "GEOIP_DMA_CODE_V6", metrocodestr);
+ apr_table_setn(r->notes, "GEOIP_METRO_CODE_V6", metrocodestr);
+ apr_table_setn(r->notes, "GEOIP_AREA_CODE_V6", areacodestr);
+ }
+ if (cfg->GeoIPOutput & GEOIP_ENV) {
+ apr_table_setn(r->subprocess_env, "GEOIP_CONTINENT_CODE_V6", gir->continent_code);
+ apr_table_setn(r->subprocess_env, "GEOIP_COUNTRY_CODE_V6", gir->country_code);
+ apr_table_setn(r->subprocess_env, "GEOIP_COUNTRY_NAME_V6", gir->country_name);
+ if (gir->region != NULL) {
+ apr_table_set(r->subprocess_env, "GEOIP_REGION_V6", gir->region);
+ if ( region_name != NULL ){
+ apr_table_set(r->subprocess_env, "GEOIP_REGION_NAME_V6", region_name);
+ }
+ }
+ if (gir->city != NULL) {
+ apr_table_set(r->subprocess_env, "GEOIP_CITY_V6", gir->city);
+ }
+ apr_table_setn(r->subprocess_env, "GEOIP_DMA_CODE_V6", metrocodestr);
+ apr_table_setn(r->subprocess_env, "GEOIP_METRO_CODE_V6", metrocodestr);
+ apr_table_setn(r->subprocess_env, "GEOIP_AREA_CODE_V6", areacodestr);
+ }
+ sprintf(latstr, "%f", gir->latitude);
+ sprintf(lonstr, "%f", gir->longitude);
+ if (cfg->GeoIPOutput & GEOIP_NOTES) {
+ apr_table_setn(r->notes, "GEOIP_LATITUDE_V6", latstr);
+ }
+ if (cfg->GeoIPOutput & GEOIP_ENV) {
+ apr_table_setn(r->subprocess_env, "GEOIP_LATITUDE_V6", latstr);
+ }
+ if (cfg->GeoIPOutput & GEOIP_NOTES) {
+ apr_table_setn(r->notes, "GEOIP_LONGITUDE_V6", lonstr);
+ }
+ if (cfg->GeoIPOutput & GEOIP_ENV) {
+ apr_table_setn(r->subprocess_env, "GEOIP_LONGITUDE_V6", lonstr);
+ }
+ if (gir->postal_code != NULL) {
+ if (cfg->GeoIPOutput & GEOIP_NOTES) {
+ apr_table_set(r->notes, "GEOIP_POSTAL_CODE_V6", gir->postal_code);
+ }
+ if (cfg->GeoIPOutput & GEOIP_ENV) {
+ apr_table_set(r->subprocess_env, "GEOIP_POSTAL_CODE_V6", gir->postal_code);
+ }
+ }
+ GeoIPRecord_delete(gir);
+ }
+ break;
case GEOIP_CITY_EDITION_REV0:
case GEOIP_CITY_EDITION_REV1:
gir = GeoIP_record_by_addr(cfg->gips[i], ipaddr);
@@ -498,7 +618,7 @@
if ( gir->country_code != NULL ) {
region_name = GeoIP_region_name_by_code(gir->country_code, gir->region);
}
- sprintf(dmacodestr, "%d", gir->dma_code);
+ sprintf(metrocodestr, "%d", gir->dma_code);
sprintf(areacodestr, "%d", gir->area_code);
if (cfg->GeoIPOutput & GEOIP_NOTES) {
apr_table_setn(r->notes, "GEOIP_CONTINENT_CODE", gir->continent_code);
@@ -513,7 +633,8 @@
if (gir->city != NULL) {
apr_table_set(r->notes, "GEOIP_CITY", gir->city);
}
- apr_table_setn(r->notes, "GEOIP_DMA_CODE", dmacodestr);
+ apr_table_setn(r->notes, "GEOIP_DMA_CODE", metrocodestr);
+ apr_table_setn(r->notes, "GEOIP_METRO_CODE", metrocodestr);
apr_table_setn(r->notes, "GEOIP_AREA_CODE", areacodestr);
}
if (cfg->GeoIPOutput & GEOIP_ENV) {
@@ -529,7 +650,8 @@
if (gir->city != NULL) {
apr_table_set(r->subprocess_env, "GEOIP_CITY", gir->city);
}
- apr_table_setn(r->subprocess_env, "GEOIP_DMA_CODE", dmacodestr);
+ apr_table_setn(r->subprocess_env, "GEOIP_DMA_CODE", metrocodestr);
+ apr_table_setn(r->subprocess_env, "GEOIP_METRO_CODE", metrocodestr);
apr_table_setn(r->subprocess_env, "GEOIP_AREA_CODE", areacodestr);
}
sprintf(latstr, "%f", gir->latitude);
@@ -579,6 +701,17 @@
}
}
break;
+ case GEOIP_DOMAIN_EDITION:
+ orgorisp = GeoIP_name_by_addr(cfg->gips[i], ipaddr);
+ if (orgorisp != NULL) {
+ if (cfg->GeoIPOutput & GEOIP_NOTES) {
+ apr_table_setn(r->notes, "GEOIP_DOMAIN", orgorisp);
+ }
+ if (cfg->GeoIPOutput & GEOIP_ENV) {
+ apr_table_setn(r->subprocess_env, "GEOIP_DOMAIN", orgorisp);
+ }
+ }
+ break;
}
}
@@ -586,6 +719,17 @@
}
+static const char *geoip_use_last_x_forwarded_for_ip(cmd_parms *cmd, void *dummy, int arg)
+{
+ geoip_server_config_rec *conf = (geoip_server_config_rec *)
+ ap_get_module_config(cmd->server->module_config, &geoip_module);
+
+ if (!conf)
+ return "mod_geoip: server structure not allocated";
+
+ conf->use_last_x_forwarded_for_ip = arg;
+ return NULL;
+}
static const char *geoip_scanproxy(cmd_parms *cmd, void *dummy, int arg)
{
geoip_server_config_rec *conf = (geoip_server_config_rec *)
@@ -700,6 +844,7 @@
static const command_rec geoip_cmds[] =
{
AP_INIT_FLAG("GeoIPScanProxyHeaders", geoip_scanproxy, NULL, RSRC_CONF, "Get IP from HTTP_CLIENT IP or X-Forwarded-For"),
+ AP_INIT_FLAG("GeoIPUseLastXForwardedForIP", geoip_use_last_x_forwarded_for_ip, NULL, RSRC_CONF, "For more IP's in X-Forwarded-For, use the last"),
AP_INIT_FLAG("GeoIPEnable", set_geoip_enable, NULL, RSRC_CONF | OR_FILEINFO, "Turn on mod_geoip"),
AP_INIT_FLAG("GeoIPEnableUTF8", set_geoip_enable_utf8, NULL, RSRC_CONF, "Turn on utf8 characters for city names"),
AP_INIT_TAKE12("GeoIPDBFile", set_geoip_filename, NULL, RSRC_CONF, "Path to GeoIP Data File"),
|