Merge remote-tracking branch 'origin/topic/jsiwek/geoip-fixes'

* origin/topic/jsiwek/geoip-fixes:
  Fixes for GeoIP support (addresses #538).
This commit is contained in:
Seth Hall 2011-08-31 10:29:39 -04:00
commit c67c1e8ba6
5 changed files with 99 additions and 43 deletions

View file

@ -16,6 +16,8 @@
# LIBGEOIP_FOUND System has GeoIP libraries and headers # LIBGEOIP_FOUND System has GeoIP libraries and headers
# LibGeoIP_LIBRARY The GeoIP library # LibGeoIP_LIBRARY The GeoIP library
# LibGeoIP_INCLUDE_DIR The location of GeoIP headers # LibGeoIP_INCLUDE_DIR The location of GeoIP headers
# HAVE_GEOIP_COUNTRY_EDITION_V6 Whether the API support IPv6 country edition
# HAVE_GEOIP_CITY_EDITION_REV0_V6 Whether the API supports IPv6 city edition
find_path(LibGeoIP_ROOT_DIR find_path(LibGeoIP_ROOT_DIR
NAMES include/GeoIPCity.h NAMES include/GeoIPCity.h
@ -45,6 +47,20 @@ find_package_handle_standard_args(LibGeoIP DEFAULT_MSG
LibGeoIP_INCLUDE_DIR LibGeoIP_INCLUDE_DIR
) )
if (LIBGEOIP_FOUND)
include(CheckCXXSourceCompiles)
set(CMAKE_REQUIRED_INCLUDES ${LibGeoIP_INCLUDE_DIR})
check_cxx_source_compiles("
#include <GeoIPCity.h>
int main() { GEOIP_COUNTRY_EDITION_V6; return 0; }
" HAVE_GEOIP_COUNTRY_EDITION_V6)
check_cxx_source_compiles("
#include <GeoIPCity.h>
int main() { GEOIP_CITY_EDITION_REV0_V6; return 0; }
" HAVE_GEOIP_CITY_EDITION_REV0_V6)
set(CMAKE_REQUIRED_INCLUDES)
endif ()
mark_as_advanced( mark_as_advanced(
LibGeoIP_ROOT_DIR LibGeoIP_ROOT_DIR
LibGeoIP_LIBRARY LibGeoIP_LIBRARY

View file

@ -114,6 +114,12 @@
/* GeoIP geographic lookup functionality */ /* GeoIP geographic lookup functionality */
#cmakedefine USE_GEOIP #cmakedefine USE_GEOIP
/* Whether the found GeoIP API supports IPv6 Country Edition */
#cmakedefine HAVE_GEOIP_COUNTRY_EDITION_V6
/* Whether the found GeoIP API supports IPv6 City Edition */
#cmakedefine HAVE_GEOIP_CITY_EDITION_REV0_V6
/* Use Google's perftools */ /* Use Google's perftools */
#cmakedefine USE_PERFTOOLS #cmakedefine USE_PERFTOOLS

View file

@ -25,11 +25,13 @@ event log_smtp(rec: Info)
ip = rec$x_originating_ip; ip = rec$x_originating_ip;
loc = lookup_location(ip); loc = lookup_location(ip);
if ( loc$country_code in suspicious_origination_countries || if ( (loc?$country_code &&
loc$country_code in suspicious_origination_countries) ||
ip in suspicious_origination_networks ) ip in suspicious_origination_networks )
{ {
NOTICE([$note=Suspicious_Origination, NOTICE([$note=Suspicious_Origination,
$msg=fmt("An email originated from %s (%s).", loc$country_code, ip), $msg=fmt("An email originated from %s (%s).",
loc?$country_code ? loc$country_code : "", ip),
$id=rec$id]); $id=rec$id]);
} }
} }
@ -38,11 +40,12 @@ event log_smtp(rec: Info)
ip = rec$path[|rec$path|-1]; ip = rec$path[|rec$path|-1];
loc = lookup_location(ip); loc = lookup_location(ip);
if ( loc$country_code in suspicious_origination_countries || if ( (loc?$country_code &&
loc$country_code in suspicious_origination_countries) ||
ip in suspicious_origination_networks ) ip in suspicious_origination_networks )
{ {
NOTICE([$note=Suspicious_Origination, NOTICE([$note=Suspicious_Origination,
$msg=fmt("Based up Received headers, email originated from %s (%s).", loc$country_code, ip), $msg=fmt("Based up Received headers, email originated from %s (%s).", loc?$country_code ? loc$country_code : "", ip),
$id=rec$id]); $id=rec$id]);
} }
} }

View file

@ -33,7 +33,7 @@ event SSH::heuristic_successful_login(c: connection) &priority=5
# Add the location data to the SSH record. # Add the location data to the SSH record.
c$ssh$remote_location = location; c$ssh$remote_location = location;
if ( location$country_code in watched_countries ) if ( location?$country_code && location$country_code in watched_countries )
{ {
NOTICE([$note=Login_From_Watched_Country, NOTICE([$note=Login_From_Watched_Country,
$conn=c, $conn=c,

View file

@ -3019,6 +3019,18 @@ function syslog%(s: string%): any
extern "C" { extern "C" {
#include <GeoIPCity.h> #include <GeoIPCity.h>
} }
static GeoIP* open_geoip_db(GeoIPDBTypes type)
{
GeoIP* geoip = 0;
if ( GeoIP_db_avail(type) )
geoip = GeoIP_open_type(type, GEOIP_MEMORY_CACHE);
if ( ! geoip )
reporter->Warning("Failed to open GeoIP database: %s",
GeoIPDBFileName[type]);
return geoip;
}
#endif #endif
%%} %%}
@ -3031,82 +3043,103 @@ function lookup_location%(a: addr%) : geo_location
static GeoIP* geoip = 0; static GeoIP* geoip = 0;
static GeoIP* geoip_v6 = 0; static GeoIP* geoip_v6 = 0;
static bool geoip_initialized = false; static bool geoip_initialized = false;
static bool have_city_db = false;
static bool have_cityv6_db = false;
GeoIPRecord* gir = 0; GeoIPRecord* gir = 0;
const char* cc = 0;
if ( ! geoip_initialized ) if ( ! geoip_initialized )
{ {
geoip_initialized = true; geoip_initialized = true;
geoip = GeoIP_open_type(GEOIP_CITY_EDITION_REV0,
GEOIP_MEMORY_CACHE); geoip = open_geoip_db(GEOIP_CITY_EDITION_REV0);
if ( ! geoip ) if ( ! geoip )
{ {
builtin_error("can't initialize GeoIP City database.. trying Country version"); geoip = open_geoip_db(GEOIP_COUNTRY_EDITION);
geoip = GeoIP_open_type(GEOIP_COUNTRY_EDITION,
GEOIP_MEMORY_CACHE);
if ( ! geoip ) if ( ! geoip )
builtin_error("can't initialize GeoIP Country database"); builtin_error("Can't initialize GeoIP City/Country database");
else
reporter->Warning("Fell back to GeoIP Country database");
} }
else
have_city_db = true;
#ifdef BROv6 #ifdef BROv6
#ifdef GEOIP_COUNTRY_EDITION_V6 #ifdef HAVE_GEOIP_CITY_EDITION_REV0_V6
geoip_v6 = GeoIP_open_type(GEOIP_COUNTRY_EDITION_V6, geoip_v6 = open_geoip_db(GEOIP_CITY_EDITION_REV0_V6);
GEOIP_MEMORY_CACHE); if ( geoip_v6 ) have_cityv6_db = true;
#endif
#ifdef HAVE_GEOIP_COUNTRY_EDITION_V6
if ( ! geoip_v6 ) if ( ! geoip_v6 )
builtin_error("can't initialize the GeoIPv6 Country database"); geoip_v6 = open_geoip_db(GEOIP_COUNTRY_EDITION_V6);
#endif #endif
if ( ! geoip_v6 )
builtin_error("Can't initialize GeoIPv6 City/Country database");
#endif #endif
} }
#ifdef BROv6 #ifdef BROv6
#ifdef GEOIP_COUNTRY_EDITION_V6 #ifdef HAVE_GEOIP_COUNTRY_EDITION_V6
if ( geoip_v6 && ! is_v4_addr(a) ) if ( geoip_v6 && ! is_v4_addr(a) )
gir = GeoIP_record_by_ipnum_v6(geoip_v6, geoipv6_t(a)); {
geoipv6_t ga;
memcpy(&ga, a, 16);
if ( have_cityv6_db )
gir = GeoIP_record_by_ipnum_v6(geoip_v6, ga);
else
cc = GeoIP_country_code_by_ipnum_v6(geoip_v6, ga);
}
else else
#endif #endif
if ( geoip && is_v4_addr(a) ) if ( geoip && is_v4_addr(a) )
{ {
uint32 addr = to_v4_addr(a); uint32 addr = to_v4_addr(a);
if ( have_city_db )
gir = GeoIP_record_by_ipnum(geoip, ntohl(addr)); gir = GeoIP_record_by_ipnum(geoip, ntohl(addr));
else
cc = GeoIP_country_code_by_ipnum(geoip, ntohl(addr));
} }
#else #else
if ( geoip ) if ( geoip )
{
if ( have_city_db )
gir = GeoIP_record_by_ipnum(geoip, ntohl(a)); gir = GeoIP_record_by_ipnum(geoip, ntohl(a));
else
cc = GeoIP_country_code_by_ipnum(geoip, ntohl(a));
}
#endif #endif
if ( gir ) if ( gir )
{ {
if ( gir->country_code ) if ( gir->country_code )
location->Assign(0, new StringVal(gir->country_code)); location->Assign(0, new StringVal(gir->country_code));
else
location->Assign(0, new StringVal(""));
if ( gir->region ) if ( gir->region )
location->Assign(1, new StringVal(gir->region)); location->Assign(1, new StringVal(gir->region));
else
location->Assign(1, new StringVal(""));
if ( gir->city ) if ( gir->city )
location->Assign(2, new StringVal(gir->city)); location->Assign(2, new StringVal(gir->city));
else
location->Assign(2, new StringVal(""));
if ( gir->latitude ) if ( gir->latitude )
location->Assign(3, new Val(gir->latitude, location->Assign(3, new Val(gir->latitude,
TYPE_DOUBLE)); TYPE_DOUBLE));
else
location->Assign(3, new Val(0.0, TYPE_DOUBLE));
if ( gir->longitude ) if ( gir->longitude )
location->Assign(4, new Val(gir->longitude, location->Assign(4, new Val(gir->longitude,
TYPE_DOUBLE)); TYPE_DOUBLE));
else
location->Assign(4, new Val(0.0, TYPE_DOUBLE));
GeoIPRecord_delete(gir); GeoIPRecord_delete(gir);
return location; return location;
} }
else if (cc)
{
location->Assign(0, new StringVal(cc));
return location;
}
#else #else
static int missing_geoip_reported = 0; static int missing_geoip_reported = 0;
@ -3120,11 +3153,6 @@ function lookup_location%(a: addr%) : geo_location
// We can get here even if we have GeoIP support if we weren't // We can get here even if we have GeoIP support if we weren't
// able to initialize it or it didn't return any information for // able to initialize it or it didn't return any information for
// the address. // the address.
location->Assign(0, new StringVal(""));
location->Assign(1, new StringVal(""));
location->Assign(2, new StringVal(""));
location->Assign(3, new Val(0.0, TYPE_DOUBLE));
location->Assign(4, new Val(0.0, TYPE_DOUBLE));
return location; return location;
%} %}
@ -3139,10 +3167,9 @@ function lookup_asn%(a: addr%) : count
if ( ! geoip_asn_initialized ) if ( ! geoip_asn_initialized )
{ {
geoip_asn_initialized = true; geoip_asn_initialized = true;
geoip_asn = GeoIP_open_type(GEOIP_ASNUM_EDITION, geoip_asn = open_geoip_db(GEOIP_ASNUM_EDITION);
GEOIP_MEMORY_CACHE);
if ( ! geoip_asn ) if ( ! geoip_asn )
builtin_error("can't initialize GeoIP ASNUM database"); builtin_error("Can't initialize GeoIP ASNUM database");
} }
if ( geoip_asn ) if ( geoip_asn )
@ -3150,9 +3177,13 @@ function lookup_asn%(a: addr%) : count
#ifdef BROv6 #ifdef BROv6
// IPv6 support showed up in 1.4.5. // IPv6 support showed up in 1.4.5.
#ifdef GEOIP_COUNTRY_EDITION_V6 #ifdef HAVE_GEOIP_COUNTRY_EDITION_V6
if ( ! is_v4_addr(a) ) if ( ! is_v4_addr(a) )
gir = GeoIP_name_by_ipnum_v6(geoip_asn, geoipv6_t(a)); {
geoipv6_t ga;
memcpy(&ga, a, 16);
gir = GeoIP_name_by_ipnum_v6(geoip_asn, ga);
}
else else
#endif #endif
if ( is_v4_addr(a) ) if ( is_v4_addr(a) )