Variant f_geoip_database_info(int64 database /* = k_GEOIP_COUNTRY_EDITION */) { if (!is_db_avail(database)) return null_variant; const char *db_info = GeoIP_database_info(s_geoip->gi[database]); return String(db_info, AttachString); }
static PyObject *GeoIP_get_database_info(PyObject *self, void *UNUSED(closure)) { GeoIP_GeoIPObject *GeoIP = (GeoIP_GeoIPObject *)self; char *database_info = GeoIP_database_info(GeoIP->gi); PyObject *ret = Py_BuildValue("z", database_info); free(database_info); return ret; }
static void init_geoip_db(GeoIP **dbp, GeoIPDBTypes edition, GeoIPDBTypes fallback, GeoIPOptions method, const char *name) { char *info; GeoIP *db; REQUIRE(dbp != NULL); db = *dbp; if (db != NULL) { GeoIP_delete(db); db = *dbp = NULL; } if (! GeoIP_db_avail(edition)) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_INFO, "GeoIP %s (type %d) DB not available", name, edition); goto fail; } isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_INFO, "initializing GeoIP %s (type %d) DB", name, edition); db = GeoIP_open_type(edition, method); if (db == NULL) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, "failed to initialize GeoIP %s (type %d) DB%s", name, edition, fallback == 0 ? "geoip matches using this database will fail" : ""); goto fail; } info = GeoIP_database_info(db); if (info != NULL) isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_INFO, "%s", info); *dbp = db; return; fail: if (fallback != 0) init_geoip_db(dbp, fallback, 0, method, name); }
static PyObject * GeoIP_GetAttr(PyObject *self, char *attrname) { PyObject * ret; char * database_info; GeoIP_GeoIPObject* GeoIP = (GeoIP_GeoIPObject*)self; if (strcmp(attrname, "GEOIP_STANDARD") == 0) { return Py_BuildValue("i", 0); } else if (strcmp(attrname, "database_info") == 0) { database_info = GeoIP_database_info(GeoIP->gi); ret = Py_BuildValue("z", database_info); free(database_info); return ret; } else if (strcmp(attrname, "database_edition") == 0) { return Py_BuildValue("z", GeoIPDBDescription[GeoIP_database_edition(GeoIP->gi)]); } return Py_FindMethod(GeoIP_Object_methods, self, attrname); }
bool GeoIP_Extension::SDK_OnLoad(char *error, size_t maxlength, bool late) { char path[PLATFORM_MAX_PATH]; g_pSM->BuildPath(Path_SM, path, sizeof(path), "configs/geoip/GeoIP.dat"); gi = GeoIP_open(path, GEOIP_MEMORY_CACHE); if (!gi) { snprintf(error, maxlength, "Could not load configs/geoip/GeoIP.dat"); return false; } g_pShareSys->AddNatives(myself, geoip_natives); g_pShareSys->RegisterLibrary(myself, "GeoIP"); g_pSM->LogMessage(myself, "GeoIP database info: %s", GeoIP_database_info(gi)); return true; }
int main(int argc, char *argv[]) { char * filename = NULL; char * db_info; GeoIP * gi; int i; char *custom_directory = NULL; char *custom_file = NULL; int version_flag = 0; int charset = GEOIP_CHARSET_UTF8; if (argc < 2) { usage(); exit(1); } i = 1; while (i < argc) { if (strcmp(argv[i], "-v") == 0) { version_flag = 1; } else if (strcmp(argv[i], "-l") == 0) { charset = GEOIP_CHARSET_ISO_8859_1; } else if (strcmp(argv[i], "-i") == 0) { info_flag = 1; } else if (( strcmp(argv[i], "-?" ) == 0 ) || ( strcmp(argv[i], "-h" ) == 0 )) { usage(); exit(0); } else if (strcmp(argv[i], "-f") == 0) { if ((i + 1) < argc) { i++; custom_file = argv[i]; } } else if (strcmp(argv[i], "-d") == 0) { if ((i + 1) < argc) { i++; custom_directory = argv[i]; } } else { filename = argv[i]; } i++; } if (filename == NULL) { usage(); exit(1); } FILE *hostname_file = fopen(filename, "r"); if (hostname_file == NULL) { usage(); exit(1); } if (custom_directory != NULL) { GeoIP_setup_custom_directory(custom_directory); } _GeoIP_setup_dbfilename(); if (custom_file != NULL) { gi = GeoIP_open(custom_file, GEOIP_STANDARD | GEOIP_SILENCE); if (NULL == gi) { printf("%s not available, skipping...\n", custom_file); } else { gi->charset = charset; i = GeoIP_database_edition(gi); if (version_flag == 1) { db_info = GeoIP_database_info(gi); printf("%s: %s\n", GeoIPDBDescription[i], db_info == NULL ? "" : db_info ); free(db_info); } else { char *hostname = NULL; ssize_t read; size_t len = 0; while ((read = getline(&hostname, &len, hostname_file)) != -1) { if (hostname[read - 1] == '\n') { hostname[read - 1] = '\0'; --read; } geoiplookup(gi, hostname, i); } } } GeoIP_delete(gi); } else { /* iterate through different database types */ for (i = 0; i < NUM_DB_TYPES; ++i) { if (GeoIP_db_avail(i)) { gi = GeoIP_open_type(i, GEOIP_STANDARD | GEOIP_SILENCE); if (NULL == gi) { /* Ignore these errors. It's possible * to use the same database name for * different databases. */ ; } else { gi->charset = charset; if (version_flag == 1) { db_info = GeoIP_database_info(gi); printf("%s: %s\n", GeoIPDBDescription[i], db_info == NULL ? "" : db_info ); free(db_info); } else { char *hostname = NULL; ssize_t read; size_t len = 0; while ((read = getline(&hostname, &len, hostname_file)) != -1) { if (hostname[read -1] == '\n') { hostname[read - 1] = '\0'; --read; } geoiplookup(gi, hostname, i); } } } GeoIP_delete(gi); } } } return 0; }
int main(int argc, char *argv[]) { char * hostname = NULL; char * db_info; GeoIP * gi; int i; char *custom_directory = NULL; char *custom_file = NULL; int version_flag = 0; if (argc < 2) { usage(); exit(1); } i = 1; while (i < argc) { if (strcmp(argv[i], "-v") == 0) { version_flag = 1; } else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-?") == 0) { usage(); exit(0); } else if (strcmp(argv[i], "-f") == 0) { if ((i + 1) < argc) { i++; custom_file = argv[i]; } } else if (strcmp(argv[i], "-d") == 0) { if ((i + 1) < argc) { i++; custom_directory = argv[i]; } } else { hostname = argv[i]; } i++; } if (hostname == NULL) { usage(); exit(1); } if (custom_directory != NULL) { GeoIP_setup_custom_directory(custom_directory); } _GeoIP_setup_dbfilename(); if (custom_file != NULL) { gi = GeoIP_open(custom_file, GEOIP_STANDARD); if (NULL == gi) { printf("%s not available, skipping...\n", custom_file); } else { i = GeoIP_database_edition(gi); if (version_flag == 1) { db_info = GeoIP_database_info(gi); printf("%s: %s\n", GeoIPDBDescription[i], db_info == NULL ? "" : db_info ); free(db_info); } else { geoiplookup(gi, hostname, i); } } GeoIP_delete(gi); } else { /* iterate through different database types */ for (i = 0; i < NUM_DB_TYPES; ++i) { if (GeoIP_db_avail(i)) { gi = GeoIP_open_type(i, GEOIP_STANDARD); if (NULL == gi) { /* Ignore these errors. It's possible * to use the same database name for * different databases. */ ; } else { if (version_flag == 1) { db_info = GeoIP_database_info(gi); printf("%s: %s\n", GeoIPDBDescription[i], db_info); free(db_info); } else { geoiplookup(gi, hostname, i); } } GeoIP_delete(gi); } } } return 0; }
short int GeoIP_update_database_general (char * user_id,char * license_key,char *data_base_type, int verbose,char ** client_ipaddr, void (*f)( char *)) { struct hostent *hostlist; int sock; char * buf; struct sockaddr_in sa; int offset = 0, err; char * request_uri; char * compr; unsigned long comprLen; FILE *comp_fh, *cur_db_fh, *gi_fh; gzFile gz_fh; char * file_path_gz, * file_path_test; MD5_CONTEXT context; MD5_CONTEXT context2; unsigned char buffer[1024], digest[16] ,digest2[16]; char hex_digest[33] = "0000000000000000000000000000000\0"; char hex_digest2[33] = "0000000000000000000000000000000\0"; unsigned int i; char *f_str; GeoIP * gi; char * db_info; char *ipaddress; char *geoipfilename; char *tmpstr; int dbtype; int lookupresult = 1; char block[BLOCK_SIZE]; int block_size = BLOCK_SIZE; size_t len; size_t request_uri_len; size_t size; hostlist = GeoIP_get_host_or_proxy(); if (hostlist == NULL) return GEOIP_DNS_ERR; if (hostlist->h_addrtype != AF_INET) return GEOIP_NON_IPV4_ERR; if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { return GEOIP_SOCKET_OPEN_ERR; } memset(&sa, 0, sizeof(struct sockaddr_in)); sa.sin_port = htons(GeoIPHTTPPort); memcpy(&sa.sin_addr, hostlist->h_addr_list[0], hostlist->h_length); sa.sin_family = AF_INET; if (verbose == 1) { GeoIP_printf(f,"Connecting to MaxMind GeoIP server\n"); GeoIP_printf(f, "via Host or Proxy Server: %s:%d\n", hostlist->h_name, GeoIPHTTPPort); } if (connect(sock, (struct sockaddr *)&sa, sizeof(struct sockaddr))< 0) return GEOIP_CONNECTION_ERR; request_uri = malloc(sizeof(char) * (strlen(license_key) + strlen(GeoIPHTTPRequestMD5)+1036)); if (request_uri == NULL) return GEOIP_OUT_OF_MEMORY_ERR; /* get the file name from a web page using the product id */ sprintf(request_uri,GeoIPHTTPRequestFilename,GeoIPProxyHTTP,GeoIPProxiedHost,data_base_type,GeoIPUpdateHost); if (verbose == 1) { GeoIP_printf(f, "sending request %s \n",request_uri); } send(sock, request_uri, strlen(request_uri),0); /* send the request */ free(request_uri); buf = malloc(sizeof(char) * (block_size+4)); if (buf == NULL) return GEOIP_OUT_OF_MEMORY_ERR; offset = 0; for (;;){ int amt; amt = recv(sock, &buf[offset], block_size,0); if (amt == 0){ break; } else if (amt == -1) { free(buf); return GEOIP_SOCKET_READ_ERR; } offset += amt; buf = realloc(buf, offset + block_size + 4); } buf[offset] = 0; offset = 0; tmpstr = strstr(buf, "\r\n\r\n") + 4; if (tmpstr[0] == '.' || strchr(tmpstr, '/') != NULL) { free(buf); return GEOIP_INVALID_SERVER_RESPONSE; } geoipfilename = _GeoIP_full_path_to(tmpstr); free(buf); /* print the database product id and the database filename */ if (verbose == 1){ GeoIP_printf(f, "database product id %s database file name %s \n",data_base_type,geoipfilename); } _GeoIP_setup_dbfilename(); /* get MD5 of current GeoIP database file */ if ((cur_db_fh = fopen (geoipfilename, "rb")) == NULL) { GeoIP_printf(f, NoCurrentDB, geoipfilename); } else { md5_init(&context); while ((len = fread (buffer, 1, 1024, cur_db_fh)) > 0) md5_write (&context, buffer, len); md5_final (&context); memcpy(digest,context.buf,16); fclose (cur_db_fh); for (i = 0; i < 16; i++) sprintf (&hex_digest[2*i], "%02x", digest[i]); GeoIP_printf(f, MD5Info, hex_digest ); } if (verbose == 1) { GeoIP_printf(f,"MD5 sum of database %s is %s \n",geoipfilename,hex_digest); } if (client_ipaddr[0] == NULL) { /* We haven't gotten our IP address yet, so let's request it */ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { free(geoipfilename); return GEOIP_SOCKET_OPEN_ERR; } memset(&sa, 0, sizeof(struct sockaddr_in)); sa.sin_port = htons(GeoIPHTTPPort); memcpy(&sa.sin_addr, hostlist->h_addr_list[0], hostlist->h_length); sa.sin_family = AF_INET; if (verbose == 1) GeoIP_printf(f,"Connecting to MaxMind GeoIP Update server\n"); /* Download gzip file */ if (connect(sock, (struct sockaddr *)&sa, sizeof(struct sockaddr))< 0) { free(geoipfilename); return GEOIP_CONNECTION_ERR; } request_uri = malloc(sizeof(char) * (strlen(license_key) + strlen(GeoIPHTTPRequestMD5)+1036)); if (request_uri == NULL) { free(geoipfilename); return GEOIP_OUT_OF_MEMORY_ERR; } /* get client ip address from MaxMind web page */ sprintf(request_uri,GeoIPHTTPRequestClientIP,GeoIPProxyHTTP,GeoIPProxiedHost,GeoIPUpdateHost); send(sock, request_uri, strlen(request_uri),0); /* send the request */ if (verbose == 1) { GeoIP_printf(f, "sending request %s", request_uri); } free(request_uri); buf = malloc(sizeof(char) * (block_size+1)); if (buf == NULL) { free(geoipfilename); return GEOIP_OUT_OF_MEMORY_ERR; } offset = 0; for (;;){ int amt; amt = recv(sock, &buf[offset], block_size,0); if (amt == 0) { break; } else if (amt == -1) { free(buf); return GEOIP_SOCKET_READ_ERR; } offset += amt; buf = realloc(buf, offset+block_size+1); } buf[offset] = 0; offset = 0; ipaddress = strstr(buf, "\r\n\r\n") + 4; /* get the ip address */ ipaddress = malloc(strlen(strstr(buf, "\r\n\r\n") + 4)+5); strcpy(ipaddress,strstr(buf, "\r\n\r\n") + 4); client_ipaddr[0] = ipaddress; if (verbose == 1) { GeoIP_printf(f, "client ip address: %s\n",ipaddress); } free(buf); close(sock); } ipaddress = client_ipaddr[0]; /* make a md5 sum of ip address and license_key and store it in hex_digest2 */ request_uri_len = sizeof(char) * 2036; request_uri = malloc(request_uri_len); md5_init(&context2); md5_write (&context2, (byte *)license_key, 12);//add license key to the md5 sum md5_write (&context2, (byte *)ipaddress, strlen(ipaddress));//add ip address to the md5 sum md5_final (&context2); memcpy(digest2,context2.buf,16); for (i = 0; i < 16; i++) snprintf (&hex_digest2[2*i], 3, "%02x", digest2[i]);// change the digest to a hex digest if (verbose == 1) { GeoIP_printf(f, "md5sum of ip address and license key is %s \n",hex_digest2); } /* send the request using the user id,product id, * md5 sum of the prev database and * the md5 sum of the license_key and ip address */ if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { return GEOIP_SOCKET_OPEN_ERR; } memset(&sa, 0, sizeof(struct sockaddr_in)); sa.sin_port = htons(GeoIPHTTPPort); memcpy(&sa.sin_addr, hostlist->h_addr_list[0], hostlist->h_length); sa.sin_family = AF_INET; if (connect(sock, (struct sockaddr *)&sa, sizeof(struct sockaddr))< 0) return GEOIP_CONNECTION_ERR; snprintf(request_uri, request_uri_len, GeoIPHTTPRequestMD5,GeoIPProxyHTTP,GeoIPProxiedHost,hex_digest,hex_digest2,user_id,data_base_type); send(sock, request_uri, strlen(request_uri),0); if (verbose == 1) { GeoIP_printf(f, "sending request %s\n",request_uri); } free(request_uri); offset = 0; buf = malloc(sizeof(char) * block_size); if (buf == NULL) return GEOIP_OUT_OF_MEMORY_ERR; if (verbose == 1) GeoIP_printf(f,"Downloading gzipped GeoIP Database...\n"); for (;;) { int amt; amt = recv(sock, &buf[offset], block_size,0); if (amt == 0) { break; } else if (amt == -1) { free(buf); return GEOIP_SOCKET_READ_ERR; } offset += amt; buf = realloc(buf, offset+block_size); if (buf == NULL) return GEOIP_OUT_OF_MEMORY_ERR; } compr = strstr(buf, "\r\n\r\n") + 4; comprLen = offset + buf - compr; if (strstr(compr, "License Key Invalid") != NULL) { if (verbose == 1) GeoIP_printf(f,"Failed\n"); free(buf); return GEOIP_LICENSE_KEY_INVALID_ERR; } else if (strstr(compr, "No new updates available") != NULL) { free(buf); GeoIP_printf(f, "%s is up to date, no updates required\n", geoipfilename); return GEOIP_NO_NEW_UPDATES; } else if (strstr(compr, "Invalid UserId") != NULL){ free(buf); return GEOIP_USER_ID_INVALID_ERR; } else if (strstr(compr, "Invalid product ID or subscription expired") != NULL){ free(buf); return GEOIP_PRODUCT_ID_INVALID_ERR; } if (verbose == 1) GeoIP_printf(f,"Done\n"); GeoIP_printf(f, "Updating %s\n", geoipfilename); /* save gzip file */ file_path_gz = malloc(sizeof(char) * (strlen(geoipfilename) + 4)); if (file_path_gz == NULL) return GEOIP_OUT_OF_MEMORY_ERR; strcpy(file_path_gz,geoipfilename); strcat(file_path_gz,".gz"); if (verbose == 1) { GeoIP_printf(f, "%s%s", SavingGzip, file_path_gz ); } comp_fh = fopen(file_path_gz, "wb"); if(comp_fh == NULL) { free(file_path_gz); free(buf); return GEOIP_GZIP_IO_ERR; } size = fwrite(compr, 1, comprLen, comp_fh); fclose(comp_fh); free(buf); if ( size != comprLen ) { return GEOIP_GZIP_IO_ERR; } if (verbose == 1) { GeoIP_printf(f, "download data to a gz file named %s \n",file_path_gz); GeoIP_printf(f,"Done\n"); GeoIP_printf(f,"Uncompressing gzip file ... "); } file_path_test = malloc(sizeof(char) * (strlen(GeoIPDBFileName[GEOIP_COUNTRY_EDITION]) + 6)); if (file_path_test == NULL) { free(file_path_gz); return GEOIP_OUT_OF_MEMORY_ERR; } strcpy(file_path_test,GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); strcat(file_path_test,".test"); gi_fh = fopen(file_path_test, "wb"); if(gi_fh == NULL) { free(file_path_test); free(file_path_gz); return GEOIP_TEST_IO_ERR; } /* uncompress gzip file */ offset = 0; gz_fh = gzopen(file_path_gz, "rb"); for (;;) { int amt; amt = gzread(gz_fh, block, block_size); if (amt == -1) { free(file_path_gz); free(file_path_test); gzclose(gz_fh); fclose(gi_fh); return GEOIP_GZIP_READ_ERR; } if (amt == 0) { break; } if ( amt != fwrite(block,1,amt,gi_fh) ){ return GEOIP_GZIP_IO_ERR; } } gzclose(gz_fh); unlink(file_path_gz); free(file_path_gz); fclose(gi_fh); if (verbose == 1) GeoIP_printf(f,"Done\n"); if (verbose == 1) { len = strlen(WritingFile) + strlen(geoipfilename) - 1; f_str = malloc(len); snprintf(f_str,len,WritingFile,geoipfilename); free(f_str); } /* sanity check */ gi = GeoIP_open(file_path_test, GEOIP_STANDARD); if (verbose == 1) GeoIP_printf(f,"Performing santity checks ... "); if (gi == NULL) { GeoIP_printf(f,"Error opening sanity check database\n"); return GEOIP_SANITY_OPEN_ERR; } /* get the database type */ dbtype = GeoIP_database_edition(gi); if (verbose == 1) { GeoIP_printf(f, "Database type is %d\n",dbtype); } /* this checks to make sure the files is complete, since info is at the end dependent on future databases having MaxMind in info (ISP and Organization databases currently don't have info string */ if ((dbtype != GEOIP_ISP_EDITION)&& (dbtype != GEOIP_ORG_EDITION)) { if (verbose == 1) GeoIP_printf(f,"database_info "); db_info = GeoIP_database_info(gi); if (db_info == NULL) { GeoIP_delete(gi); if (verbose == 1) GeoIP_printf(f,"FAIL null\n"); return GEOIP_SANITY_INFO_FAIL; } if (strstr(db_info, "MaxMind") == NULL) { free(db_info); GeoIP_delete(gi); if (verbose == 1) GeoIP_printf(f,"FAIL maxmind\n"); return GEOIP_SANITY_INFO_FAIL; } free(db_info); if (verbose == 1) GeoIP_printf(f,"PASS "); } /* this performs an IP lookup test of a US IP address */ if (verbose == 1) GeoIP_printf(f,"lookup "); if (dbtype == GEOIP_NETSPEED_EDITION) { int netspeed = GeoIP_id_by_name(gi,"24.24.24.24"); lookupresult = 0; if (netspeed == GEOIP_CABLEDSL_SPEED){ lookupresult = 1; } } if (dbtype == GEOIP_COUNTRY_EDITION) { /* if data base type is country then call the function * named GeoIP_country_code_by_addr */ lookupresult = 1; if (strcmp(GeoIP_country_code_by_addr(gi,"24.24.24.24"), "US") != 0) { lookupresult = 0; } if (verbose == 1) { GeoIP_printf(f,"testing GEOIP_COUNTRY_EDITION\n"); } } if (dbtype == GEOIP_REGION_EDITION_REV1) { /* if data base type is region then call the function * named GeoIP_region_by_addr */ GeoIPRegion *r = GeoIP_region_by_addr(gi,"24.24.24.24"); lookupresult = 0; if (r != NULL) { lookupresult = 1; free(r); } if (verbose == 1) { GeoIP_printf(f,"testing GEOIP_REGION_EDITION\n"); } } if (dbtype == GEOIP_CITY_EDITION_REV1) { /* if data base type is city then call the function * named GeoIP_record_by_addr */ GeoIPRecord *r = GeoIP_record_by_addr(gi,"24.24.24.24"); lookupresult = 0; if (r != NULL) { lookupresult = 1; free(r); } if (verbose == 1) { GeoIP_printf(f,"testing GEOIP_CITY_EDITION\n"); } } if ((dbtype == GEOIP_ISP_EDITION)|| (dbtype == GEOIP_ORG_EDITION)) { /* if data base type is isp or org then call the function * named GeoIP_org_by_addr */ GeoIPRecord *r = (GeoIPRecord*)GeoIP_org_by_addr(gi,"24.24.24.24"); lookupresult = 0; if (r != NULL) { lookupresult = 1; free(r); } if (verbose == 1) { if (dbtype == GEOIP_ISP_EDITION) { GeoIP_printf(f,"testing GEOIP_ISP_EDITION\n"); } if (dbtype == GEOIP_ORG_EDITION) { GeoIP_printf(f,"testing GEOIP_ORG_EDITION\n"); } } } if (lookupresult == 0) { GeoIP_delete(gi); if (verbose == 1) GeoIP_printf(f,"FAIL\n"); return GEOIP_SANITY_LOOKUP_FAIL; } GeoIP_delete(gi); if (verbose == 1) GeoIP_printf(f,"PASS\n"); /* install GeoIP.dat.test -> GeoIP.dat */ err = rename(file_path_test, geoipfilename); if (err != 0) { GeoIP_printf(f,"GeoIP Install error while renaming file\n"); return GEOIP_RENAME_ERR; } if (verbose == 1) GeoIP_printf(f,"Done\n"); free(geoipfilename); return 0; }
short int GeoIP_update_database (char * license_key, int verbose, void (*f)( char * )) { struct hostent *hostlist; int sock; char * buf; struct sockaddr_in sa; int offset = 0, err; char * request_uri; char * compr; unsigned long comprLen; FILE *comp_fh, *cur_db_fh, *gi_fh; gzFile gz_fh; char * file_path_gz, * file_path_test; MD5_CONTEXT context; unsigned char buffer[1024], digest[16]; char hex_digest[33] = "00000000000000000000000000000000\0"; unsigned int i; GeoIP * gi; char * db_info; char block[BLOCK_SIZE]; int block_size = BLOCK_SIZE; size_t len; size_t written; _GeoIP_setup_dbfilename(); /* get MD5 of current GeoIP database file */ if ((cur_db_fh = fopen (GeoIPDBFileName[GEOIP_COUNTRY_EDITION], "rb")) == NULL) { GeoIP_printf(f,"%s%s", NoCurrentDB, GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); } else { md5_init(&context); while ((len = fread (buffer, 1, 1024, cur_db_fh)) > 0) md5_write (&context, buffer, len); md5_final (&context); memcpy(digest,context.buf,16); fclose (cur_db_fh); for (i = 0; i < 16; i++) { // "%02x" will write 3 chars snprintf (&hex_digest[2*i], 3, "%02x", digest[i]); } GeoIP_printf(f, MD5Info, hex_digest); } hostlist = GeoIP_get_host_or_proxy(); if (hostlist == NULL) return GEOIP_DNS_ERR; if (hostlist->h_addrtype != AF_INET) return GEOIP_NON_IPV4_ERR; if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { return GEOIP_SOCKET_OPEN_ERR; } memset(&sa, 0, sizeof(struct sockaddr_in)); sa.sin_port = htons(GeoIPHTTPPort); memcpy(&sa.sin_addr, hostlist->h_addr_list[0], hostlist->h_length); sa.sin_family = AF_INET; if (verbose == 1){ GeoIP_printf(f,"Connecting to MaxMind GeoIP Update server\n"); GeoIP_printf(f, "via Host or Proxy Server: %s:%d\n", hostlist->h_name, GeoIPHTTPPort); } /* Download gzip file */ if (connect(sock, (struct sockaddr *)&sa, sizeof(struct sockaddr))< 0) return GEOIP_CONNECTION_ERR; request_uri = malloc(sizeof(char) * (strlen(license_key) + strlen(GeoIPHTTPRequest)+36)); if (request_uri == NULL) return GEOIP_OUT_OF_MEMORY_ERR; sprintf(request_uri,GeoIPHTTPRequest,GeoIPProxyHTTP,GeoIPProxiedHost,license_key, hex_digest); send(sock, request_uri, strlen(request_uri),0); free(request_uri); buf = malloc(sizeof(char) * block_size); if (buf == NULL) return GEOIP_OUT_OF_MEMORY_ERR; if (verbose == 1) GeoIP_printf(f,"Downloading gzipped GeoIP Database...\n"); for (;;) { int amt; amt = recv(sock, &buf[offset], block_size,0); if (amt == 0) { break; } else if (amt == -1) { free(buf); return GEOIP_SOCKET_READ_ERR; } offset += amt; buf = realloc(buf, offset+block_size); if (buf == NULL) return GEOIP_OUT_OF_MEMORY_ERR; } compr = strstr(buf, "\r\n\r\n") + 4; comprLen = offset + buf - compr; if (strstr(compr, "License Key Invalid") != NULL) { if (verbose == 1) GeoIP_printf(f,"Failed\n"); free(buf); return GEOIP_LICENSE_KEY_INVALID_ERR; } else if (strstr(compr, "Invalid product ID or subscription expired") != NULL){ free(buf); return GEOIP_PRODUCT_ID_INVALID_ERR; } else if (strstr(compr, "No new updates available") != NULL) { free(buf); return GEOIP_NO_NEW_UPDATES; } if (verbose == 1) GeoIP_printf(f,"Done\n"); /* save gzip file */ file_path_gz = malloc(sizeof(char) * (strlen(GeoIPDBFileName[GEOIP_COUNTRY_EDITION]) + 4)); if (file_path_gz == NULL) return GEOIP_OUT_OF_MEMORY_ERR; strcpy(file_path_gz,GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); strcat(file_path_gz,".gz"); if (verbose == 1) { GeoIP_printf(f, SavingGzip, file_path_gz); } comp_fh = fopen(file_path_gz, "wb"); if(comp_fh == NULL) { free(file_path_gz); free(buf); return GEOIP_GZIP_IO_ERR; } written = fwrite(compr, 1, comprLen, comp_fh); fclose(comp_fh); free(buf); if ( written != comprLen ) return GEOIP_GZIP_IO_ERR; if (verbose == 1) GeoIP_printf(f,"Done\n"); if (verbose == 1) GeoIP_printf(f,"Uncompressing gzip file ... "); /* uncompress gzip file */ gz_fh = gzopen(file_path_gz, "rb"); file_path_test = malloc(sizeof(char) * (strlen(GeoIPDBFileName[GEOIP_COUNTRY_EDITION]) + 6)); if (file_path_test == NULL) return GEOIP_OUT_OF_MEMORY_ERR; strcpy(file_path_test,GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); strcat(file_path_test,".test"); gi_fh = fopen(file_path_test, "wb"); if(gi_fh == NULL) { free(file_path_test); return GEOIP_TEST_IO_ERR; } for (;;) { int amt; amt = gzread(gz_fh, block, block_size); if (amt == -1) { free(file_path_test); fclose(gi_fh); gzclose(gz_fh); return GEOIP_GZIP_READ_ERR; } if (amt == 0) { break; } if ( fwrite(block,1,amt,gi_fh) != amt ){ free(file_path_test); fclose(gi_fh); gzclose(gz_fh); return GEOIP_GZIP_READ_ERR; } } gzclose(gz_fh); unlink(file_path_gz); free(file_path_gz); fclose(gi_fh); if (verbose == 1) GeoIP_printf(f,"Done\n"); if (verbose == 1) { GeoIP_printf(f, WritingFile, GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); } /* sanity check */ gi = GeoIP_open(file_path_test, GEOIP_STANDARD); if (verbose == 1) GeoIP_printf(f,"Performing santity checks ... "); if (gi == NULL) { GeoIP_printf(f,"Error opening sanity check database\n"); return GEOIP_SANITY_OPEN_ERR; } /* this checks to make sure the files is complete, since info is at the end */ /* dependent on future databases having MaxMind in info */ if (verbose == 1) GeoIP_printf(f,"database_info "); db_info = GeoIP_database_info(gi); if (db_info == NULL) { GeoIP_delete(gi); if (verbose == 1) GeoIP_printf(f,"FAIL\n"); return GEOIP_SANITY_INFO_FAIL; } if (strstr(db_info, "MaxMind") == NULL) { free(db_info); GeoIP_delete(gi); if (verbose == 1) GeoIP_printf(f,"FAIL\n"); return GEOIP_SANITY_INFO_FAIL; } free(db_info); if (verbose == 1) GeoIP_printf(f,"PASS "); /* this performs an IP lookup test of a US IP address */ if (verbose == 1) GeoIP_printf(f,"lookup "); if (strcmp(GeoIP_country_code_by_addr(gi,"24.24.24.24"), "US") != 0) { GeoIP_delete(gi); if (verbose == 1) GeoIP_printf(f,"FAIL\n"); return GEOIP_SANITY_LOOKUP_FAIL; } GeoIP_delete(gi); if (verbose == 1) GeoIP_printf(f,"PASS\n"); /* install GeoIP.dat.test -> GeoIP.dat */ err = rename(file_path_test, GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); if (err != 0) { GeoIP_printf(f,"GeoIP Install error while renaming file\n"); return GEOIP_RENAME_ERR; } if (verbose == 1) GeoIP_printf(f,"Done\n"); return 0; }
int main(void) { FILE *f; char *db_info; char ipAddress[30]; char expectedCountry[3]; char expectedCountry3[4]; const char *returnedCountry; GeoIP *gi; int failed = 0; int test_num = 1; int i; for (i = 0; i < 2; ++i) { if (0 == i) { /* Read from filesystem, check for updated file */ gi = GeoIP_open(SRCDIR "/data/GeoIP.dat", GEOIP_STANDARD | GEOIP_CHECK_CACHE); } else { /* Read from memory, faster but takes up more memory */ gi = GeoIP_open(SRCDIR "/data/GeoIP.dat", GEOIP_MEMORY_CACHE); } if (gi == NULL) { fprintf(stderr, "Error opening database\n"); exit(1); } db_info = GeoIP_database_info(gi); if (!db_info || strcmp(db_info, "GEO-106 20160621 Build 1 Copyright (c) 2016 " "MaxMind Inc All Rights Reserved")) { fprintf(stderr, "Error reading database info (got %s).\n", db_info); free(db_info); failed = 1; } /* make sure GeoIP deals with invalid query gracefully */ returnedCountry = GeoIP_country_code_by_addr(gi, NULL); if (returnedCountry != NULL) { fprintf(stderr, "Invalid Query test failed, got non NULL, expected NULL\n"); failed = 1; } returnedCountry = GeoIP_country_code_by_name(gi, NULL); if (returnedCountry != NULL) { fprintf(stderr, "Invalid Query test failed, got non NULL, expected NULL\n"); failed = 1; } f = fopen(SRCDIR "/test/country_test.txt", "r"); while ( fscanf(f, "%s%s%s", ipAddress, expectedCountry, expectedCountry3) != EOF) { returnedCountry = GeoIP_country_code_by_addr(gi, ipAddress); if (returnedCountry == NULL || strcmp(returnedCountry, expectedCountry) != 0) { fprintf(stderr, "Test addr %d for %s failed, got %s, expected %s\n", test_num, ipAddress, returnedCountry, expectedCountry); failed = 1; } returnedCountry = GeoIP_country_code_by_name(gi, ipAddress); if (returnedCountry == NULL || strcmp(returnedCountry, expectedCountry) != 0) { fprintf(stderr, "Test name %d for %s failed, got %s, expected %s\n", test_num, ipAddress, returnedCountry, expectedCountry); failed = 1; } returnedCountry = GeoIP_country_code3_by_addr(gi, ipAddress); if (returnedCountry == NULL || strcmp(returnedCountry, expectedCountry3) != 0) { fprintf(stderr, "Test addr %d for %s failed, got %s, expected %s\n", test_num, ipAddress, returnedCountry, expectedCountry); failed = 1; } returnedCountry = GeoIP_country_code3_by_name(gi, ipAddress); if (returnedCountry == NULL || strcmp(returnedCountry, expectedCountry3) != 0) { fprintf(stderr, "Test name %d for %s failed, got %s, expected %s\n", test_num, ipAddress, returnedCountry, expectedCountry); failed = 1; } test_num++; } fclose(f); f = fopen(SRCDIR "/test/country_test2.txt", "r"); while (fscanf(f, "%s%s", ipAddress, expectedCountry) != EOF) { returnedCountry = GeoIP_country_code_by_addr(gi, ipAddress); if (returnedCountry == NULL || strcmp(returnedCountry, expectedCountry) != 0) { fprintf(stderr, "Test addr %d %s failed, got %s, expected %s\n", test_num, ipAddress, returnedCountry, expectedCountry); failed = 1; } test_num++; } fclose(f); GeoIP_delete(gi); } return failed; }
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)"); } }
/* 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; }
void parse(char *country_input, char *path_input, char *domain_input, char *ipaddress_input, char *http_status_input, char *referer_input, char *bird, char *db_path, int minimum_field_count) { // GENERIC VARIABLES char *fields[MAX_FIELD_CNT]; // number of fields we expect in a single line int num_filters = 0; // total number of filters we detect from the command line int num_domain_filters = 0; // total number of domain filters int num_path_filters = 0; // total number of path filters int num_ipaddress_filters = 0; // total number of ipaddress filter int num_countries_filters = 0; // total number countries we want to restrict the filtering int num_http_status_filters = 0; // total number of http status we want to restrict the filtering. int num_referer_filters = 0; int required_hits = 0; int bird_int = 0; int i; int field_count_this_line=0; // number of fields found in the current line char line[ LINE_BUF_SIZE ]; char *ipaddr; char *url; char *http_status; char *referer; // DETERMINE NUMBER OF FILTERS if(params[DOMAIN_FILTER]){ num_domain_filters = determine_num_obs(domain_input,comma_delimiter); required_hits+=1; } if(params[PATH_FILTER]){ num_path_filters = determine_num_obs(path_input,comma_delimiter); required_hits+=1; } if(params[IP_FILTER]){ num_ipaddress_filters = determine_num_obs(ipaddress_input, comma_delimiter); required_hits+=1; } if(params[GEO_FILTER]){ if(country_input != NULL && strlen(country_input) >1){ num_countries_filters = determine_num_obs(country_input, comma_delimiter); required_hits+=1; } } if(params[REFERER_FILTER]){ num_referer_filters = determine_num_obs(referer_input, comma_delimiter); required_hits+=1; } if(params[HTTP_STATUS_FILTER]){ if(http_status_input != NULL && strlen(http_status_input) >1){ num_http_status_filters = determine_num_obs(http_status_input, comma_delimiter); required_hits+=1; } } num_filters = num_path_filters + num_domain_filters + num_ipaddress_filters + num_countries_filters + num_http_status_filters + num_referer_filters; Filter filters[num_filters]; // GEO_FILTER INITIALIZATION GeoIP *gi = NULL; // initialize to suppress compiler warning char *countries[num_countries_filters]; char *area; // FILTER INITIALIZATION if(params[DOMAIN_FILTER]){ init_domains(filters, domain_input, comma_delimiter); } else { domain_input=NULL; } if(params[PATH_FILTER]){ init_paths(filters, path_input, comma_delimiter); } else { path_input = NULL; } if(params[IP_FILTER]){ init_ip_addresses(filters, ipaddress_input, comma_delimiter); } else { ipaddress_input = NULL; } if (params[REFERER_FILTER]){ init_domains(filters, referer_input, comma_delimiter); } else { referer_input = NULL; } if( ! (params[GEO_FILTER] || (recode & GEO)) ) { country_input = NULL; } else { init_countries(countries, country_input, num_countries_filters, comma_delimiter); bird_int = init_bird_level(bird); /* * Before changing the type of cache, have a look at this benchmark: * http://www.maxmind.com/app/benchmark * and choose wisely. */ switch(bird_int){ case COUNTRY: if(db_path!=NULL){ db_country_path=db_path; } gi = GeoIP_open(db_country_path, GEOIP_MEMORY_CACHE); break; case REGION: if(db_path!=NULL){ db_region_path=db_path; } gi = GeoIP_open(db_region_path, GEOIP_MEMORY_CACHE); break; case CITY: if(db_path!=NULL){ db_city_path=db_path; } gi = GeoIP_open(db_city_path, GEOIP_MEMORY_CACHE); break; case LAT_LON: if(db_path!=NULL){ db_city_path=db_path; } gi = GeoIP_open(db_city_path, GEOIP_MEMORY_CACHE); break; case EVERYTHING: if(db_path!=NULL){ db_city_path=db_path; } gi = GeoIP_open(db_city_path, GEOIP_MEMORY_CACHE); break; } if (gi == NULL) { fprintf(stderr, "Error opening MaxMind Geo database.\n"); fprintf(stderr, "Path used for country database:%s\n", db_country_path); fprintf(stderr, "Path used for region database:%s\n", db_region_path); fprintf(stderr, "Path used for city database:%s\n", db_city_path); exit(EXIT_FAILURE); } else { if(verbose_flag){ char *db_info =GeoIP_database_info(gi); unsigned char db_edition = GeoIP_database_edition(gi); GeoIPDBTypes geodbtype = (GeoIPDBTypes)db_info; fprintf(stderr,"Maxmind database: %i; version: %i\n", db_edition, geodbtype); } } } if(params[HTTP_STATUS_FILTER]){ init_http_status(filters, http_status_input, comma_delimiter); } else { http_status_input = NULL; } if (verbose_flag){ fprintf(stderr, "num_path_filters:%d\tnum_domain_filters:%d" "\tnum_http_status_filters:%d\tip_address_count:%d" "\tcountries_count:%d\treferer_count:%d\n", num_path_filters, num_domain_filters, num_http_status_filters, num_ipaddress_filters, num_countries_filters, num_referer_filters); } // Now that we have initilaized all the filters, // do the actual filtering and conversion of the // incoming data. while ( true ) { int found =0; area = NULL; char *r; r=fgets(line, LINE_BUF_SIZE, stdin); if(!r) { break; } i = 0; char *p; do { fields[i] = r; //strsep(&r, ws_delimiter); p = strchr( r, *ws_delimiter ); i++; if ( NULL == p ) break; *p = 0; r = p + 1; } while (i < MAX_FIELD_CNT); if (i < minimum_field_count || i == MAX_FIELD_CNT){ continue; // ignore line since field count is outside expected range } // we found i fields in this line. field_count_this_line = i; ipaddr = fields[4]; http_status = fields[5]; url = fields[8]; referer = fields[11]; //ua = fields[13]; // necessary for bot detection if (url != NULL) { if (params[DOMAIN_FILTER]){ found += match_domain(url, filters, num_domain_filters,verbose_flag); } if (params[PATH_FILTER]){ found += match_path(url, filters, num_path_filters,verbose_flag); } if (params[HTTP_STATUS_FILTER]){ found += match_http_status(http_status, filters, num_http_status_filters,verbose_flag); } if (params[IP_FILTER]){ found += match_ip_address(ipaddr, filters, num_ipaddress_filters,verbose_flag); } if (params[REFERER_FILTER]){ found += match_domain(referer, filters, num_referer_filters,verbose_flag); } if (params[GEO_FILTER]){ area = geo_lookup(gi, ipaddr, bird_int); found += geo_check(area, countries, num_countries_filters,verbose_flag); if (verbose_flag){ fprintf(stderr, "IP address: %s was geocoded as: %s\n", ipaddr, area); } } } // required_hits will equal the number of filters // given. These include ip, domain, path, status, // and country filtering. If no filters were given, // then found will be 0 AND require_hits will be 0, // allowing the line to pass through. if (found >= required_hits) { // if we need to replace the IP addr // because recode is GEO or ANONYMIZE or both if (recode) { // geocode if we haven't already geocoded and // we'll be needing the geocoded string when // replacing the IP. if (area == NULL && (recode & GEO)) { area = geo_lookup(gi, ipaddr, bird_int); } // replace the ip address in fields. // if area is not null, it will be appended // to the ip address. If (recode & ANONYMIZE) is // true, then the IP will be replaced. replace_ip_addr(fields, area, (recode & ANONYMIZE)); } // print output to stdout for (i=0;i<field_count_this_line;++i){ if (i!=0){ FPUTS(ws_delimiter, stdout); } FPUTS(fields[i], stdout); } } if (verbose_flag) { fprintf(stderr, "ipaddr: '%s', url: '%s, status: %s'\n", ipaddr, url, http_status); } } free_memory(filters, path_input, domain_input,num_filters, gi, countries, num_countries_filters); }