Beispiel #1
0
ipdata_t *ipdata_lookup(const char *inaddr, db_t *dbp)
{
  char *city, *region, *country, *asnum, *empty = "X";
  city = region = country = asnum = empty;
  ipdata_t *ip = NULL;
  GeoIPRecord *grp = NULL;

  if(!inaddr) return NULL;

  ip = MALLOCORDIE(sizeof(ipdata_t), "ipdata_lookup()");
  ip->latitude = 0.0;
  ip->longitude = 0.0;

  /* Query the city database, if we have it. */
  if(dbp->citygp)
  {
    if(opts.family == AF_INET6)
      grp = GeoIP_record_by_name_v6(dbp->citygp, inaddr);
    else grp = GeoIP_record_by_name(dbp->citygp, inaddr);

    if(grp)
    {
      if(grp->city) city = grp->city;
      if(grp->region) region = grp->region;
      if(grp->country_code) country = grp->country_code;
      ip->latitude = grp->latitude;
      ip->longitude = grp->longitude;
    }
  }

  /* Query the asnum database, if we have it. */
  if(dbp->asgp)
  {
    if(opts.family == AF_INET6)
      asnum = GeoIP_org_by_name_v6(dbp->asgp, inaddr);
    else asnum = GeoIP_org_by_name(dbp->asgp, inaddr);
    if(!asnum) asnum = empty;
  }

  /* Copy data into ipdata_t for great thread safety. */
  ip->address = MALLOCORDIE(strlen(inaddr) + 1, "ipdata_lookup()");
  strcpy(ip->address, inaddr);
  ip->city = MALLOCORDIE(strlen(city) + 1, "ipdata_lookup()");
  strcpy(ip->city, city);
  ip->region = MALLOCORDIE(strlen(region) + 1, "ipdata_lookup()");
  strcpy(ip->region, region);
  ip->country = MALLOCORDIE(strlen(country) + 1, "ipdata_lookup()");
  strcpy(ip->country, country);
  ip->asnum = MALLOCORDIE(strlen(asnum) + 1, "ipdata_lookup()");
  strcpy(ip->asnum, asnum);

  if(strcmp(asnum, empty)) free(asnum);
  if(grp) GeoIPRecord_delete(grp);
  return ip;
}
Beispiel #2
0
/* Get detailed information found in the GeoIP Database about the
 * given IPv4 or IPv6.
 *
 * On error, NULL is returned
 * On success, GeoIPRecord structure is returned */
static GeoIPRecord *
get_geoip_record (const char *addr, GTypeIP type_ip)
{
  GeoIPRecord *rec = NULL;

  if (TYPE_IPV4 == type_ip)
    rec = GeoIP_record_by_name (geo_location_data, addr);
  else if (TYPE_IPV6 == type_ip)
    rec = GeoIP_record_by_name_v6 (geo_location_data, addr);

  return rec;
}
Beispiel #3
0
static PyObject * GeoIP_record_by_name_v6_Py(PyObject *self, PyObject *args) {
  char * name;
  GeoIPRecord * gir;
  GeoIP_GeoIPObject* GeoIP = (GeoIP_GeoIPObject*)self;
  if (!PyArg_ParseTuple(args, "s", &name)) {
    return NULL;
  }
  gir = GeoIP_record_by_name_v6(GeoIP->gi, name);
	if (gir == NULL) {
		Py_INCREF(Py_None);
		return Py_None;
	}
	return GeoIP_populate_dict(GeoIP->gi, gir);
}
Beispiel #4
0
/* Use the GeoIP API to locate an IP address
 */
char *GeoIPLookup(char *ip)
{
	GeoIP	*gi;
	GeoIPRecord	*gir;
	char buffer[OS_SIZE_1024 +1];
        unsigned long longip;

	/* Dumb way to detect an IPv6 address */
	if (strchr(ip, ':')) {
		/* Use the IPv6 DB */
		gi = GeoIP_open(Config.geoip_db_path, GEOIP_INDEX_CACHE);
		if (gi == NULL) {
			merror(INVALID_GEOIP_DB, ARGV0, Config.geoip6_db_path);
			return("Unknown");
		}
		gir = GeoIP_record_by_name_v6(gi, (const char *)ip);
	}
	else {
		/* Use the IPv4 DB */
                /* If we have a RFC1918 IP, do not perform a DB lookup (performance) */
                longip = StrIP2Int(ip);
                if (longip == 0 ) return("Unknown");
                if ((longip & NETMASK_8)  == RFC1918_10 ||
                    (longip & NETMASK_12) == RFC1918_172 ||
                    (longip & NETMASK_16) == RFC1918_192) return("");

		gi = GeoIP_open(Config.geoip_db_path, GEOIP_INDEX_CACHE);
		if (gi == NULL) {
			merror(INVALID_GEOIP_DB, ARGV0, Config.geoip_db_path);
			return("Unknown");
		}
		gir = GeoIP_record_by_name(gi, (const char *)ip);
	}
	if (gir != NULL) {
		sprintf(buffer,"%s,%s,%s",
				_mk_NA(gir->country_code),
				_mk_NA(GeoIP_region_name_by_code(gir->country_code, gir->region)),
				_mk_NA(gir->city)
		);
		GeoIP_delete(gi);
		return(buffer);
	}
	GeoIP_delete(gi);
	return("Unknown");
}
Beispiel #5
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;
}
Beispiel #6
0
void
geoiplookup(GeoIP * gi, char *hostname, int i)
{
	const char     *country_code;
	const char     *country_name;
	const char     *domain_name;
        const char     *asnum_name;        
	int             netspeed;
	int             country_id;
	GeoIPRegion    *region;
	GeoIPRecord    *gir;
	const char     *org;

	geoipv6_t       ipnum;
	ipnum = _GeoIP_lookupaddress_v6(hostname);
	if (__GEOIP_V6_IS_NULL(ipnum)) {
		printf("%s: can't resolve hostname ( %s )\n", GeoIPDBDescription[i], hostname);

	}
	else {


#if 0
		if (GEOIP_DOMAIN_EDITION_V6 == i) {
			domain_name = GeoIP_name_by_name_v6(gi, hostname);
			if (domain_name == NULL) {
				printf("%s: IP Address not found\n", GeoIPDBDescription[i]);
			}
			else {
				printf("%s: %s\n", GeoIPDBDescription[i], domain_name);
			}
		}
#endif



		if (GEOIP_LOCATIONA_EDITION_V6 == i || GEOIP_ASNUM_EDITION_V6 == i || GEOIP_USERTYPE_EDITION_V6 == i || GEOIP_REGISTRAR_EDITION_V6 == i || GEOIP_DOMAIN_EDITION_V6 == i || GEOIP_ORG_EDITION_V6 == i || GEOIP_ISP_EDITION_V6 == i || GEOIP_NETSPEED_EDITION_REV1_V6 == i ) {
			asnum_name = GeoIP_name_by_ipnum_v6(gi, ipnum);
			if (asnum_name == NULL) {
				printf("%s: IP Address not found\n", GeoIPDBDescription[i]);
			}
			else {
				printf("%s: %s\n", GeoIPDBDescription[i], asnum_name);
                              //  _say_range_by_ip(gi, ipnum);
			}
		}
	
        	else if (GEOIP_CITY_EDITION_REV0_V6 == i) {
		        gir = GeoIP_record_by_name_v6(gi, hostname);
      		        if (NULL == gir) {
			        printf("%s: IP Address not found\n", GeoIPDBDescription[i]);
		        }
		        else {
			        printf("%s: %s, %s, %s, %s, %f, %f\n", GeoIPDBDescription[i], gir->country_code, _mk_NA(gir->region),
				       _mk_NA(gir->city), _mk_NA(gir->postal_code), gir->latitude, gir->longitude);
		        }
	        }
	        else if (GEOIP_CITY_EDITION_REV1_V6 == i) {
		        gir = GeoIP_record_by_name_v6(gi, hostname);
		        if (NULL == gir) {
			        printf("%s: IP Address not found\n", GeoIPDBDescription[i]);
		        }
		        else {
		                printf("%s: %s, %s, %s, %s, %f, %f, %d, %d\n", GeoIPDBDescription[i], gir->country_code, _mk_NA(gir->region), _mk_NA(gir->city), _mk_NA(gir->postal_code),
				       gir->latitude, gir->longitude, gir->metro_code, gir->area_code);
                        }
	        }
	
		else if (GEOIP_COUNTRY_EDITION_V6 == i) {

			country_id = GeoIP_id_by_ipnum_v6(gi, ipnum);
			country_code = GeoIP_country_code[country_id];
			country_name = GeoIP_country_name[country_id];
			if (country_id == 0) {
				printf("%s: IP Address not found\n", GeoIPDBDescription[i]);
			}
			else {
				printf("%s: %s, %s\n", GeoIPDBDescription[i], country_code, country_name);
			}
		}
	}

#if 0

	else
	if (GEOIP_REGION_EDITION_REV0 == i || GEOIP_REGION_EDITION_REV1 == i) {