diff --git a/.travis.yml b/.travis.yml
index 9311ecb425..37f9af8525 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -54,7 +54,7 @@ before_script:
- sudo apt-get install -y libevent-dev libsystemd-dev
- ( wget https://ftp.pcre.org/pub/pcre/pcre2-10.32.tar.gz
&& tar xzf pcre2-10.32.tar.gz -C src/external )
-- if [[ "${GEOIP}" == "yes" ]]; then ( sudo apt-get install geoip-bin geoip-database libgeoip-dev libgeoip1 ); fi
+- if [[ "${GEOIP}" == "yes" ]]; then ( sudo apt-get install libmaxminddb-dev libmaxminddb0 ); fi
- if [[ "${PRELUDE}" == "yes" ]]; then ( sudo apt-get install libprelude-dev ); fi
- if [[ "${ZEROMQ}" == "yes" ]]; then ( sudo apt-get install libzmq3-dev libtool autoconf libczmq-dev ); fi
- if [[ "${OSSEC_TYPE}" == "winagent" ]]; then ( sudo apt-get install aptitude && sudo aptitude -y install mingw-w64 nsis ); fi
diff --git a/changelog.md b/changelog.md
new file mode 100644
index 0000000000..b7708b40e5
--- /dev/null
+++ b/changelog.md
@@ -0,0 +1,22 @@
+# 3.6.0
+
+## Breaking changes
+
+### empty pcre2 options raise an error
+
+Previously empty `pcre2` options could be used:
+``
+
+This has been changed to raise an error.
+Now there must be a value for these options:
+`.*`
+
+### maxminddb
+
+geoip support has been replaced with [libmaxminddb](https://github.com/maxmind/libmaxminddb)
+The maxminddb development package should be installed to enable geoip support.
+The `geoipdb` configuration option has been re-used for the new database.
+Testing has only been done with the `GeoLite2-Country.mmdb` database, and currently the country
+`iso_code` is the only output.
+
+
diff --git a/src/Makefile b/src/Makefile
index 06a7094ca5..c3b9feb604 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -246,7 +246,8 @@ endif # USE_ZEROMQ
ifneq (,$(filter ${USE_GEOIP},auto yes y Y 1))
DEFINES+=-DLIBGEOIP_ENABLED
- OSSEC_LDFLAGS+=-lGeoIP
+ OSSEC_LDFLAGS+=-lmaxminddb
+ OSSEC_CFLAGS+=-I/usr/include/x86_64-linux-gnu
endif # USE_GEOIP
ifneq (,$(filter ${USE_SQLITE},auto yes y Y 1))
diff --git a/src/analysisd/analysisd.c b/src/analysisd/analysisd.c
index 0a81971de4..588fafc0fd 100644
--- a/src/analysisd/analysisd.c
+++ b/src/analysisd/analysisd.c
@@ -25,7 +25,7 @@
#include "config.h"
#include "rules.h"
#include "stats.h"
-#include "eventinfo.h"
+
#include "accumulator.h"
#include "analysisd.h"
#include "fts.h"
@@ -47,7 +47,7 @@ sqlite3 *conn;
#endif
#ifdef LIBGEOIP_ENABLED
-GeoIP *geoipdb;
+#include
#endif
/** Prototypes **/
@@ -86,6 +86,10 @@ static int hourly_events;
static int hourly_syscheck;
static int hourly_firewall;
+#ifdef LIBGEOIP_ENABLED
+ MMDB_s geoipdb;
+#endif
+
/* Print help statement */
__attribute__((noreturn))
@@ -137,11 +141,6 @@ int main_analysisd(int argc, char **argv)
hourly_syscheck = 0;
hourly_firewall = 0;
-#ifdef LIBGEOIP_ENABLED
- geoipdb = NULL;
-#endif
-
-
while ((c = getopt(argc, argv, "Vtdhfu:g:D:c:")) != -1) {
switch (c) {
case 'V':
@@ -233,14 +232,17 @@ int main_analysisd(int argc, char **argv)
#ifdef LIBGEOIP_ENABLED
- Config.geoip_jsonout = getDefine_Int("analysisd", "geoip_jsonout", 0, 1);
+ Config.geoip_jsonout = getDefine_Int("analysisd", "geoip_jsonout", 0, 1);
/* Opening GeoIP DB */
+
if(Config.geoipdb_file) {
- geoipdb = GeoIP_open(Config.geoipdb_file, GEOIP_INDEX_CACHE);
- if (geoipdb == NULL)
- {
- merror("%s: ERROR: Unable to open GeoIP database from: %s (disabling GeoIP).", ARGV0, Config.geoipdb_file);
+ int status = MMDB_open(Config.geoipdb_file, MMDB_MODE_MMAP, &geoipdb);
+ if (status != MMDB_SUCCESS) {
+ merror("%s: ERROR: Cannot open geoipdb: %s", __local_name, MMDB_strerror(status));
+ if (status == MMDB_IO_ERROR) {
+ merror("%s: ERROR: geoip IO error: %s", __local_name, strerror(errno));
+ }
}
}
#endif
diff --git a/src/analysisd/analysisd.h b/src/analysisd/analysisd.h
index 6586fe4b8b..71acbecd1a 100644
--- a/src/analysisd/analysisd.h
+++ b/src/analysisd/analysisd.h
@@ -33,6 +33,9 @@ extern OSDecoderInfo *NULL_Decoder;
#define OSSEC_SERVER "ossec-server"
#define MAX_DECODER_ORDER_SIZE 20
+#ifdef USE_GEOIP
+int goipdb_success;
+#endif
#endif /* _LOGAUDIT__H */
diff --git a/src/analysisd/config.h b/src/analysisd/config.h
index 976d1942eb..ab52522e2c 100644
--- a/src/analysisd/config.h
+++ b/src/analysisd/config.h
@@ -14,7 +14,7 @@
#include "config/global-config.h"
#ifdef LIBGEOIP_ENABLED
-#include "GeoIP.h"
+#include
#endif
@@ -23,7 +23,7 @@ extern _Config Config; /* Global Config structure */
/*
#ifdef LIBGEOIP_ENABLED
-GeoIP *geoipdb;
+MMDB_s geoipdb;
#endif
*/
diff --git a/src/analysisd/decoders/geoip.c b/src/analysisd/decoders/geoip.c
index 9816b4c81d..f8016a7bc2 100644
--- a/src/analysisd/decoders/geoip.c
+++ b/src/analysisd/decoders/geoip.c
@@ -21,69 +21,77 @@
#include "eventinfo.h"
#include "alerts/alerts.h"
#include "decoder.h"
-#include "GeoIP.h"
-#include "GeoIPCity.h"
+#include
char *GetGeoInfobyIP(char *ip_addr)
{
- GeoIPRecord *geoiprecord;
- char *geodata = NULL;
- char geobuffer[256 +1];
- extern GeoIP *geoipdb;
-
- if(!geoipdb)
- {
- return(NULL);
- }
+ //debug1("%s: DEBUG: Entered GetGeoInfobyIP", __local_name);
+ MMDB_s geoipdb;
if(!ip_addr)
{
+ debug1("%s: DEBUG: (geo) ip_addr is NULL", __local_name);
return(NULL);
}
-
- geoiprecord = GeoIP_record_by_name(geoipdb, (const char *)ip_addr);
- if(geoiprecord == NULL)
- {
+ if(!Config.geoipdb_file) {
+ debug1("%s: DEBUG: (geo) Config.geoipdb_file (geoipdb) is null", __local_name);
return(NULL);
}
-
- if(geoiprecord->country_code == NULL)
- {
- GeoIPRecord_delete(geoiprecord);
+
+ int gai_error, mmdb_error;
+ MMDB_lookup_result_s geo_result = MMDB_lookup_string(&geoipdb, ip_addr, &gai_error, &mmdb_error);
+ if(gai_error != 0) {
+ merror("%s: ERROR: error from (geo) getaddrinfo for %s: %s", __local_name, ip_addr, gai_strerror(gai_error));
return(NULL);
}
- if(strlen(geoiprecord->country_code) < 2)
- {
- GeoIPRecord_delete(geoiprecord);
+ if(mmdb_error != MMDB_SUCCESS) {
+ merror("%s: ERROR: Error from geoip: %s", __local_name, MMDB_strerror(mmdb_error));
return(NULL);
}
-
- if(geoiprecord->region != NULL && geoiprecord->region[0] != '\0')
- {
- const char *regionname = NULL;
- regionname = GeoIP_region_name_by_code(geoiprecord->country_code, geoiprecord->region);
- if(regionname != NULL)
- {
- snprintf(geobuffer, 255, "%s / %s", geoiprecord->country_code, regionname);
- geobuffer[255] = '\0';
- geodata = strdup(geobuffer);
+ MMDB_entry_data_list_s *entry_data_list = NULL;
+
+ if(geo_result.found_entry) {
+ int entry_status = MMDB_get_entry_data_list(&geo_result.entry, &entry_data_list);
+ if(entry_status != MMDB_SUCCESS) {
+ merror("%s: ERROR: Error during geoip lookup: %s", __local_name, MMDB_strerror(entry_status));
+ return(NULL);
}
- else
- {
- geodata = strdup(geoiprecord->country_code);
+
+ if(entry_data_list != NULL) {
+ /* XXX what do? */
+ /* I need country code, region */
+ static char country_code[3];
+ MMDB_entry_data_s entry_data;
+ int cc = MMDB_get_value(&geo_result.entry, &entry_data, "country", "iso_code", NULL);
+ if(cc != MMDB_SUCCESS) {
+ goto cleanup;
+ }
+ if(!entry_data.has_data || entry_data.type != MMDB_DATA_TYPE_UTF8_STRING) {
+ goto cleanup;
+ }
+ snprintf(country_code, 3, "%.2s", entry_data.utf8_string);
+ if(strnlen(country_code, 3) != 2) {
+ debug1("%s: DEBUG: (geo) country_code is wrong?", __local_name);
+ }
+
+ MMDB_free_entry_data_list(entry_data_list);
+ return(country_code);
}
+ } else {
+ debug1("%s: DEBUG: No entry for %s", __local_name, ip_addr);
+ goto cleanup;
}
- else
- {
- geodata = strdup(geoiprecord->country_code);
- }
- GeoIPRecord_delete(geoiprecord);
- return(geodata);
-
+ /* Should not get here */
+ MMDB_free_entry_data_list(entry_data_list);
+ return(NULL);
+
+cleanup:
+ MMDB_free_entry_data_list(entry_data_list);
+ return(NULL);
}
#endif
diff --git a/src/analysisd/decoders/syscheck.c b/src/analysisd/decoders/syscheck.c
index 3a2a62793d..11fb1b0977 100644
--- a/src/analysisd/decoders/syscheck.c
+++ b/src/analysisd/decoders/syscheck.c
@@ -287,7 +287,7 @@ static int DB_Search(const char *f_name, const char *c_sum, Eventinfo *lf)
/* Get name */
saved_name = strchr(sdb.buf, ' ');
if (saved_name == NULL) {
- merror("%s: Invalid integrity message in the database.", ARGV0);
+ merror("%s: Invalid integrity message in the database. (agentid: %d, sdb.buf: %s", ARGV0, agent_id, sdb.buf);
fgetpos(fp, &sdb.init_pos); /* Get next location */
continue;
}
diff --git a/src/analysisd/eventinfo.c b/src/analysisd/eventinfo.c
index 9cc2b62e32..9c0727852f 100644
--- a/src/analysisd/eventinfo.c
+++ b/src/analysisd/eventinfo.c
@@ -574,7 +574,7 @@ void Free_Eventinfo(Eventinfo *lf)
}
if(lf->srcgeoip) {
- free(lf->srcgeoip);
+ //free(lf->srcgeoip);
lf->srcgeoip = NULL;
}
@@ -583,7 +583,7 @@ void Free_Eventinfo(Eventinfo *lf)
}
if(lf->dstgeoip) {
- free(lf->dstgeoip);
+ //free(lf->dstgeoip);
lf->dstgeoip = NULL;
}
diff --git a/src/analysisd/makelists.c b/src/analysisd/makelists.c
index dfbe6a4a31..06c90db709 100644
--- a/src/analysisd/makelists.c
+++ b/src/analysisd/makelists.c
@@ -32,10 +32,6 @@ time_t c_time;
char __shost[512];
OSDecoderInfo *NULL_Decoder;
-#ifdef LIBGEOIP_ENABLED
-GeoIP *geoipdb;
-#endif
-
/* print help statement */
__attribute__((noreturn))
static void help_makelists(void)
diff --git a/src/analysisd/testrule.c b/src/analysisd/testrule.c
index b1aa928f7b..d8cb73dbc8 100644
--- a/src/analysisd/testrule.c
+++ b/src/analysisd/testrule.c
@@ -30,6 +30,9 @@
/** Internal Functions **/
void OS_ReadMSG(char *ut_str);
+#ifdef LIBGEOIP_ENABLED
+ extern MMDB_s geoipdb;
+#endif
/* Analysisd function */
RuleInfo *OS_CheckIfRuleMatch(Eventinfo *lf, RuleNode *curr_node);
@@ -82,11 +85,6 @@ int main(int argc, char **argv)
active_responses = NULL;
memset(prev_month, '\0', 4);
-#ifdef LIBGEOIP_ENABLED
- extern GeoIP *geoipdb;
- geoipdb = NULL;
-#endif
-
while ((c = getopt(argc, argv, "VatvdhU:D:c:q")) != -1) {
switch (c) {
case 'V':
@@ -146,10 +144,12 @@ int main(int argc, char **argv)
/* Opening GeoIP DB */
if(Config.geoipdb_file) {
- geoipdb = GeoIP_open(Config.geoipdb_file, GEOIP_INDEX_CACHE);
- if (geoipdb == NULL)
- {
- merror("%s: Unable to open GeoIP database from: %s (disabling GeoIP).", ARGV0, Config.geoipdb_file);
+ int status = MMDB_open(Config.geoipdb_file, MMDB_MODE_MMAP, &geoipdb);
+ if(status != MMDB_SUCCESS) {
+ merror("%s: ERROR: Cannot open geoipdb: %s", __local_name, MMDB_strerror(status));
+ if(status == MMDB_IO_ERROR) {
+ merror("%s: ERROR: IO error: %s", __local_name, strerror(errno));
+ }
}
}
#endif
diff --git a/src/os_net/os_net.c b/src/os_net/os_net.c
index a420836b5b..2de8490b29 100644
--- a/src/os_net/os_net.c
+++ b/src/os_net/os_net.c
@@ -601,6 +601,7 @@ int OS_SendUnix(int socket, const char *msg, int size)
if (errno == ENOBUFS) {
return (OS_SOCKBUSY);
}
+ debug1("DEBUG: OS_SendUnix errno: %d: %s", errno, strerror(errno));
return (OS_SOCKTERR);
}