示例#1
0
static char *
ngx_stream_geoip_org(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_stream_geoip_conf_t  *gcf = conf;

    ngx_str_t  *value;

    if (gcf->org) {
        return "is duplicate";
    }

    value = cf->args->elts;

    gcf->org = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE);

    if (gcf->org == NULL) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "GeoIP_open(\"%V\") failed", &value[1]);

        return NGX_CONF_ERROR;
    }

    if (cf->args->nelts == 3) {
        if (ngx_strcmp(value[2].data, "utf8") == 0) {
            GeoIP_set_charset(gcf->org, GEOIP_CHARSET_UTF8);

        } else {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "invalid parameter \"%V\"", &value[2]);
            return NGX_CONF_ERROR;
        }
    }

    switch (gcf->org->databaseType) {

    case GEOIP_ISP_EDITION:
    case GEOIP_ORG_EDITION:
    case GEOIP_DOMAIN_EDITION:
    case GEOIP_ASNUM_EDITION:

        return NGX_CONF_OK;

#if (NGX_HAVE_GEOIP_V6)
    case GEOIP_ISP_EDITION_V6:
    case GEOIP_ORG_EDITION_V6:
    case GEOIP_DOMAIN_EDITION_V6:
    case GEOIP_ASNUM_EDITION_V6:

        gcf->org_v6 = 1;
        return NGX_CONF_OK;
#endif

    default:
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "invalid GeoIP database \"%V\" type:%d",
                           &value[1], gcf->org->databaseType);
        return NGX_CONF_ERROR;
    }
}
示例#2
0
static PyObject * GeoIP_set_charset_Py(PyObject *self, PyObject * args) {
  GeoIP_GeoIPObject* GeoIP = (GeoIP_GeoIPObject*)self;
  int charset;
  if (!PyArg_ParseTuple(args, "i", &charset)) {
    return NULL;
  }
  return Py_BuildValue("i", GeoIP_set_charset(GeoIP->gi, charset));

}
示例#3
0
/* Open the given GeoLocation database and set its charset.
 *
 * On error, it aborts.
 * On success, a new geolocation structure is returned. */
GeoIP *
geoip_open_db (const char *db)
{
  GeoIP *geoip;
  geoip = GeoIP_open (db, GEOIP_MEMORY_CACHE);

  if (geoip == NULL)
    FATAL ("Unable to open GeoIP database: %s\n", db);

  GeoIP_set_charset (geoip, GEOIP_CHARSET_UTF8);
  LOG_DEBUG (("Opened GeoIP City database: %s\n", db));

  return geoip;
}
static char *
ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_http_geoip_conf_t  *gcf = conf;

    ngx_str_t  *value;

    if (gcf->country) {
        return "is duplicate";
    }

    value = cf->args->elts;

    gcf->country = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE);

    if (gcf->country == NULL) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "GeoIP_open(\"%V\") failed", &value[1]);

        return NGX_CONF_ERROR;
    }

    if (cf->args->nelts == 3) {
        if (ngx_strcmp(value[2].data, "utf8") == 0) {
            GeoIP_set_charset (gcf->country, GEOIP_CHARSET_UTF8);

        } else {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "invalid parameter \"%V\"", &value[2]);
            return NGX_CONF_ERROR;
        }
    }

    switch (gcf->country->databaseType) {

    case GEOIP_COUNTRY_EDITION:
    case GEOIP_PROXY_EDITION:
    case GEOIP_NETSPEED_EDITION:

        return NGX_CONF_OK;

    default:
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "invalid GeoIP database \"%V\" type:%d",
                           &value[1], gcf->country->databaseType);
        return NGX_CONF_ERROR;
    }
}
示例#5
0
static PyObject *GeoIP_set_charset_Py(PyObject * self, PyObject * args)
{
    GeoIP_GeoIPObject *GeoIP = (GeoIP_GeoIPObject *)self;
    int charset;
    if (!PyArg_ParseTuple(args, "i", &charset)) {
        return NULL;
    }
#if PY_MAJOR_VERSION >= 3
    if (charset != GEOIP_CHARSET_UTF8) {
        PyErr_SetString(PyExc_ValueError,
                        "Only UTF-8 is supported for Python 3+.");
        return NULL;
    }
#endif
    return Py_BuildValue("i", GeoIP_set_charset(GeoIP->gi, charset));
}
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;
        }
    }
}
/* 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);

}
示例#8
0
vmod_event(VRT_CTX, struct vmod_priv *pp, enum vcl_event_e evt)
{

	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);

	if (pp->priv == NULL) {
		xxxassert(evt == VCL_EVENT_LOAD);

		/* The README says:
		 * If GEOIP_MMAP_CACHE doesn't work on a 64bit machine, try
		 * adding * the flag "MAP_32BIT" to the mmap call. MMAP is not
		 * avail for WIN32.
		 */
		pp->priv = GeoIP_new(GEOIP_MMAP_CACHE);
		AN(pp->priv);
		pp->free = (vmod_priv_free_f *)GeoIP_delete;
		GeoIP_set_charset((GeoIP *)pp->priv, GEOIP_CHARSET_UTF8);
	}

	return (0);
}
示例#9
0
GeoIP* Geolocation::loadGeoDB(char *base_path, const char *db_name) {
  char path[MAX_PATH];
  GeoIP *geo;
  struct stat buf;
  bool found;  
  
  snprintf(path, sizeof(path), "%s/%s", base_path, db_name);
  ntop->fixPath(path);

  found = ((stat(path, &buf) == 0) && (S_ISREG(buf.st_mode))) ? true : false;

  if(!found) return(NULL);

  geo = GeoIP_open(path, GEOIP_CHECK_CACHE);

  if(geo == NULL)
    ntop->getTrace()->traceEvent(TRACE_WARNING, "Unable to read GeoIP database %s", path);
  else
    GeoIP_set_charset(geo, GEOIP_CHARSET_UTF8); /* Avoid UTF-8 issues (hopefully) */

  return(geo);
}
示例#10
0
static int
GeoIP_GeoIP_init(PyObject *self, PyObject *args, PyObject *kwargs)
{
    static char *kwlist[] = { "filename", "flags", NULL };
    GeoIP_GeoIPObject *GeoIP = (GeoIP_GeoIPObject *)self;
    char *filename = NULL;
    int flags;

    /* For consistency with the C API, positional arguments are in the
       order filename, flags; but it is filename that is optional. */
    if (PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist + 1, &flags)) {
        GeoIP->gi = GeoIP_new(flags);
    } else{
        PyErr_Clear();
        if (PyArg_ParseTupleAndKeywords(args, kwargs, "si", kwlist,
                                        &filename, &flags)) {
            GeoIP->gi = GeoIP_open(filename, flags);
        } else{
            return -1;
        }
    }

    if (!GeoIP->gi) {
        /* Failure is probably due to a system-call-level failure. */
        if (!filename) {
            filename = GeoIPDBFileName[GEOIP_COUNTRY_EDITION];
        }
        PyErr_SetFromErrnoWithFilename(GeoIP_GeoIPError, filename);
        return -1;
    }

#if PY_MAJOR_VERSION >= 3
    GeoIP_set_charset(GeoIP->gi, GEOIP_CHARSET_UTF8);
#endif

    return 0;
}
示例#11
0
static int geoip_header_parser(request_rec * r)
{
    char *orgorisp;
    char *ipaddr;
    char *free_me = NULL;
    short int country_id;
    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 = NULL;
    char *comma_ptr;
    cfg = ap_get_module_config(r->server->module_config, &geoip_module);

    if (!cfg)
        return DECLINED;

    if (!cfg->scanProxyHeaders) {
        ipaddr = _get_client_ip(r);
    } 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 = _get_client_ip(r);
        } else {
            /* Found XFF like header */
            ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0,
                         r->server, "[mod_geoip]: IPADDR_PTR: %s", ipaddr_ptr);

            if (cfg->proxyHeaderMode ==
                GEOIP_PROXY_HEADER_MODE_FIRST_NON_PRIVATE_IP) {
                ipaddr = free_me = _get_ip_from_xff(ipaddr_ptr);
                if (!ipaddr)
                    ipaddr = _get_client_ip(r);
            } else {
                ipaddr = free_me = (char *)calloc(8 * 4 + 7 + 1, sizeof(char));
                /* proxyHeaderMode is
                 * GEOIP_PROXY_HEADER_MODE_LAST_IP or GEOIP_PROXY_HEADER_MODE_FIRST_IP
                 */

                /*
                 * 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.
                 */

                if (cfg->proxyHeaderMode == GEOIP_PROXY_HEADER_MODE_LAST_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! */
#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

    set_geoip_output(cfg, r, "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_REV1:
            orgorisp = GeoIP_name_by_addr(cfg->gips[i], ipaddr);
            setn_geoip_output(cfg, r, "GEOIP_NETSPEED", orgorisp);
            break;

        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";
            }
            setn_geoip_output(cfg, r, "GEOIP_NETSPEED", netspeedstring);
            break;
        case GEOIP_COUNTRY_EDITION_V6:
            /* Get the Country ID */
            country_id = GeoIP_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 */
                setn_geoip_output(cfg, r, "GEOIP_CONTINENT_CODE_V6",
                                  continent_code);
                setn_geoip_output(cfg, r, "GEOIP_COUNTRY_CODE_V6",
                                  country_code);
                setn_geoip_output(cfg, r, "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);

            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 */
                setn_geoip_output(cfg, r, "GEOIP_CONTINENT_CODE",
                                  continent_code);
                setn_geoip_output(cfg, r, "GEOIP_COUNTRY_CODE", country_code);
                setn_geoip_output(cfg, r, "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) {
                region_name = NULL;
                if (giregion->country_code[0]) {
                    region_name =
                        GeoIP_region_name_by_code
                        (giregion->country_code, giregion->region);
                    set_geoip_output(cfg, r, "GEOIP_COUNTRY_CODE",
                                      giregion->country_code);
                    country_id = GeoIP_id_by_code(giregion->country_code);
                    setn_geoip_output(cfg, r, "GEOIP_COUNTRY_NAME",
                                      GeoIP_country_name[country_id]);
                    setn_geoip_output(cfg, r, "GEOIP_CONTINENT_CODE",
                                      GeoIP_country_continent[country_id]);
                }
                if (giregion->region[0]) {
                    set_geoip_output(cfg, r, "GEOIP_REGION", giregion->region);
                }
                if (region_name != NULL) {
                    set_geoip_output(cfg, r, "GEOIP_REGION_NAME", region_name);
                }
                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);
                set_geoip_output(cfg, r, "GEOIP_CONTINENT_CODE_V6",
                                  gir->continent_code);
                set_geoip_output(cfg, r, "GEOIP_COUNTRY_CODE_V6",
                                  gir->country_code);
                set_geoip_output(cfg, r, "GEOIP_COUNTRY_NAME_V6",
                                  gir->country_name);
                set_geoip_output(cfg, r, "GEOIP_REGION_V6", gir->region);
                set_geoip_output(cfg, r, "GEOIP_REGION_NAME_V6", region_name);
                set_geoip_output(cfg, r, "GEOIP_CITY_V6", gir->city);
                set_geoip_output(cfg, r, "GEOIP_DMA_CODE_V6", metrocodestr);
                set_geoip_output(cfg, r, "GEOIP_METRO_CODE_V6", metrocodestr);
                set_geoip_output(cfg, r, "GEOIP_AREA_CODE_V6", areacodestr);
                sprintf(latstr, "%f", gir->latitude);
                sprintf(lonstr, "%f", gir->longitude);
                set_geoip_output(cfg, r, "GEOIP_LATITUDE_V6", latstr);
                set_geoip_output(cfg, r, "GEOIP_LONGITUDE_V6", lonstr);

                set_geoip_output(cfg, r, "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);
            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);
                set_geoip_output(cfg, r, "GEOIP_CONTINENT_CODE",
                                  gir->continent_code);
                set_geoip_output(cfg, r, "GEOIP_COUNTRY_CODE",
                                  gir->country_code);
                set_geoip_output(cfg, r, "GEOIP_COUNTRY_NAME",
                                  gir->country_name);
                set_geoip_output(cfg, r, "GEOIP_REGION", gir->region);
                set_geoip_output(cfg, r, "GEOIP_REGION_NAME", region_name);
                set_geoip_output(cfg, r, "GEOIP_CITY", gir->city);
                set_geoip_output(cfg, r, "GEOIP_DMA_CODE", metrocodestr);
                set_geoip_output(cfg, r, "GEOIP_METRO_CODE", metrocodestr);
                set_geoip_output(cfg, r, "GEOIP_AREA_CODE", areacodestr);
                sprintf(latstr, "%f", gir->latitude);
                sprintf(lonstr, "%f", gir->longitude);
                set_geoip_output(cfg, r, "GEOIP_LATITUDE", latstr);
                set_geoip_output(cfg, r, "GEOIP_LONGITUDE", lonstr);
                set_geoip_output(cfg, r, "GEOIP_POSTAL_CODE",
                                  gir->postal_code);
                GeoIPRecord_delete(gir);
            }

            break;
        case GEOIP_ORG_EDITION:
            orgorisp = GeoIP_name_by_addr(cfg->gips[i], ipaddr);
            setn_geoip_output(cfg, r, "GEOIP_ORGANIZATION", orgorisp);
            break;
        case GEOIP_ISP_EDITION:
            orgorisp = GeoIP_name_by_addr(cfg->gips[i], ipaddr);
            setn_geoip_output(cfg, r, "GEOIP_ISP", orgorisp);
            break;
        case GEOIP_DOMAIN_EDITION:
            orgorisp = GeoIP_name_by_addr(cfg->gips[i], ipaddr);
            setn_geoip_output(cfg, r, "GEOIP_DOMAIN", orgorisp);
            break;
        }
    }

    if (free_me)
        free(free_me);
    return OK;
}
示例#12
0
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;
	char           *found_ip;
	apr_sockaddr_t *sa;
	char           *hostname = 0;

	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);

			if (cfg->use_left_public_x_forwarded_for_ip) {
				// find the first public IP address in a potentially comma-separated list,
				// fall back to remote_ip if we can't find one
				ipaddr = first_public_ip_in_list(ipaddr_ptr, r->connection->remote_ip);
			} else {
				// leaving some of the following inconsistent indenting intact for easier diff to original maxmind src

                       /*
                        * 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! */
#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->GeoIPEnableHostnameLookups
			&& apr_sockaddr_info_get(&sa, ipaddr, APR_INET, 0, 0, r->pool) == APR_SUCCESS
			&& apr_getnameinfo(&hostname, sa, 0) == APR_SUCCESS) {
		ap_str_tolower(hostname);
	}

	if (!hostname)
		hostname = ipaddr;

	if (cfg->GeoIPOutput & GEOIP_NOTES) {
		apr_table_setn(r->notes, "GEOIP_ADDR", ipaddr);
		apr_table_setn(r->notes, "GEOIP_HOST", hostname);
	}
	if (cfg->GeoIPOutput & GEOIP_ENV) {
		apr_table_setn(r->subprocess_env, "GEOIP_ADDR", ipaddr);
		apr_table_setn(r->subprocess_env, "GEOIP_HOST", hostname);
	}

	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_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) {
				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_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);

      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 ( giregion->country_code[0] ) {
			    region_name = GeoIP_region_name_by_code(giregion->country_code, giregion->region);
			  }
				if (cfg->GeoIPOutput & GEOIP_NOTES) {
					if ( giregion->country_code[0] ){
						apr_table_set(r->notes, "GEOIP_COUNTRY_CODE", giregion->country_code);
					}
					if (giregion->region[0]) {
						apr_table_set(r->notes, "GEOIP_REGION", giregion->region);
					}
					if ( region_name != NULL ){
					  apr_table_set(r->notes, "GEOIP_REGION_NAME", region_name);
					}
				}
				if (cfg->GeoIPOutput & GEOIP_ENV) {
					if ( giregion->country_code[0] ){
						apr_table_set(r->subprocess_env, "GEOIP_COUNTRY_CODE", giregion->country_code);
					}
					if (giregion->region[0]) {
					      apr_table_set(r->subprocess_env, "GEOIP_REGION", giregion->region);
					}
					if ( region_name != NULL ){
					  apr_table_set(r->subprocess_env, "GEOIP_REGION_NAME", region_name);
					}
				}
				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);
			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", 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);
						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", metrocodestr);
					apr_table_setn(r->notes, "GEOIP_METRO_CODE", metrocodestr);
					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);
						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", 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);
				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;
		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;
		}
	}

	return OK;
}
示例#13
0
char *geo_lookup(GeoIP *gi, char *ipaddr, int bird) {
	/*
	 * Lookup the country_code by ip address, we can
	 * extend this in the future with more granular data
	 * such as region,city or even zipcode.
	 */
	static char area[MAX_BUF_LENGTH];

	// set the charset to UTF8
	GeoIP_set_charset(gi, GEOIP_CHARSET_UTF8);

	switch(bird){
		case COUNTRY: {
			const char *country= GeoIP_country_code_by_addr(gi, ipaddr);
			if (country==NULL){
				strncpy(area, unknown_geography, MAX_BUF_LENGTH);
			} else {
				strncpy(area, country, MAX_BUF_LENGTH);
			}

		}
		break;

		case REGION:{
			GeoIPRegion *gir;
			gir=GeoIP_region_by_addr(gi,ipaddr);
			if(gir == NULL || strlen(gir->region)==0){
				strncpy(area, unknown_geography, MAX_BUF_LENGTH);
			} else {
				strncpy(area, gir->region, MAX_BUF_LENGTH);
			}

			if(gir != NULL) {
				GeoIPRegion_delete(gir);
			}
			break;
		}

		case CITY:{
			GeoIPRecord *grecord;
			char *city;
			int mustFreeCity = 0;
			grecord = GeoIP_record_by_addr(gi, ipaddr);
			if (grecord !=NULL){
				if (grecord->city == NULL){
					strncpy(area, unknown_geography, MAX_BUF_LENGTH);
				} else {
					int len = strlen(grecord->city);
					city = strdup(grecord->city);
					mustFreeCity = 1;
					strncpy(area,city, MAX_BUF_LENGTH);
					replace_space_with_underscore(area, len);
				}
				if (mustFreeCity) {
					free(city);
				}
				GeoIPRecord_delete(grecord);
			} else {
				strncpy(area, unknown_geography, MAX_BUF_LENGTH);
			}
			break;
		}

		case LAT_LON: {
			GeoIPRecord *grecord;
			grecord = GeoIP_record_by_addr(gi, ipaddr);
			if (grecord!=NULL){
				snprintf(area, MAX_BUF_LENGTH, "%f,%f", grecord->latitude, grecord->longitude);
				GeoIPRecord_delete(grecord);
			} else {
				strncpy(area, unknown_geography, MAX_BUF_LENGTH);
			}
			break;
		}

		case EVERYTHING: {
			GeoIPRecord *grecord;
			char *country = unknown_geography, *region = unknown_geography, *city = unknown_geography;
			int mustFreeCity = 0;
			float lat = 0.0, lon = 0.0;
			grecord = GeoIP_record_by_addr(gi, ipaddr);
			if (grecord != NULL) {
				if (grecord->city != NULL) {
					city = strdup(grecord->city);
					mustFreeCity = 1;
				}
				replace_space_with_underscore(city, strlen(city));

				if (grecord->region != NULL) {
					region = grecord->region;
				}
				if (grecord->country_code != NULL) {
					country = grecord->country_code;
				}
				lat = grecord->latitude;
				lon = grecord->longitude;
			}
			snprintf(area, MAX_BUF_LENGTH, "%s|%s|%s|%f,%f", country, region, city, lat, lon);

			if (grecord != NULL) {
				GeoIPRecord_delete(grecord);
			}

			if (mustFreeCity) {
				free(city);
			}
			break;
		}

		default:
			break;
	}
	return area;
}
示例#14
0
static void get_geoip_tables(array_header *geoips, int filter_flags) {
  config_rec *c;

  c = find_config(main_server->conf, CONF_PARAM, "GeoIPTable", FALSE);
  while (c) {
    GeoIP *gi;
    const char *path;
    int flags, use_utf8 = FALSE;

    pr_signals_handle();

    path = c->argv[0];
    flags = *((int *) c->argv[1]);
    use_utf8 = *((int *) c->argv[2]);

    /* Make sure we open tables that are marked with the default
     * GEOIP_STANDARD flag, which has a value of zero.
     */
    if ((flags == GEOIP_STANDARD && filter_flags != GEOIP_STANDARD) || 
        !(flags & filter_flags)) {
      c = find_config_next(c, c->next, CONF_PARAM, "GeoIPTable", FALSE);
      continue;
    } 

    PRIVS_ROOT
    gi = GeoIP_open(path, flags);
    if (gi == NULL &&
        (flags & GEOIP_INDEX_CACHE)) {
      /* Per Bug#3975, a common cause of this error is the fact that some
       * of the Maxmind GeoIP Lite database files simply do not have indexes.
       * So try to open them as standard databases as a fallback.
       */
      pr_log_debug(DEBUG8, MOD_GEOIP_VERSION
        ": unable to open GeoIPTable '%s' using the IndexCache flag "
        "(database lacks index?), retrying without IndexCache flag", path);
      flags &= ~GEOIP_INDEX_CACHE;
      gi = GeoIP_open(path, flags);
    }
    PRIVS_RELINQUISH

    if (gi != NULL) {
      if (use_utf8) {
        GeoIP_set_charset(gi, GEOIP_CHARSET_UTF8); 
      }

      *((GeoIP **) push_array(geoips)) = gi;

      pr_trace_msg(trace_channel, 15, "loaded GeoIP table '%s': %s (type %d)",
        path, GeoIP_database_info(gi), GeoIP_database_edition(gi));

    } else {
      /* XXX Sigh.  Stupid libGeoIP library logs to stdout/stderr, rather
       * than providing a strerror function.  Grr!
       */

      pr_log_pri(PR_LOG_WARNING, MOD_GEOIP_VERSION
        ": warning: unable to open/use GeoIPTable '%s'", path);
    }

    c = find_config_next(c, c->next, CONF_PARAM, "GeoIPTable", FALSE);
  }

  if (geoips->nelts == 0 &&
      static_geoips->nelts == 0 &&
      ((filter_flags == GEOIP_STANDARD) ||
       (filter_flags & GEOIP_CHECK_CACHE))) {
    GeoIP *gi;

    /* Let the library use its own default database file(s), if no others
     * have been configured.
     */

    PRIVS_ROOT
    gi = GeoIP_new(GEOIP_STANDARD);
    PRIVS_RELINQUISH

    if (gi != NULL) {
      *((GeoIP **) push_array(geoips)) = gi;

      pr_trace_msg(trace_channel, 15,
        "loaded default GeoIP table: %s (type %d)",
        GeoIP_database_info(gi), GeoIP_database_edition(gi));

    } else {
      pr_log_pri(PR_LOG_WARNING, MOD_GEOIP_VERSION
        ": warning: unable to open/use default GeoIP library database file(s)");
    }
  }
示例#15
0
/* Error message capture code inspired by code by Wolfgang Oertl. */
int luageoip_common_open_db(
    lua_State * L,
    const luaL_reg * M,
    int default_type,
    int default_flags,
    const char * mt_name,
    unsigned int bad_flags,
    size_t num_allowed_types,
    const int * allowed_types
  )
{
  /* First argument is checked later */
  int flags = luaL_optint(L, 2, default_flags);
  int charset = luaL_optint(L, 2, GEOIP_CHARSET_UTF8);

  GeoIP * pGeoIP = NULL;
  luageoip_DB * pResult = NULL;

  int old_stderr;
  int pipefd[2];
  char buf[256];

  int error_reported = 0;

  if (bad_flags && (flags & bad_flags) == bad_flags)
  {
    /* TODO: Or is it concrete DB file problem? */
    return luaL_error(
        L,
        "%s error: can't open db with these flags",
        mt_name
      );
  }

  /* Errors are printed to stderr, capture them */
  {
    /* TODO: Handle failures */
    int result = pipe(pipefd);
    result = 0 + result; /* While we're not handling failures, shut up compiler */
    fcntl(pipefd[0], F_SETFL, O_NONBLOCK);
    fcntl(pipefd[1], F_SETFL, O_NONBLOCK);
    old_stderr = dup(2);
    dup2(pipefd[1], 2);
  }

  if (lua_isnoneornil(L, 1))
  {
    pGeoIP = GeoIP_open_type(default_type, flags);
  }
  else
  {
    const char * filename = luaL_checkstring(L, 1);
    pGeoIP = GeoIP_open(filename, flags);
  }

  /* Cleanup error handling */
  {
    int n = read(pipefd[0], buf, sizeof(buf));
    if (n >= 0)
    {
      buf[n] = 0;

      if (!pGeoIP) /* ?! What to do otherwise? */
      {
        lua_pushnil(L);
        lua_pushstring(L, buf);
        error_reported = 1;
      }
    }

    close(pipefd[0]);
    close(pipefd[1]);
    dup2(old_stderr, 2);
    close(old_stderr);
  }

  if (pGeoIP)
  {
    int type = GeoIP_database_edition(pGeoIP);
    int found = 0;
    size_t i = 0;

    for (i = 0; i < num_allowed_types; ++i)
    {
      if (type == allowed_types[i])
      {
        found = 1;
        break;
      }
    }

    if (!found)
    {
      lua_pushnil(L);
      lua_pushfstring(
          L,
          "%s error: unexpected db type in that file (%s)",
          mt_name,
          GeoIP_database_info(pGeoIP)
        );
      error_reported = 1;

      GeoIP_delete(pGeoIP);
      pGeoIP = NULL;
    }
  }

  if (pGeoIP == NULL)
  {
    if (!error_reported)
    {
      lua_pushnil(L);
      lua_pushfstring(
          L,
          "%s error: failed to open database file",
          mt_name
        );
      error_reported = 1;
    }

    return 2; /* nil and error message already on stack */
  }

  GeoIP_set_charset(pGeoIP, charset);

  pResult = (luageoip_DB *)lua_newuserdata(L, sizeof(luageoip_DB));
  pResult->pGeoIP = pGeoIP;

  if (luaL_newmetatable(L, mt_name))
  {
    luaL_register(L, NULL, M);
    lua_pushvalue(L, -1);
    lua_setfield(L, -2, "__index");
  }

  lua_setmetatable(L, -2);

  return 1;
}
示例#16
0
PAM_EXTERN int
pam_sm_acct_mgmt(pam_handle_t *pamh,
                 int flags,
                 int argc,
                 const char **argv)
{
    struct options *opts;
    FILE *fh;
    char *username;        /* username requesting access */
    char *rhost;           /* remote host */
    char *srv;             /* PAM service we're running as */
    char buf[LINE_LENGTH];
    int retval, action;
    int is_v6 = 0;
    struct locations *geo;
    unsigned char gi_type;

    GeoIP       *gi   = NULL;
#ifdef HAVE_GEOIP_010408
    GeoIP       *gi6  = NULL;
    int is_city6_db   = 0;
#endif
    GeoIPRecord *rec  = NULL;

    opts = malloc(sizeof(struct options));
    if (opts == NULL) {
        pam_syslog(pamh, LOG_CRIT, "malloc error 'opts': %m");
        return PAM_SERVICE_ERR;
    }
    opts->charset      = GEOIP_CHARSET_UTF8;
    opts->debug        = 0;
    opts->action       = PAM_PERM_DENIED;
    opts->system_file  = NULL;
    opts->service_file = NULL;
    opts->by_service   = 0;
    opts->geoip_db     = NULL;
#ifdef HAVE_GEOIP_010408
    opts->use_v6       = 0;
    opts->v6_first     = 0;
    opts->geoip6_db    = NULL;
#endif
    opts->is_city_db   = 0;

    geo = malloc(sizeof(struct locations));
    if (geo == NULL) {
        pam_syslog(pamh, LOG_CRIT, "malloc error 'geo': %m");
        free_opts(opts);
        return PAM_SERVICE_ERR;
    }
    geo->country = NULL;
    geo->city    = NULL;
    geo->next    = NULL;

    _parse_args(pamh, argc, argv, opts);

    if (opts->system_file == NULL)
        opts->system_file = strdup(SYSTEM_FILE);
    if (opts->system_file == NULL) {
        pam_syslog(pamh, LOG_CRIT, "malloc error 'opts->system_file': %m");
        free_opts(opts);
        return PAM_SERVICE_ERR;
    }

    if (opts->geoip_db == NULL)
        opts->geoip_db = strdup(GEOIPDB_FILE);
    if (opts->geoip_db == NULL) {
        pam_syslog(pamh, LOG_CRIT, "malloc error 'opts->geoip_db': %m");
        free_opts(opts);
        return PAM_SERVICE_ERR;
    }

#ifdef HAVE_GEOIP_010408
    if (opts->geoip6_db == NULL)
        opts->geoip6_db = strdup(GEOIP6DB_FILE);
    if (opts->geoip6_db == NULL) {
        pam_syslog(pamh, LOG_CRIT, "malloc error 'opts->geoip6_db': %m");
        free_opts(opts);
        return PAM_SERVICE_ERR;
    }
#endif

    retval = pam_get_item(pamh, PAM_USER, (void*) &username);
    if (username == NULL || retval != PAM_SUCCESS) {
        pam_syslog(pamh, LOG_CRIT, "error recovering username");
        free_opts(opts);
        free_locations(geo);
        return PAM_SERVICE_ERR;
    }

    retval = pam_get_item(pamh, PAM_RHOST, (void*) &rhost);
    if (retval != PAM_SUCCESS) {
        pam_syslog(pamh, LOG_CRIT, "error fetching rhost");
        free_opts(opts);
        free_locations(geo);
        return PAM_SERVICE_ERR;
    }
    if (rhost == NULL) {
        pam_syslog(pamh, LOG_INFO, "rhost is NULL, allowing");
        free_opts(opts);
        free_locations(geo);
        return PAM_SUCCESS;
    }

    retval = pam_get_item(pamh, PAM_SERVICE, (void*) &srv);
    if (srv == NULL || retval != PAM_SUCCESS ) {
        pam_syslog(pamh, LOG_CRIT, "error requesting service name");
        free_opts(opts);
        free_locations(geo);
        return PAM_SERVICE_ERR;
    }

    opts->service_file = malloc(PATH_MAX);
    if (opts->service_file == NULL) {
        pam_syslog(pamh, LOG_CRIT, "malloc error 'service_file': %m");
        free_opts(opts);
        free_locations(geo);
        return PAM_SERVICE_ERR;
    }
    if (snprintf(opts->service_file, PATH_MAX-1, SERVICE_FILE, srv) < 0) {
        pam_syslog(pamh, LOG_CRIT, "snprintf error 'service_file'");
        free_opts(opts);
        free_locations(geo);
        return PAM_SERVICE_ERR;
    }

    gi = GeoIP_open(opts->geoip_db, GEOIP_INDEX_CACHE);
    if (gi == NULL) {
        pam_syslog(pamh, LOG_CRIT,
                   "failed to open geoip db (%s): %m", opts->geoip_db);
        free_opts(opts);
        free_locations(geo);
        return PAM_SERVICE_ERR;
    }
    gi_type = GeoIP_database_edition(gi);
    if (opts->debug)
        pam_syslog(pamh, LOG_DEBUG, "GeoIP edition: %d", gi_type);
    switch (gi_type) {
    case GEOIP_COUNTRY_EDITION:
        if (opts->debug)
            pam_syslog(pamh, LOG_DEBUG, "GeoIP v4 edition: country");
        opts->is_city_db = 0;
        break;
    case GEOIP_CITY_EDITION_REV0:
        if (opts->debug)
            pam_syslog(pamh, LOG_DEBUG, "GeoIP v4 edition: city rev0");
        opts->is_city_db = 1;
        break;
    case GEOIP_CITY_EDITION_REV1:
        if (opts->debug)
            pam_syslog(pamh, LOG_DEBUG, "GeoIP v4 edition: city rev1");
        opts->is_city_db = 1;
        break;
    default:
        pam_syslog(pamh, LOG_CRIT, "invalid GeoIP DB type `%d' found", gi_type);
        GeoIP_delete(gi);
        free_opts(opts);
        free_locations(geo);
        return PAM_SERVICE_ERR;
    }
    GeoIP_set_charset(gi, opts->charset);
    if (opts->debug)
        pam_syslog(pamh, LOG_DEBUG, "GeoIP DB is City: %s",
                   opts->is_city_db ? "yes" : "no");

#ifdef HAVE_GEOIP_010408
    if (opts->use_v6 != 0) {
        gi6 = GeoIP_open(opts->geoip6_db, GEOIP_INDEX_CACHE);
        if (gi6 == NULL) {
            pam_syslog(pamh, LOG_CRIT,
                       "failed to open geoip6 db (%s): %m", opts->geoip6_db);
            GeoIP_delete(gi);
            free_opts(opts);
            free_locations(geo);
            return PAM_SERVICE_ERR;
        }
        gi_type = GeoIP_database_edition(gi6);

        switch (gi_type) {
        case GEOIP_COUNTRY_EDITION_V6:
            if (opts->debug)
                pam_syslog(pamh, LOG_DEBUG, "GeoIP v6 edition: country");
            is_city6_db = 0;
            break;
        case GEOIP_CITY_EDITION_REV0_V6:
            if (opts->debug)
                pam_syslog(pamh, LOG_DEBUG, "GeoIP v6 edition: city rev0");
            is_city6_db = 1;
            break;
        case GEOIP_CITY_EDITION_REV1_V6:
            if (opts->debug)
                pam_syslog(pamh, LOG_DEBUG, "GeoIP v6 edition: city rev1");
            is_city6_db = 1;
            break;
        default:
            pam_syslog(pamh, LOG_CRIT, "invalid GeoIP DB type `%d' found", gi_type);
            GeoIP_delete(gi);
            GeoIP_delete(gi6);
            free_opts(opts);
            free_locations(geo);
            return PAM_SERVICE_ERR;
        }
        if (opts->debug)
            pam_syslog(pamh, LOG_DEBUG, "GeoIP DB is City v6: %s",
                       is_city6_db ? "yes" : "no");
        GeoIP_set_charset(gi6, opts->charset);

        if (opts->is_city_db != is_city6_db) {
            pam_syslog(pamh, LOG_CRIT, "IPv4 DB type is not the same as IPv6 (not both Country edition or both City edition)");
            GeoIP_delete(gi);
            GeoIP_delete(gi6);
            free_opts(opts);
            free_locations(geo);
            return PAM_SERVICE_ERR;
        }

        if (opts->v6_first != 0) {
            rec = GeoIP_record_by_name_v6(gi6, rhost);
            if (rec == NULL) {
                if (opts->debug)
                    pam_syslog(pamh, LOG_DEBUG, "no IPv6 record for %s, trying IPv4", rhost);
                rec = GeoIP_record_by_name(gi, rhost);
            }
            else
                is_v6 = 1;
        }
        else {
            rec = GeoIP_record_by_name(gi, rhost);
            if (rec == NULL) {
                if (opts->debug)
                    pam_syslog(pamh, LOG_DEBUG, "no IPv4 record for %s, trying IPv6", rhost);
                rec = GeoIP_record_by_name_v6(gi6, rhost);
                if (rec != NULL)
                    is_v6 = 1;
            }
        }
    }
    else
#endif /* HAVE_GEOIP_010408 */
        rec = GeoIP_record_by_name(gi, rhost);

    if (rec == NULL) {
        pam_syslog(pamh, LOG_INFO, "no record for %s, setting GeoIP to 'UNKNOWN,*'", rhost);

        geo->city    = strdup("*");
        geo->country = strdup("UNKNOWN");

        if (geo->city == NULL || geo->country == NULL) {
            pam_syslog(pamh, LOG_CRIT, "malloc error 'geo->{city,country}': %m");
            GeoIP_delete(gi);
#ifdef HAVE_GEOIP_010408
            GeoIP_delete(gi6);
#endif
            free_opts(opts);
            free_locations(geo);
            return PAM_SERVICE_ERR;
        }
    }
    else {
        if (rec->city == NULL || opts->is_city_db == 0)
            geo->city = strdup("*");
        else
            geo->city = strdup(rec->city);

        if (rec->country_code == NULL)
            geo->country = strdup("UNKNOWN");
        else
            geo->country = strdup(rec->country_code);

        if (geo->city == NULL || geo->country == NULL) {
            pam_syslog(pamh, LOG_CRIT, "malloc error 'geo->{city,country}': %m");
            GeoIP_delete(gi);
#ifdef HAVE_GEOIP_010408
            GeoIP_delete(gi6);
#endif
            free_opts(opts);
            free_locations(geo);
            return PAM_SERVICE_ERR;
        }

        if (opts->is_city_db) {
            geo->latitude  = rec->latitude;
            geo->longitude = rec->longitude;
        }
    }

    if (opts->debug)
        pam_syslog(pamh, LOG_DEBUG, "GeoIP record for %s: %s,%s",
                   rhost, geo->country, geo->city);

    if (opts->debug && strcmp(geo->country, "UNKNOWN") != 0 && opts->is_city_db)
        pam_syslog(pamh, LOG_DEBUG, "GeoIP coordinates for %s: %f,%f",
                   rhost, geo->latitude, geo->longitude);

    if ((fh = fopen(opts->service_file, "r")) != NULL) {
        opts->by_service = 1;
        if (opts->debug)
            pam_syslog(pamh, LOG_DEBUG, "using services file %s",
                       opts->service_file);
    }
    else {
        if ((fh = fopen(opts->system_file, "r")) == NULL) {
            pam_syslog(pamh, LOG_CRIT, "error opening %s: %m", opts->system_file);

#ifdef HAVE_GEOIP_010408
            if (gi6) GeoIP_delete(gi6);
#endif
            if (gi) GeoIP_delete(gi);
            if (rec) GeoIPRecord_delete(rec);
            free_opts(opts);
            return PAM_SERVICE_ERR;
        }
    }

    action = opts->action;
    char location[LINE_LENGTH];
    while (fgets(buf, LINE_LENGTH, fh) != NULL) {
        char *line, *ptr;
        char domain[LINE_LENGTH],
             service[LINE_LENGTH];

        action = opts->action;
        line   = buf;
        /* skip the leading white space */
        while (*line && isspace(*line))
            line++;

        /* Rip off the comments */
        ptr = strchr(line,'#');
        if (ptr)
            *ptr = '\0';
        /* Rip off the newline char */
        ptr = strchr(line,'\n');
        if (ptr)
            *ptr = '\0';
        /* Anything left ? */
        if (!strlen(line))
            continue;

        if (opts->by_service)
            action = parse_line_srv(pamh, line, domain, location);
        else
            action = parse_line_sys(pamh, line, domain, service, location);
        if (action < 0) { /* parsing failed */
            action = opts->action;
            continue;
        }

        if (!opts->by_service) {
            if (!check_service(pamh, service, srv))
                continue;
        }

        if ((strcmp(domain, "*") == 0) || (strcmp(username, domain) == 0)) {
            if (check_location(pamh, opts, location, geo))
                break;
        }
        else if (domain[0] == '@') {
            if (pam_modutil_user_in_group_nam_nam(pamh, username, domain+1)) {
                if (check_location(pamh, opts, location, geo))
                    break;
            }
        }
    }

    fclose(fh);
    if (gi) GeoIP_delete(gi);
#ifdef HAVE_GEOIP_010408
    if (gi6) GeoIP_delete(gi6);
#endif
    if (rec) GeoIPRecord_delete(rec);
    free_locations(geo);

    switch (action) {
    case PAM_SUCCESS:
        pam_syslog(pamh, LOG_DEBUG, "location %s allowed for user %s from %s (IPv%d)", location, username, rhost, is_v6 ? 6 : 4);
        break;
    case PAM_PERM_DENIED:
        pam_syslog(pamh, LOG_DEBUG, "location %s denied for user %s from %s (IPv%d)", location, username, rhost, is_v6 ? 6 : 4);
        break;
    case PAM_IGNORE:
        pam_syslog(pamh, LOG_DEBUG, "location %s ignored for user %s from %s (IPv%d)", location, username, rhost, is_v6 ? 6 : 4);
        break;
    default: /* should not happen */
        pam_syslog(pamh, LOG_DEBUG, "location status: %d, IPv%d", action, is_v6 ? 6 : 4);
        break;
    };
    free_opts(opts);
    return action;
}