pkgconfigdir = $(libdir)/pkgconfig
# Overwrite Python path
-#pkgpythondir = $(pythondir)/location
-pkgpythondir = /usr/lib/python3/dist-packages/location
+pkgpythondir = $(pythondir)/location
%: %.in Makefile
$(SED_PROCESS)
src/perl/t/Location.t \
src/perl/typemap
-.PHONY: build-perl
-build-perl:
+build-perl: src/libloc.la
@mkdir -p $(builddir)/src/perl/{lib,t}
@test -e $(builddir)/src/perl/Location.xs || ln -s --relative $(srcdir)/src/perl/Location.xs $(builddir)/src/perl/
@test -e $(builddir)/src/perl/MANIFEST || ln -s --relative $(srcdir)/src/perl/MANIFEST $(builddir)/src/perl/
@test -e $(builddir)/src/perl/t/Location.t || ln -s --relative $(srcdir)/src/perl/t/Location.t $(builddir)/src/perl/t/
@test -e $(builddir)/src/perl/typemap || ln -s --relative $(srcdir)/src/perl/typemap $(builddir)/src/perl/
- cd $(builddir)/src/perl && $(PERL) Makefile.PL PREFIX="$(prefix)" \
+ cd $(builddir)/src/perl && $(PERL) Makefile.PL NO_PACKLIST=1 NO_PERLLOCAL=1 \
+ INSTALLDIRS=vendor \
INC="-I$(abs_srcdir)/src" LIBS="-L$(abs_builddir)/src/.libs -lloc"
- cd $(builddir)/src/perl && $(MAKE) LD_RUN_PATH=
+ cd $(builddir)/src/perl && $(MAKE)
+ touch build-perl
.PHONY: check-perl
-check-perl: testdata.db
+check-perl: testdata.db build-perl
cd $(builddir)/src/perl && $(MAKE) LD_LIBRARY_PATH="$(abs_builddir)/src/.libs" test \
database="../../$<" keyfile="$(abs_srcdir)/examples/public-key.pem"
.PHONY: install-perl
-install-perl:
- cd $(builddir)/src/perl && $(MAKE) install DESTIDR=$(DESTDIR)
+install-perl: build-perl
+ cd $(builddir)/src/perl && $(MAKE) install DESTDIR=$(DESTDIR)
.PHONY: clean-perl
clean-perl:
cd $(builddir)/src/perl && $(MAKE) distclean
+ rm -f build-perl
.PHONY: uninstall-perl
uninstall-perl:
- rm -rvf \
- $(DESTDIR)/$(prefix)/lib/*/perl/*/Location.pm \
- $(DESTDIR)/$(prefix)/lib/*/perl/*/auto/Location \
- $(DESTDIR)/$(prefix)/lib/*/perl/*/perllocal.pod \
- $(DESTDIR)/$(prefix)/man/man3/Location.3pm
+ rm -vf \
+ $(DESTDIR)/@PERL_MODPATH@/Location.pm \
+ $(DESTDIR)/@PERL_MODPATH@/auto/Location/Location.so \
+ $(DESTDIR)/@PERL_MANPATH@/Location.3pm
+ -rmdir $(DESTDIR)/@PERL_MODPATH@/auto/Location
bin_SCRIPTS = \
src/scripts/location \
# ------------------------------------------------------------------------------
dist_database_DATA = \
- src/signing-key.pem
+ data/database.db \
+ data/signing-key.pem
+
+install-data-hook:
+ chmod 444 $(DESTDIR)$(databasedir)/database.db
+
+.PHONY: update-database
+update-database:
+ curl https://location.ipfire.org/databases/1/location.db.xz | xz -d > data/database.db
# ------------------------------------------------------------------------------
TESTS_ENVIRONMENT = \
PYTHONPATH=$(abs_srcdir)/src/python:$(abs_builddir)/src/python/.libs \
- TEST_DATA_DIR="$(abs_top_srcdir)/tests/data"
+ TEST_DATA_DIR="$(abs_top_srcdir)/data"
TESTS = \
$(check_PROGRAMS) \
$(dist_check_SCRIPTS)
-EXTRA_DIST += \
- tests/data/location-2022-03-30.db \
- tests/data/signing-key.pem
-
CLEANFILES += \
testdata.db
MANPAGES = \
$(MANPAGES_3) \
- $(MANPAGES_8)
+ $(MANPAGES_1)
MANPAGES_3 = \
man/libloc.3 \
man/loc_set_log_fn.3 \
man/loc_set_log_priority.3
-MANPAGES_8 = \
- man/location.8
+MANPAGES_1 = \
+ man/location.1
-MANPAGES_TXT = $(MANPAGES_TXT_3) $(MANPAGES_TXT_8)
+MANPAGES_TXT = $(MANPAGES_TXT_3) $(MANPAGES_TXT_1)
MANPAGES_TXT_3 = $(patsubst %.3,%.txt,$(MANPAGES_3))
-MANPAGES_TXT_8 = $(patsubst %.8,%.txt,$(MANPAGES_8))
+MANPAGES_TXT_1 = $(patsubst %.1,%.txt,$(MANPAGES_1))
MANPAGES_HTML = $(patsubst %.txt,%.html,$(MANPAGES_TXT))
MANPAGES_XML = $(patsubst %.txt,%.xml,$(MANPAGES_TXT))
man/%.3: man/%.xml
$(XSLTPROC_COMMAND_MAN)
-man/%.8: man/%.xml
+man/%.1: man/%.xml
$(XSLTPROC_COMMAND_MAN)
man/%.html: man/%.txt man/asciidoc.conf
AC_PREREQ(2.60)
AC_INIT([libloc],
- [0.9.15],
+ [0.9.16],
[location@lists.ipfire.org],
[libloc],
[https://location.ipfire.org/])
AC_ARG_WITH([database-path],
AS_HELP_STRING([--with-database-path], [The default database path]),
- [], [with_database_path=/var/lib/${PACKAGE_NAME}/database.db]
+ [], [with_database_path=/var/lib/location/database.db]
)
if test -z "${with_database_path}"; then
AC_PATH_PROG(PERL, perl, no)
AC_SUBST(PERL)
-AX_PROG_PERL_MODULES(ExtUtils::MakeMaker,, AC_MSG_WARN(Need some Perl modules))
+AX_PROG_PERL_MODULES(Config ExtUtils::MakeMaker,, AC_MSG_WARN(Need some Perl modules))
AC_ARG_ENABLE(perl, AS_HELP_STRING([--disable-perl], [do not build the perl modules]), [],[enable_perl=yes])
AM_CONDITIONAL(ENABLE_PERL, test "$enable_perl" = "yes")
+AS_IF([test "$enable_perl" = "yes"],
+ [
+ PERL_MODPATH=$($PERL -MConfig -e 'print $Config{installvendorarch}')
+ PERL_MANPATH=$($PERL -MConfig -e 'print $Config{installvendorman3dir}')
+ AC_SUBST(PERL_MODPATH)
+ AC_SUBST(PERL_MANPATH)
+ ],
+)
dnl Checking for libresolv
case "${host}" in
systemd support: ${have_systemd}
Bindings:
- perl: ${enable_perl}
+ Perl: ${enable_perl}
+ Perl module path: ${PERL_MODPATH}
+ Perl manual path: ${PERL_MANPATH}
])
== See Also
-link:location[8]
+link:location[1]
== Bug Reports
-= location(8)
+= location(1)
== NAME
location - Query the location database
}
}
+ int sig1_valid = 0;
+ int sig2_valid = 0;
+
// Check first signature
- if (db->signature1.data) {
+ if (db->signature1.length) {
hexdump(db->ctx, db->signature1.data, db->signature1.length);
r = EVP_DigestVerifyFinal(mdctx,
if (r == 0) {
DEBUG(db->ctx, "The first signature is invalid\n");
- r = 1;
} else if (r == 1) {
DEBUG(db->ctx, "The first signature is valid\n");
- r = 0;
+ sig1_valid = 1;
} else {
ERROR(db->ctx, "Error verifying the first signature: %s\n",
ERR_error_string(ERR_get_error(), NULL));
r = -1;
+ goto CLEANUP;
}
}
// Check second signature only when the first one was invalid
- if (r && db->signature2.data) {
+ if (db->signature2.length) {
hexdump(db->ctx, db->signature2.data, db->signature2.length);
r = EVP_DigestVerifyFinal(mdctx,
if (r == 0) {
DEBUG(db->ctx, "The second signature is invalid\n");
- r = 1;
} else if (r == 1) {
DEBUG(db->ctx, "The second signature is valid\n");
- r = 0;
+ sig2_valid = 1;
} else {
ERROR(db->ctx, "Error verifying the second signature: %s\n",
ERR_error_string(ERR_get_error(), NULL));
r = -1;
+ goto CLEANUP;
}
}
INFO(db->ctx, "Signature checked in %.4fms\n",
(double)(end - start) / CLOCKS_PER_SEC * 1000);
+ // Check if at least one signature as okay
+ if (sig1_valid || sig2_valid)
+ r = 0;
+ else
+ r = 1;
+
CLEANUP:
// Cleanup
EVP_MD_CTX_free(mdctx);
-#!/usr/bin/python3
###############################################################################
# #
# libloc - A library to determine the location of someone on the Internet #
# Import everything from the C module
from _location import *
+from _location import __version__
# Initialise logging
from . import logger
-#!/usr/bin/env python
-
"""
A lightweight wrapper around psycopg2.
-#!/usr/bin/python3
###############################################################################
# #
# libloc - A library to determine the location of someone on the Internet #
-#!/usr/bin/python3
###############################################################################
# #
# libloc - A library to determine the location of someone on the Internet #
self.family = family
self.directory = directory
+ # Tag
+ self.tag = self._make_tag()
+
# Open output file
if f:
self.f = f
else:
self.f = io.StringIO()
- # Tag
- self.tag = self._make_tag()
-
# Call any custom initialization
self.init()
-#!/usr/bin/python3
###############################################################################
# #
# libloc - A library to determine the location of someone on the Internet #
-#!/usr/bin/python3
###############################################################################
# #
# libloc - A library to determine the location of someone on the Internet #
-#!/usr/bin/python3
###############################################################################
# #
# libloc - A library to determine the location of someone on the Internet #
return -1;
// Re-open file descriptor
- f2 = fdopen(fd, "r");
- if (!f2) {
+ f1 = fdopen(fd, "r");
+ if (!f1) {
PyErr_SetFromErrno(PyExc_IOError);
return -1;
}
"ap-southeast-2": "AU",
"ap-southeast-3": "MY",
"ap-southeast-4": "AU",
+ "ap-southeast-6": "AP", # XXX: Precise location not documented anywhere
"ap-northeast-1": "JP",
"ca-central-1": "CA",
+ "ca-west-1": "CA",
"eu-central-1": "DE",
"eu-central-2": "CH",
"eu-west-1": "IE",
def _update_overrides_for_spamhaus_drop(self):
downloader = location.importer.Downloader()
- ip_urls = [
- "https://www.spamhaus.org/drop/drop.txt",
- "https://www.spamhaus.org/drop/edrop.txt",
- "https://www.spamhaus.org/drop/dropv6.txt"
+ ip_lists = [
+ ("SPAMHAUS-DROP", "https://www.spamhaus.org/drop/drop.txt"),
+ ("SPAMHAUS-EDROP", "https://www.spamhaus.org/drop/edrop.txt"),
+ ("SPAMHAUS-DROPV6", "https://www.spamhaus.org/drop/dropv6.txt")
]
- asn_urls = [
- "https://www.spamhaus.org/drop/asndrop.txt"
+ asn_lists = [
+ ("SPAMHAUS-ASNDROP", "https://www.spamhaus.org/drop/asndrop.txt")
]
- for url in ip_urls:
- # Fetch IP list
+ for name, url in ip_lists:
+ # Fetch IP list from given URL
f = downloader.retrieve(url)
# Split into lines
fcontent = f.readlines()
- # Conduct a very basic sanity check to rule out CDN issues causing bogus DROP
- # downloads.
- if len(fcontent) > 10:
- self.db.execute("""
- DELETE FROM autnum_overrides WHERE source = 'Spamhaus ASN-DROP list';
- DELETE FROM network_overrides WHERE source = 'Spamhaus DROP lists';
- """)
- else:
- log.error("Spamhaus DROP URL %s returned likely bogus file, ignored" % url)
- continue
-
- # Iterate through every line, filter comments and add remaining networks to
- # the override table in case they are valid...
with self.db.transaction():
+ # Conduct a very basic sanity check to rule out CDN issues causing bogus DROP
+ # downloads.
+ if len(fcontent) > 10:
+ self.db.execute("DELETE FROM network_overrides WHERE source = %s", name)
+ else:
+ log.error("%s (%s) returned likely bogus file, ignored" % (name, url))
+ continue
+
+ # Iterate through every line, filter comments and add remaining networks to
+ # the override table in case they are valid...
for sline in fcontent:
# The response is assumed to be encoded in UTF-8...
sline = sline.decode("utf-8")
# Sanitize parsed networks...
if not self._check_parsed_network(network):
- log.warning("Skipping bogus network found in Spamhaus DROP URL %s: %s" % \
- (url, network))
+ log.warning("Skipping bogus network found in %s (%s): %s" % \
+ (name, url, network))
continue
# Conduct SQL statement...
) VALUES (%s, %s, %s)
ON CONFLICT (network) DO UPDATE SET is_drop = True""",
"%s" % network,
- "Spamhaus DROP lists",
+ name,
True
)
- for url in asn_urls:
+ for name, url in asn_lists:
# Fetch URL
f = downloader.retrieve(url)
- # Iterate through every line, filter comments and add remaining ASNs to
- # the override table in case they are valid...
+ # Split into lines
+ fcontent = f.readlines()
+
with self.db.transaction():
+ # Conduct a very basic sanity check to rule out CDN issues causing bogus DROP
+ # downloads.
+ if len(fcontent) > 10:
+ self.db.execute("DELETE FROM autnum_overrides WHERE source = %s", name)
+ else:
+ log.error("%s (%s) returned likely bogus file, ignored" % (name, url))
+ continue
+
+ # Iterate through every line, filter comments and add remaining ASNs to
+ # the override table in case they are valid...
for sline in f.readlines():
# The response is assumed to be encoded in UTF-8...
sline = sline.decode("utf-8")
# Filter invalid ASNs...
if not self._check_parsed_asn(asn):
- log.warning("Skipping bogus ASN found in Spamhaus DROP URL %s: %s" % \
- (url, asn))
+ log.warning("Skipping bogus ASN found in %s (%s): %s" % \
+ (name, url, asn))
continue
# Conduct SQL statement...
) VALUES (%s, %s, %s)
ON CONFLICT (number) DO UPDATE SET is_drop = True""",
"%s" % asn,
- "Spamhaus ASN-DROP list",
+ name,
True
)
[Unit]
Description=Automatic Location Database Updater
-Documentation=man:location(8) https://man-pages.ipfire.org/libloc/location.html
+Documentation=man:location(1) https://man-pages.ipfire.org/libloc/location.html
Requires=network.target
[Service]
}
// Open another public key
- public_key = freopen(ABS_SRCDIR "/src/signing-key.pem", "r", public_key);
+ public_key = freopen(ABS_SRCDIR "/data/signing-key.pem", "r", public_key);
if (!public_key) {
fprintf(stderr, "Could not open public key file: %m\n");
exit(EXIT_FAILURE);
return r;
}
+ // Add an empty string to the stringpool
+ r = loc_stringpool_add(w->pool, "");
+ if (r) {
+ loc_writer_unref(w);
+ return r;
+ }
+
// Initialize the network tree
r = loc_network_tree_new(ctx, &w->networks);
if (r) {
if (writer->signature2_length) {
DEBUG(writer->ctx, "Copying second signature of %zu byte(s)\n",
- writer->signature1_length);
+ writer->signature2_length);
memcpy(header.signature2, writer->signature2, writer->signature2_length);
header.signature2_length = htobe16(writer->signature2_length);
+++ /dev/null
-../../src/signing-key.pem
\ No newline at end of file
class Test(unittest.TestCase):
def setUp(self):
- path = os.path.join(TEST_DATA_DIR, "location-2022-03-30.db")
+ path = os.path.join(TEST_DATA_DIR, "database.db")
# Load the database
self.db = location.Database(path)
self.assertEqual(self.db.license, "CC BY-SA 4.0")
# Created At
- self.assertEqual(self.db.created_at, 1648619023)
+ self.assertIsInstance(self.db.created_at, int)
def test_fetch_network(self):
"""
class Test(unittest.TestCase):
def setUp(self):
- path = os.path.join(TEST_DATA_DIR, "location-2022-03-30.db")
+ path = os.path.join(TEST_DATA_DIR, "database.db")
# Load the database
self.db = location.Database(path)