diff -Nru osmo-hlr-0.1.0/configure.ac osmo-hlr-0.2.1/configure.ac --- osmo-hlr-0.1.0/configure.ac 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/configure.ac 2018-05-04 16:41:35.000000000 +0000 @@ -34,11 +34,11 @@ PKG_CHECK_MODULES(TALLOC, [talloc >= 2.0.1]) -PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.9.5) -PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.9.0) -PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.9.0) -PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl) -PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 0.3.2) +PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.11.0) +PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.11.0) +PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.11.0) +PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 0.11.0) +PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 0.5.0) PKG_CHECK_MODULES(SQLITE3, sqlite3) @@ -47,6 +47,36 @@ dnl checks for header files AC_HEADER_STDC +AC_ARG_ENABLE(sanitize, + [AS_HELP_STRING( + [--enable-sanitize], + [Compile with address sanitizer enabled], + )], + [sanitize=$enableval], [sanitize="no"]) +if test x"$sanitize" = x"yes" +then + CFLAGS="$CFLAGS -fsanitize=address -fsanitize=undefined" + CPPFLAGS="$CPPFLAGS -fsanitize=address -fsanitize=undefined" +fi + +AC_ARG_ENABLE(werror, + [AS_HELP_STRING( + [--enable-werror], + [Turn all compiler warnings into errors, with exceptions: + a) deprecation (allow upstream to mark deprecation without breaking builds); + b) "#warning" pragmas (allow to remind ourselves of errors without breaking builds) + ] + )], + [werror=$enableval], [werror="no"]) +if test x"$werror" = x"yes" +then + WERROR_FLAGS="-Werror" + WERROR_FLAGS+=" -Wno-error=deprecated -Wno-error=deprecated-declarations" + WERROR_FLAGS+=" -Wno-error=cpp" # "#warning" + CFLAGS="$CFLAGS $WERROR_FLAGS" + CPPFLAGS="$CPPFLAGS $WERROR_FLAGS" +fi + AC_ARG_ENABLE([external_tests], AC_HELP_STRING([--enable-external-tests], [Include the VTY/CTRL tests in make check [default=no]]), @@ -62,13 +92,18 @@ AC_MSG_RESULT([$enable_ext_tests]) AM_CONDITIONAL(ENABLE_EXT_TESTS, test "x$enable_ext_tests" = "xyes") +AC_MSG_RESULT([CFLAGS="$CFLAGS"]) +AC_MSG_RESULT([CPPFLAGS="$CPPFLAGS"]) + AC_OUTPUT( Makefile + doc/Makefile src/Makefile sql/Makefile tests/Makefile tests/auc/Makefile tests/auc/gen_ts_55_205_test_sets/Makefile tests/gsup_server/Makefile + tests/gsup/Makefile tests/db/Makefile ) diff -Nru osmo-hlr-0.1.0/contrib/ipa.py osmo-hlr-0.2.1/contrib/ipa.py --- osmo-hlr-0.1.0/contrib/ipa.py 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/contrib/ipa.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,278 +0,0 @@ -#!/usr/bin/python3 -# -*- mode: python-mode; py-indent-tabs-mode: nil -*- -""" -/* - * Copyright (C) 2016 sysmocom s.f.m.c. GmbH - * - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -""" - -import struct, random, sys - -class IPA(object): - """ - Stateless IPA protocol multiplexer: add/remove/parse (extended) header - """ - version = "0.0.5" - TCP_PORT_OML = 3002 - TCP_PORT_RSL = 3003 - # OpenBSC extensions: OSMO, MGCP_OLD - PROTO = dict(RSL=0x00, CCM=0xFE, SCCP=0xFD, OML=0xFF, OSMO=0xEE, MGCP_OLD=0xFC) - # ...OML Router Control, GSUP GPRS extension, Osmocom Authn Protocol - EXT = dict(CTRL=0, MGCP=1, LAC=2, SMSC=3, ORC=4, GSUP=5, OAP=6) - # OpenBSC extension: SCCP_OLD - MSGT = dict(PING=0x00, PONG=0x01, ID_GET=0x04, ID_RESP=0x05, ID_ACK=0x06, SCCP_OLD=0xFF) - _IDTAG = dict(SERNR=0, UNITNAME=1, LOCATION=2, TYPE=3, EQUIPVERS=4, SWVERSION=5, IPADDR=6, MACADDR=7, UNIT=8) - CTRL_GET = 'GET' - CTRL_SET = 'SET' - CTRL_REP = 'REPLY' - CTRL_ERR = 'ERR' - CTRL_TRAP = 'TRAP' - - def _l(self, d, p): - """ - Reverse dictionary lookup: return key for a given value - """ - if p is None: - return 'UNKNOWN' - return list(d.keys())[list(d.values()).index(p)] - - def _tag(self, t, v): - """ - Create TAG as TLV data - """ - return struct.pack(">HB", len(v) + 1, t) + v - - def proto(self, p): - """ - Lookup protocol name - """ - return self._l(self.PROTO, p) - - def ext(self, p): - """ - Lookup protocol extension name - """ - return self._l(self.EXT, p) - - def msgt(self, p): - """ - Lookup message type name - """ - return self._l(self.MSGT, p) - - def idtag(self, p): - """ - Lookup ID tag name - """ - return self._l(self._IDTAG, p) - - def ext_name(self, proto, exten): - """ - Return proper extension byte name depending on the protocol used - """ - if self.PROTO['CCM'] == proto: - return self.msgt(exten) - if self.PROTO['OSMO'] == proto: - return self.ext(exten) - return None - - def add_header(self, data, proto, ext=None): - """ - Add IPA header (with extension if necessary), data must be represented as bytes - """ - if ext is None: - return struct.pack(">HB", len(data) + 1, proto) + data - return struct.pack(">HBB", len(data) + 1, proto, ext) + data - - def del_header(self, data): - """ - Strip IPA protocol header correctly removing extension if present - Returns data length, IPA protocol, extension (or None if not defined for a give protocol) and the data without header - """ - if not len(data): - return None, None, None, None - (dlen, proto) = struct.unpack('>HB', data[:3]) - if self.PROTO['OSMO'] == proto or self.PROTO['CCM'] == proto: # there's extension which we have to unpack - return struct.unpack('>HBB', data[:4]) + (data[4:], ) # length, protocol, extension, data - return dlen, proto, None, data[3:] # length, protocol, _, data - - def split_combined(self, data): - """ - Split the data which contains multiple concatenated IPA messages into tuple (first, rest) where rest contains remaining messages, first is the single IPA message - """ - (length, _, _, _) = self.del_header(data) - return data[:(length + 3)], data[(length + 3):] - - def tag_serial(self, data): - """ - Make TAG for serial number - """ - return self._tag(self._IDTAG['SERNR'], data) - - def tag_name(self, data): - """ - Make TAG for unit name - """ - return self._tag(self._IDTAG['UNITNAME'], data) - - def tag_loc(self, data): - """ - Make TAG for location - """ - return self._tag(self._IDTAG['LOCATION'], data) - - def tag_type(self, data): - """ - Make TAG for unit type - """ - return self._tag(self._IDTAG['TYPE'], data) - - def tag_equip(self, data): - """ - Make TAG for equipment version - """ - return self._tag(self._IDTAG['EQUIPVERS'], data) - - def tag_sw(self, data): - """ - Make TAG for software version - """ - return self._tag(self._IDTAG['SWVERSION'], data) - - def tag_ip(self, data): - """ - Make TAG for IP address - """ - return self._tag(self._IDTAG['IPADDR'], data) - - def tag_mac(self, data): - """ - Make TAG for MAC address - """ - return self._tag(self._IDTAG['MACADDR'], data) - - def tag_unit(self, data): - """ - Make TAG for unit ID - """ - return self._tag(self._IDTAG['UNIT'], data) - - def identity(self, unit=b'', mac=b'', location=b'', utype=b'', equip=b'', sw=b'', name=b'', serial=b''): - """ - Make IPA IDENTITY tag list, by default returns empty concatenated bytes of tag list - """ - return self.tag_unit(unit) + self.tag_mac(mac) + self.tag_loc(location) + self.tag_type(utype) + self.tag_equip(equip) + self.tag_sw(sw) + self.tag_name(name) + self.tag_serial(serial) - - def ping(self): - """ - Make PING message - """ - return self.add_header(b'', self.PROTO['CCM'], self.MSGT['PING']) - - def pong(self): - """ - Make PONG message - """ - return self.add_header(b'', self.PROTO['CCM'], self.MSGT['PONG']) - - def id_ack(self): - """ - Make ID_ACK CCM message - """ - return self.add_header(b'', self.PROTO['CCM'], self.MSGT['ID_ACK']) - - def id_get(self): - """ - Make ID_GET CCM message - """ - return self.add_header(self.identity(), self.PROTO['CCM'], self.MSGT['ID_GET']) - - def id_resp(self, data): - """ - Make ID_RESP CCM message - """ - return self.add_header(data, self.PROTO['CCM'], self.MSGT['ID_RESP']) - -class Ctrl(IPA): - """ - Osmocom CTRL protocol implemented on top of IPA multiplexer - """ - def __init__(self): - random.seed() - - def add_header(self, data): - """ - Add CTRL header - """ - return super(Ctrl, self).add_header(data.encode('utf-8'), IPA.PROTO['OSMO'], IPA.EXT['CTRL']) - - def rem_header(self, data): - """ - Remove CTRL header, check for appropriate protocol and extension - """ - (_, proto, ext, d) = super(Ctrl, self).del_header(data) - if self.PROTO['OSMO'] != proto or self.EXT['CTRL'] != ext: - return None - return d - - def parse(self, data, op=None): - """ - Parse Ctrl string returning (var, value) pair - var could be None in case of ERROR message - value could be None in case of GET message - """ - (s, i, v) = data.split(' ', 2) - if s == self.CTRL_ERR: - return None, v - if s == self.CTRL_GET: - return v, None - (s, i, var, val) = data.split(' ', 3) - if s == self.CTRL_TRAP and i != '0': - return None, '%s with non-zero id %s' % (s, i) - if op is not None and i != op: - if s == self.CTRL_GET + '_' + self.CTRL_REP or s == self.CTRL_SET + '_' + self.CTRL_REP: - return None, '%s with unexpected id %s' % (s, i) - return var, val - - def trap(self, var, val): - """ - Make TRAP message with given (vak, val) pair - """ - return self.add_header("%s 0 %s %s" % (self.CTRL_TRAP, var, val)) - - def cmd(self, var, val=None): - """ - Make SET/GET command message: returns (r, m) tuple where r is random operation id and m is assembled message - """ - r = random.randint(1, sys.maxsize) - if val is not None: - return r, self.add_header("%s %s %s %s" % (self.CTRL_SET, r, var, val)) - return r, self.add_header("%s %s %s" % (self.CTRL_GET, r, var)) - - def verify(self, reply, r, var, val=None): - """ - Verify reply to SET/GET command: returns (b, v) tuple where v is True/False verification result and v is the variable value - """ - (k, v) = self.parse(reply) - if k != var or (val is not None and v != val): - return False, v - return True, v - -if __name__ == '__main__': - print("IPA multiplexer v%s loaded." % IPA.version) diff -Nru osmo-hlr-0.1.0/contrib/jenkins.sh osmo-hlr-0.2.1/contrib/jenkins.sh --- osmo-hlr-0.1.0/contrib/jenkins.sh 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/contrib/jenkins.sh 2018-05-04 16:41:35.000000000 +0000 @@ -36,11 +36,9 @@ cd "$base" autoreconf --install --force -./configure --enable-external-tests +./configure --enable-sanitize --enable-external-tests --enable-werror $MAKE $PARALLEL_MAKE -if [ "x$label" != "xFreeBSD_amd64" ]; then - $MAKE check || cat-testlogs.sh - $MAKE distcheck || cat-testlogs.sh -fi +$MAKE check || cat-testlogs.sh +$MAKE distcheck || cat-testlogs.sh osmo-clean-workspace.sh diff -Nru osmo-hlr-0.1.0/debian/changelog osmo-hlr-0.2.1/debian/changelog --- osmo-hlr-0.1.0/debian/changelog 2018-04-19 17:07:49.000000000 +0000 +++ osmo-hlr-0.2.1/debian/changelog 2018-11-09 21:19:28.000000000 +0000 @@ -1,3 +1,42 @@ +osmo-hlr (0.2.1-3) unstable; urgency=medium + + * debian/control: + - Add my name to uploaders + * debian/rules: + - Disable tests on the architectures mips64el, mipsel and alpha. + + -- Ruben Undheim Fri, 09 Nov 2018 22:19:28 +0100 + +osmo-hlr (0.2.1-2) unstable; urgency=medium + + * Team upload + * Upload to unstable + + -- Ruben Undheim Tue, 06 Nov 2018 07:54:48 +0100 + +osmo-hlr (0.2.1-2~exp1) experimental; urgency=medium + + * Team upload + * debian/gbp.conf: to enforce pristine-tar + * Added default configuration file to /etc/osmocom/osmo-hlr.cfg + * debian/control: New standards version 4.2.1 - no changes + * debian/osmo-hlr.dirs: + - Create dir expected to be present when starting osmo-hlr at first + * debian/rules: + - Do not start systemd service by default + - Properly clean up in override_dh_clean + * debian/tests: + - Add simple autopkgtest checking that it is possible to run "osmo-hlr -h" + + -- Ruben Undheim Sun, 23 Sep 2018 15:43:13 +0200 + +osmo-hlr (0.2.1-1) experimental; urgency=medium + + * New upstream release + * debian/control: adjust minimal version of dependencies + + -- Thorsten Alteholz Fri, 18 May 2018 11:06:52 +0200 + osmo-hlr (0.1.0-3) unstable; urgency=medium * debian/rules: deactivate tests for BE for now diff -Nru osmo-hlr-0.1.0/debian/control osmo-hlr-0.2.1/debian/control --- osmo-hlr-0.1.0/debian/control 2018-04-16 17:05:39.000000000 +0000 +++ osmo-hlr-0.2.1/debian/control 2018-11-09 21:19:28.000000000 +0000 @@ -2,16 +2,17 @@ Section: net Priority: optional Maintainer: Debian Mobcom Maintainers -Uploaders: Thorsten Alteholz +Uploaders: Thorsten Alteholz , + Ruben Undheim Build-Depends: debhelper (>= 11), pkg-config, python-minimal, - libosmocore-dev (>= 0.10.1), - libosmo-abis-dev (>= 0.4.0), - libosmo-netif-dev (>= 0.1.1), + libosmocore-dev (>= 0.11.0), + libosmo-abis-dev (>= 0.5.0), + libosmo-netif-dev (>= 0.2.0), libsqlite3-dev, sqlite3 -Standards-Version: 4.1.4 +Standards-Version: 4.2.1 Vcs-Browser: https://salsa.debian.org/debian-mobcom-team/osmo-hlr Vcs-Git: https://salsa.debian.org/debian-mobcom-team/osmo-hlr.git Homepage: https://projects.osmocom.org/projects/osmo-hlr diff -Nru osmo-hlr-0.1.0/debian/copyright osmo-hlr-0.2.1/debian/copyright --- osmo-hlr-0.1.0/debian/copyright 2018-04-16 17:05:39.000000000 +0000 +++ osmo-hlr-0.2.1/debian/copyright 2018-11-09 21:19:28.000000000 +0000 @@ -7,9 +7,10 @@ Copyright: 2016-2017 Sysmocom s. f. m. c. GmbH License: AGPL-3+ -Files: contrib/ipa.py +Files: debian/* Copyright: 2016-2017 Sysmocom s. f. m. c. GmbH -License: GPL-3+ + 2018 Thorsten Alteholz +License: AGPL-3+ License: AGPL-3+ This program is free software: you can redistribute it and/or modify @@ -24,17 +25,3 @@ . You should have received a copy of the GNU Affero General Public License along with this program. If not, see . - -License: GPL-3+ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - . - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - . - The complete text of the GNU General Public License version 3 - can be found in `/usr/share/common-licenses/GPL-3'. diff -Nru osmo-hlr-0.1.0/debian/gbp.conf osmo-hlr-0.2.1/debian/gbp.conf --- osmo-hlr-0.1.0/debian/gbp.conf 1970-01-01 00:00:00.000000000 +0000 +++ osmo-hlr-0.2.1/debian/gbp.conf 2018-11-09 21:19:28.000000000 +0000 @@ -0,0 +1,2 @@ +[DEFAULT] +pristine-tar = True diff -Nru osmo-hlr-0.1.0/debian/osmo-hlr.cfg osmo-hlr-0.2.1/debian/osmo-hlr.cfg --- osmo-hlr-0.1.0/debian/osmo-hlr.cfg 1970-01-01 00:00:00.000000000 +0000 +++ osmo-hlr-0.2.1/debian/osmo-hlr.cfg 2018-11-09 21:19:28.000000000 +0000 @@ -0,0 +1,7 @@ +line vty + bind 127.0.0.1 +ctrl + bind 127.0.0.1 +hlr + gsup + bind ip 127.0.0.1 diff -Nru osmo-hlr-0.1.0/debian/osmo-hlr.dirs osmo-hlr-0.2.1/debian/osmo-hlr.dirs --- osmo-hlr-0.1.0/debian/osmo-hlr.dirs 1970-01-01 00:00:00.000000000 +0000 +++ osmo-hlr-0.2.1/debian/osmo-hlr.dirs 2018-11-09 21:19:28.000000000 +0000 @@ -0,0 +1 @@ +/var/lib/osmocom diff -Nru osmo-hlr-0.1.0/debian/osmo-hlr.install osmo-hlr-0.2.1/debian/osmo-hlr.install --- osmo-hlr-0.1.0/debian/osmo-hlr.install 2017-12-13 18:05:39.000000000 +0000 +++ osmo-hlr-0.2.1/debian/osmo-hlr.install 2018-11-09 21:19:28.000000000 +0000 @@ -3,3 +3,4 @@ #/usr/share/doc/osmo-hlr/hlr.sql #/usr/share/doc/osmo-hlr/examples/osmo-hlr.cfg #/usr/share/doc/osmo-hlr/examples/osmo-hlr.cfg /etc/osmocom/ +debian/osmo-hlr.cfg etc/osmocom/ diff -Nru osmo-hlr-0.1.0/debian/rules osmo-hlr-0.2.1/debian/rules --- osmo-hlr-0.1.0/debian/rules 2018-04-19 17:07:49.000000000 +0000 +++ osmo-hlr-0.2.1/debian/rules 2018-11-09 21:19:28.000000000 +0000 @@ -19,9 +19,21 @@ [ "${arch}" = "powerpc" ] || \ [ "${arch}" = "ppc64" ] || \ [ "${arch}" = "sparc64" ] || \ + [ "${arch}" = "mips64el" ] || \ + [ "${arch}" = "mipsel" ] || \ + [ "${arch}" = "alpha" ] || \ [ "${arch}" = "mips" ] ; then \ echo "Do not care of test result on this architecture" ;\ else \ echo "Do make tests on this architecture" ;\ dh_auto_test || (find . -name testsuite.log -exec cat {} \; ; false) \ fi + +override_dh_clean: + dh_clean + $(RM) .version tests/auc/auc_ts_55_205_test_sets.c + $(RM) tests/package.m4 + $(RM) tests/testsuite + +override_dh_installsystemd: + dh_installsystemd --no-enable --no-start diff -Nru osmo-hlr-0.1.0/debian/tests/can-show-help osmo-hlr-0.2.1/debian/tests/can-show-help --- osmo-hlr-0.1.0/debian/tests/can-show-help 1970-01-01 00:00:00.000000000 +0000 +++ osmo-hlr-0.2.1/debian/tests/can-show-help 2018-11-09 21:19:28.000000000 +0000 @@ -0,0 +1,6 @@ +#!/bin/sh + +set -e + +osmo-hlr -h +echo "run: OK" diff -Nru osmo-hlr-0.1.0/debian/tests/control osmo-hlr-0.2.1/debian/tests/control --- osmo-hlr-0.1.0/debian/tests/control 1970-01-01 00:00:00.000000000 +0000 +++ osmo-hlr-0.2.1/debian/tests/control 2018-11-09 21:19:28.000000000 +0000 @@ -0,0 +1,4 @@ +Tests: can-show-help +Depends: osmo-hlr + + diff -Nru osmo-hlr-0.1.0/doc/Makefile.am osmo-hlr-0.2.1/doc/Makefile.am --- osmo-hlr-0.1.0/doc/Makefile.am 1970-01-01 00:00:00.000000000 +0000 +++ osmo-hlr-0.2.1/doc/Makefile.am 2018-05-04 16:41:35.000000000 +0000 @@ -0,0 +1,22 @@ +CFG_FILES = find $(srcdir) -name '*.cfg*' | sed -e 's,^$(srcdir),,' + +dist-hook: + for f in $$($(CFG_FILES)); do \ + j="$(distdir)/$$f" && \ + mkdir -p "$$(dirname $$j)" && \ + $(INSTALL_DATA) $(srcdir)/$$f $$j; \ + done + +install-data-hook: + for f in $$($(CFG_FILES)); do \ + j="$(DESTDIR)$(docdir)/$$f" && \ + mkdir -p "$$(dirname $$j)" && \ + $(INSTALL_DATA) $(srcdir)/$$f $$j; \ + done + +uninstall-hook: + @$(PRE_UNINSTALL) + for f in $$($(CFG_FILES)); do \ + j="$(DESTDIR)$(docdir)/$$f" && \ + $(RM) $$j; \ + done diff -Nru osmo-hlr-0.1.0/.gitignore osmo-hlr-0.2.1/.gitignore --- osmo-hlr-0.1.0/.gitignore 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/.gitignore 2018-05-04 16:41:35.000000000 +0000 @@ -22,10 +22,15 @@ missing .deps -src/osmo-hlr src/db_test +src/db_bootstrap.h +src/osmo-hlr +src/osmo-hlr-db-tool +tests/atconfig tests/testsuite tests/auc/auc_3g_test tests/auc/auc_ts_55_205_test_sets.c tests/auc/auc_ts_55_205_test_sets +tests/auc/auc_test +tests/gsup_server/gsup_server_test diff -Nru osmo-hlr-0.1.0/Makefile.am osmo-hlr-0.2.1/Makefile.am --- osmo-hlr-0.1.0/Makefile.am 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/Makefile.am 2018-05-04 16:41:35.000000000 +0000 @@ -1,6 +1,7 @@ AUTOMAKE_OPTIONS = foreign dist-bzip2 SUBDIRS = \ + doc \ src \ sql \ tests \ diff -Nru osmo-hlr-0.1.0/src/auc.c osmo-hlr-0.2.1/src/auc.c --- osmo-hlr-0.1.0/src/auc.c 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/src/auc.c 2018-05-04 16:41:35.000000000 +0000 @@ -144,6 +144,7 @@ if (!aud2g) { /* use the 2G tokens from 3G keys */ + DBGP("vector [%u]: deriving 2G from 3G\n", i); DBGVB(kc); DBGVB(sres); DBGVV("0x%x", auth_types); @@ -151,7 +152,7 @@ } /* calculate 2G separately */ - DBGP("vector [%u]: deriving 2G from 3G\n", i); + DBGP("vector [%u]: calculating 2G separately\n", i); rc = osmo_auth_gen_vec(&vtmp, aud2g, rand); if (rc < 0) { diff -Nru osmo-hlr-0.1.0/src/ctrl.c osmo-hlr-0.2.1/src/ctrl.c --- osmo-hlr-0.1.0/src/ctrl.c 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/src/ctrl.c 2018-05-04 16:41:35.000000000 +0000 @@ -228,11 +228,16 @@ rc = db_get_auth_data(hlr->dbc, imsi, &aud2g, &aud3g, NULL); - if (rc == -ENOENT) { + switch (rc) { + case 0: + break; + case -ENOENT: + case -ENOKEY: /* No auth data found, tell the print*() functions about it. */ aud2g.algo = OSMO_AUTH_ALG_NONE; aud3g.algo = OSMO_AUTH_ALG_NONE; - } else if (rc) { + break; + default: cmd->reply = "Error retrieving authentication data."; return CTRL_CMD_ERROR; } @@ -258,11 +263,16 @@ rc = db_get_auth_data(hlr->dbc, subscr.imsi, &aud2g, &aud3g, NULL); - if (rc == -ENOENT) { + switch (rc) { + case 0: + break; + case -ENOENT: + case -ENOKEY: /* No auth data found, tell the print*() functions about it. */ aud2g.algo = OSMO_AUTH_ALG_NONE; aud3g.algo = OSMO_AUTH_ALG_NONE; - } else if (rc) { + break; + default: cmd->reply = "Error retrieving authentication data."; return CTRL_CMD_ERROR; } diff -Nru osmo-hlr-0.1.0/src/db_auc.c osmo-hlr-0.2.1/src/db_auc.c --- osmo-hlr-0.1.0/src/db_auc.c 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/src/db_auc.c 2018-05-04 16:41:35.000000000 +0000 @@ -74,7 +74,9 @@ } /* obtain the authentication data for a given imsi - * returns -1 in case of error, 0 for unknown IMSI, 1 for success */ + * returns 0 for success, negative value on error: + * -ENOENT if the IMSI is not known, -ENOKEY if the IMSI is known but has no auth data, + * -EIO on db failure */ int db_get_auth_data(struct db_context *dbc, const char *imsi, struct osmo_sub_auth_data *aud2g, struct osmo_sub_auth_data *aud3g, @@ -163,15 +165,16 @@ LOGAUC(imsi, LOGL_DEBUG, "No 3G Auth Data\n"); if (aud2g->type == 0 && aud3g->type == 0) - ret = -ENOENT; + ret = -ENOKEY; out: db_remove_reset(stmt); return ret; } -/* return -1 in case of error, 0 for unknown imsi, positive for number - * of vectors generated */ +/* return number of vectors generated, negative value on error: + * -ENOENT if the IMSI is not known, -ENOKEY if the IMSI is known but has no auth data, + * -EIO on db failure */ int db_get_auc(struct db_context *dbc, const char *imsi, unsigned int auc_3g_ind, struct osmo_auth_vector *vec, unsigned int num_vec, const uint8_t *rand_auts, diff -Nru osmo-hlr-0.1.0/src/db.c osmo-hlr-0.2.1/src/db.c --- osmo-hlr-0.1.0/src/db.c 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/src/db.c 2018-05-04 16:41:35.000000000 +0000 @@ -99,6 +99,8 @@ void db_remove_reset(sqlite3_stmt *stmt) { sqlite3_clear_bindings(stmt); + /* sqlite3_reset() just repeats an error code already evaluated during sqlite3_step(). */ + /* coverity[CHECKED_RETURN] */ sqlite3_reset(stmt); } @@ -209,7 +211,7 @@ return 0; } -struct db_context *db_open(void *ctx, const char *fname) +struct db_context *db_open(void *ctx, const char *fname, bool enable_sqlite_logging) { struct db_context *dbc = talloc_zero(ctx, struct db_context); unsigned int i; @@ -231,9 +233,11 @@ has_sqlite_config_sqllog = true; } - rc = sqlite3_config(SQLITE_CONFIG_LOG, sql3_error_log_cb, NULL); - if (rc != SQLITE_OK) - LOGP(DDB, LOGL_NOTICE, "Unable to set SQLite3 error log callback\n"); + if (enable_sqlite_logging) { + rc = sqlite3_config(SQLITE_CONFIG_LOG, sql3_error_log_cb, NULL); + if (rc != SQLITE_OK) + LOGP(DDB, LOGL_NOTICE, "Unable to set SQLite3 error log callback\n"); + } if (has_sqlite_config_sqllog) { rc = sqlite3_config(SQLITE_CONFIG_SQLLOG, sql3_sql_log_cb, NULL); diff -Nru osmo-hlr-0.1.0/src/db.h osmo-hlr-0.2.1/src/db.h --- osmo-hlr-0.1.0/src/db.h 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/src/db.h 2018-05-04 16:41:35.000000000 +0000 @@ -38,7 +38,7 @@ bool db_bind_int(sqlite3_stmt *stmt, const char *param_name, int nr); bool db_bind_int64(sqlite3_stmt *stmt, const char *param_name, int64_t nr); void db_close(struct db_context *dbc); -struct db_context *db_open(void *ctx, const char *fname); +struct db_context *db_open(void *ctx, const char *fname, bool enable_sqlite3_logging); #include diff -Nru osmo-hlr-0.1.0/src/db_test.c osmo-hlr-0.2.1/src/db_test.c --- osmo-hlr-0.1.0/src/db_test.c 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/src/db_test.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -#include - -#include -#include - -#include "db.h" -#include "hlr.h" -#include "rand.h" -#include "logging.h" - -static struct hlr *g_hlr; - -static int test(const char *imsi, struct db_context *dbc) -{ - struct osmo_auth_vector vec[3]; - int rc, i; - - /* initialize all vectors with a known token pattern */ - memset(vec, 0x55, sizeof(vec)); - for (i = 0; i < ARRAY_SIZE(vec); i++) - vec[i].res_len = 0; - - rc = db_get_auc(dbc, imsi, 0, vec, ARRAY_SIZE(vec), NULL, NULL); - if (rc <= 0) { - LOGP(DMAIN, LOGL_ERROR, "Cannot obtain auth tuples for '%s'\n", imsi); - return rc; - } - LOGP(DMAIN, LOGL_INFO, "Obtained %u tuples for subscriber IMSI %s\n", - rc, imsi); - - for (i = 0; i < rc; i++) { - struct osmo_auth_vector *v = vec + i; - LOGP(DMAIN, LOGL_DEBUG, "Tuple %u, auth_types=0x%x\n", i, v->auth_types); - LOGP(DMAIN, LOGL_DEBUG, "RAND=%s\n", osmo_hexdump_nospc(v->rand, sizeof(v->rand))); - LOGP(DMAIN, LOGL_DEBUG, "AUTN=%s\n", osmo_hexdump_nospc(v->autn, sizeof(v->autn))); - LOGP(DMAIN, LOGL_DEBUG, "CK=%s\n", osmo_hexdump_nospc(v->ck, sizeof(v->ck))); - LOGP(DMAIN, LOGL_DEBUG, "IK=%s\n", osmo_hexdump_nospc(v->ik, sizeof(v->ik))); - LOGP(DMAIN, LOGL_DEBUG, "RES=%s\n", osmo_hexdump_nospc(v->res, v->res_len)); - LOGP(DMAIN, LOGL_DEBUG, "Kc=%s\n", osmo_hexdump_nospc(v->kc, sizeof(v->kc))); - LOGP(DMAIN, LOGL_DEBUG, "SRES=%s\n", osmo_hexdump_nospc(v->sres, sizeof(v->sres))); - } - - return rc; -} - -int main(int argc, char **argv) -{ - int rc; - - g_hlr = talloc_zero(NULL, struct hlr); - - rc = osmo_init_logging(&hlr_log_info); - if (rc < 0) { - fprintf(stderr, "Error initializing logging\n"); - exit(1); - } - LOGP(DMAIN, LOGL_NOTICE, "hlr starting\n"); - - rc = rand_init(); - if (rc < 0) { - LOGP(DMAIN, LOGL_ERROR, "Error initializing random source\n"); - exit(1); - } - - g_hlr->dbc = db_open(NULL, "hlr.db"); - if (!g_hlr->dbc) { - LOGP(DMAIN, LOGL_ERROR, "Error opening database\n"); - exit(1); - } - - /* non-existing subscriber */ - rc = test("901990123456789", g_hlr->dbc); - /* 2G only AUC data (COMP128v1 / MILENAGE) */ - rc = test("901990000000001", g_hlr->dbc); - /* 2G + 3G AUC data (COMP128v1 / MILENAGE) */ - rc = test("901990000000002", g_hlr->dbc); - /* 3G AUC data (MILENAGE) */ - rc = test("901990000000003", g_hlr->dbc); - - LOGP(DMAIN, LOGL_NOTICE, "Exiting\n"); - - db_close(g_hlr->dbc); - - log_fini(); - - exit(0); -} diff -Nru osmo-hlr-0.1.0/src/gsup_send.c osmo-hlr-0.2.1/src/gsup_send.c --- osmo-hlr-0.1.0/src/gsup_send.c 1970-01-01 00:00:00.000000000 +0000 +++ osmo-hlr-0.2.1/src/gsup_send.c 2018-05-04 16:41:35.000000000 +0000 @@ -0,0 +1,45 @@ +/* (C) 2018 by sysmocom - s.f.m.c. GmbH + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +/* This is kept separate to be able to override the actual sending functions from unit tests. */ + +#include + +#include "gsup_server.h" +#include "gsup_router.h" + +#include + +/* Send a msgb to a given address using routing */ +int osmo_gsup_addr_send(struct osmo_gsup_server *gs, + const uint8_t *addr, size_t addrlen, + struct msgb *msg) +{ + struct osmo_gsup_conn *conn; + + conn = gsup_route_find(gs, addr, addrlen); + if (!conn) { + DEBUGP(DLGSUP, "Cannot find route for addr %s\n", addr); + msgb_free(msg); + return -ENODEV; + } + + return osmo_gsup_conn_send(conn, msg); +} + diff -Nru osmo-hlr-0.1.0/src/gsup_server.c osmo-hlr-0.2.1/src/gsup_server.c --- osmo-hlr-0.1.0/src/gsup_server.c 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/src/gsup_server.c 2018-05-04 16:41:35.000000000 +0000 @@ -24,6 +24,7 @@ #include #include #include +#include #include "gsup_server.h" #include "gsup_router.h" @@ -333,3 +334,26 @@ } talloc_free(gsups); } + +/* Set GSUP message's pdp_infos[0] to a wildcard APN. + * Use the provided apn_buf to store the produced APN data. This must remain valid until + * osmo_gsup_encode() is done. Return 0 if an entry was added, -ENOMEM if the provided buffer is too + * small. */ +int osmo_gsup_configure_wildcard_apn(struct osmo_gsup_message *gsup, + uint8_t *apn_buf, size_t apn_buf_size) +{ + int l; + + l = osmo_apn_from_str(apn_buf, apn_buf_size, "*"); + if (l <= 0) + return -ENOMEM; + + gsup->pdp_infos[0].apn_enc = apn_buf; + gsup->pdp_infos[0].apn_enc_len = l; + gsup->pdp_infos[0].have_info = 1; + gsup->num_pdp_infos = 1; + /* FIXME: use real value: */ + gsup->pdp_infos[0].context_id = 1; + + return 0; +} diff -Nru osmo-hlr-0.1.0/src/gsup_server.h osmo-hlr-0.2.1/src/gsup_server.h --- osmo-hlr-0.1.0/src/gsup_server.h 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/src/gsup_server.h 2018-05-04 16:41:35.000000000 +0000 @@ -4,6 +4,7 @@ #include #include #include +#include struct osmo_gsup_conn; @@ -33,6 +34,10 @@ struct tlv_parsed ccm; unsigned int auc_3g_ind; /*!< IND index used for UMTS AKA SQN */ + + /* Set when Location Update is received: */ + bool supports_cs; /* client supports OSMO_GSUP_CN_DOMAIN_CS */ + bool supports_ps; /* client supports OSMO_GSUP_CN_DOMAIN_PS */ }; @@ -48,3 +53,5 @@ void osmo_gsup_server_destroy(struct osmo_gsup_server *gsups); +int osmo_gsup_configure_wildcard_apn(struct osmo_gsup_message *gsup, + uint8_t *apn_buf, size_t apn_buf_size); diff -Nru osmo-hlr-0.1.0/src/hlr.c osmo-hlr-0.2.1/src/hlr.c --- osmo-hlr-0.1.0/src/hlr.c 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/src/hlr.c 2018-05-04 16:41:35.000000000 +0000 @@ -26,13 +26,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include "db.h" #include "hlr.h" @@ -46,6 +46,93 @@ static struct hlr *g_hlr; +/* Trigger 'Insert Subscriber Data' messages to all connected GSUP clients. + * + * FIXME: In order to support large-scale networks this function should skip + * VLRs/SGSNs which do not currently serve the subscriber. + * + * \param[in] subscr A subscriber we have new data to send for. + */ +void +osmo_hlr_subscriber_update_notify(struct hlr_subscriber *subscr) +{ + struct osmo_gsup_conn *co; + + if (g_hlr->gs == NULL) + return; + + llist_for_each_entry(co, &g_hlr->gs->clients, list) { + struct osmo_gsup_message gsup = { + .message_type = OSMO_GSUP_MSGT_INSERT_DATA_REQUEST + }; + uint8_t *peer; + int peer_len; + uint8_t msisdn_enc[43]; /* TODO use constant; TS 24.008 10.5.4.7 */ + uint8_t apn[APN_MAXLEN]; + int len; + struct msgb *msg_out; + + peer_len = osmo_gsup_conn_ccm_get(co, &peer, IPAC_IDTAG_SERNR); + if (peer_len < 0) { + LOGP(DMAIN, LOGL_ERROR, + "IMSI='%s': Cannot notify GSUP client, cannot get peer name " + "for %s:%u\n", subscr->imsi, + co && co->conn && co->conn->server? co->conn->server->addr : "unset", + co && co->conn && co->conn->server? co->conn->server->port : 0); + continue; + } + + osmo_strlcpy(gsup.imsi, subscr->imsi, GSM23003_IMSI_MAX_DIGITS + 1); + + len = gsm48_encode_bcd_number(msisdn_enc, sizeof(msisdn_enc), 0, subscr->msisdn); + if (len < 1) { + LOGP(DMAIN, LOGL_ERROR, "%s: Error: cannot encode MSISDN '%s'\n", + subscr->imsi, subscr->msisdn); + continue; + } + gsup.msisdn_enc = msisdn_enc; + gsup.msisdn_enc_len = len; + + if (co->supports_ps) { + gsup.cn_domain = OSMO_GSUP_CN_DOMAIN_PS; + + /* FIXME: PDP infos - use more fine-grained access control + instead of wildcard APN */ + if (osmo_gsup_configure_wildcard_apn(&gsup, apn, sizeof(apn))) { + LOGP(DMAIN, LOGL_ERROR, "%s: Error: cannot encode wildcard APN\n", + subscr->imsi); + continue; + } + } else if (co->supports_cs) { + gsup.cn_domain = OSMO_GSUP_CN_DOMAIN_CS; + } else { + /* We have not yet received a location update from this subscriber .*/ + continue; + } + + /* Send ISD to MSC/SGSN */ + msg_out = msgb_alloc_headroom(1024+16, 16, "GSUP ISD UPDATE"); + if (msg_out == NULL) { + LOGP(DMAIN, LOGL_ERROR, + "IMSI='%s': Cannot notify GSUP client; could not allocate msg buffer " + "for %s:%u\n", subscr->imsi, + co && co->conn && co->conn->server? co->conn->server->addr : "unset", + co && co->conn && co->conn->server? co->conn->server->port : 0); + continue; + } + + osmo_gsup_encode(msg_out, &gsup); + if (osmo_gsup_addr_send(g_hlr->gs, peer, peer_len, msg_out) < 0) { + LOGP(DMAIN, LOGL_ERROR, + "IMSI='%s': Cannot notify GSUP client; send operation failed " + "for %s:%u\n", subscr->imsi, + co && co->conn && co->conn->server? co->conn->server->addr : "unset", + co && co->conn && co->conn->server? co->conn->server->port : 0); + continue; + } + } +} + /*********************************************************************** * Send Auth Info handling ***********************************************************************/ @@ -67,12 +154,27 @@ gsup_out.auth_vectors, ARRAY_SIZE(gsup_out.auth_vectors), gsup->rand, gsup->auts); - if (rc < 0) { + if (rc <= 0) { gsup_out.message_type = OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR; - gsup_out.cause = GMM_CAUSE_NET_FAIL; - } else if (rc == 0) { - gsup_out.message_type = OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR; - gsup_out.cause = GMM_CAUSE_IMSI_UNKNOWN; + switch (rc) { + case 0: + /* 0 means "0 tuples generated", which shouldn't happen. + * Treat the same as "no auth data". */ + case -ENOKEY: + LOGP(DAUC, LOGL_NOTICE, "%s: IMSI known, but has no auth data;" + " Returning slightly inaccurate cause 'IMSI Unknown' via GSUP\n", + gsup->imsi); + gsup_out.cause = GMM_CAUSE_IMSI_UNKNOWN; + break; + case -ENOENT: + LOGP(DAUC, LOGL_NOTICE, "%s: IMSI not known\n", gsup->imsi); + gsup_out.cause = GMM_CAUSE_IMSI_UNKNOWN; + break; + default: + LOGP(DAUC, LOGL_ERROR, "%s: failure to look up IMSI in db\n", gsup->imsi); + gsup_out.cause = GMM_CAUSE_NET_FAIL; + break; + } } else { gsup_out.message_type = OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT; gsup_out.num_auth_vectors = rc; @@ -155,8 +257,19 @@ lu_op_statechg(luop, LU_S_LU_RECEIVED); - if (gsup->cn_domain == OSMO_GSUP_CN_DOMAIN_PS) + if (gsup->cn_domain == OSMO_GSUP_CN_DOMAIN_CS) + conn->supports_cs = true; + if (gsup->cn_domain == OSMO_GSUP_CN_DOMAIN_PS) { + conn->supports_ps = true; luop->is_ps = true; + } else { + /* The client didn't send a CN_DOMAIN IE; assume packet-switched in + * accordance with the GSUP spec in osmo-hlr's user manual (section + * 11.6.15 "CN Domain" says "if no CN Domain IE is present within + * a request, the PS Domain is assumed." */ + conn->supports_ps = true; + luop->is_ps = true; + } llist_add(&luop->list, &g_lu_ops); /* Roughly follwing "Process Update_Location_HLR" of TS 09.02 */ @@ -164,7 +277,7 @@ /* check if subscriber is known at all */ if (!lu_op_fill_subscr(luop, g_hlr->dbc, gsup->imsi)) { /* Send Error back: Subscriber Unknown in HLR */ - strcpy(luop->subscr.imsi, gsup->imsi); + osmo_strlcpy(luop->subscr.imsi, gsup->imsi, sizeof(luop->subscr.imsi)); lu_op_tx_error(luop, GMM_CAUSE_IMSI_UNKNOWN); return 0; } @@ -223,9 +336,9 @@ /* Perform the actual update of the DB */ rc = db_subscr_purge(g_hlr->dbc, gsup->imsi, true, is_ps); - if (rc == 1) + if (rc == 0) gsup_reply.message_type = OSMO_GSUP_MSGT_PURGE_MS_RESULT; - else if (rc == 0) { + else if (rc == -ENOENT) { gsup_reply.message_type = OSMO_GSUP_MSGT_PURGE_MS_ERROR; gsup_reply.cause = GMM_CAUSE_IMSI_UNKNOWN; } else { @@ -424,10 +537,11 @@ hlr_ctx = talloc_named_const(NULL, 1, "OsmoHLR"); msgb_talloc_ctx_init(hlr_ctx, 0); + vty_info.tall_ctx = hlr_ctx; g_hlr = talloc_zero(hlr_ctx, struct hlr); - rc = osmo_init_logging(&hlr_log_info); + rc = osmo_init_logging2(hlr_ctx, &hlr_log_info); if (rc < 0) { fprintf(stderr, "Error initializing logging\n"); exit(1); @@ -460,7 +574,7 @@ exit(1); } - g_hlr->dbc = db_open(hlr_ctx, cmdline_opts.db_file); + g_hlr->dbc = db_open(hlr_ctx, cmdline_opts.db_file, true); if (!g_hlr->dbc) { LOGP(DMAIN, LOGL_FATAL, "Error opening database\n"); exit(1); diff -Nru osmo-hlr-0.1.0/src/hlr_db_tool.c osmo-hlr-0.2.1/src/hlr_db_tool.c --- osmo-hlr-0.1.0/src/hlr_db_tool.c 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/src/hlr_db_tool.c 2018-05-04 16:41:35.000000000 +0000 @@ -51,8 +51,7 @@ static void print_help() { printf("\n"); - printf("Usage: osmo-hlr-db-tool [-l ] import-nitb-db ]\n"); - printf("Call without arguments to create a new empty ./hlr.db.\n"); + printf("Usage: osmo-hlr-db-tool [-l ] [create|import-nitb-db ]\n"); printf(" -l --database db-name The OsmoHLR database to use, default '%s'.\n", cmdline_opts.db_file); printf(" -h --help This text.\n"); @@ -62,7 +61,12 @@ printf(" -e --log-level number Set a global loglevel.\n"); printf(" -V --version Print the version of OsmoHLR-db-tool.\n"); printf("\n"); - printf(" import-nitb-db db Add OsmoNITB db's subscribers to OsmoHLR db.\n"); + printf("Commands:\n"); + printf("\n"); + printf(" create Create an empty OsmoHLR database.\n"); + printf(" (All commands imply this if none exists yet.)\n"); + printf("\n"); + printf(" import-nitb-db Add OsmoNITB db's subscribers to OsmoHLR db.\n"); printf(" Be aware that the import is lossy, only the\n"); printf(" IMSI, MSISDN, nam_cs/ps and 2G auth data are set.\n"); } @@ -139,9 +143,11 @@ } cmd = argv[optind++]; - printf("command '%s', %d extra arguments\n", cmd, argc - optind); - if (!strcmp(cmd, "import-nitb-db")) { + if (!strcmp(cmd, "create")) { + /* Nothing to do, just run the main program to open the database without running any + * action, which will bootstrap all tables. */ + } else if (!strcmp(cmd, "import-nitb-db")) { if (argc - optind < 1) { fprintf(stderr, "You must specify an input db file\n"); print_help(); @@ -153,6 +159,12 @@ print_help(); exit(EXIT_FAILURE); } + + if (argc - optind > 0) { + fprintf(stderr, "Too many arguments: '%s'\n", argv[optind]); + print_help(); + exit(EXIT_FAILURE); + } } static void signal_hdlr(int signal) @@ -284,12 +296,12 @@ snprintf(imsi_str, sizeof(imsi_str), "%"PRId64, imsi); rc = db_subscr_create(dbc, imsi_str); - if (rc) { + if (rc < 0) { LOGP(DDB, LOGL_ERROR, "OsmoNITB DB import to %s: failed to create IMSI %s: %d: %s\n", dbc->fname, imsi_str, rc, - strerror(rc)); + strerror(-rc)); /* on error, still attempt to continue */ } @@ -303,13 +315,13 @@ /* find the just created id */ rc = db_subscr_get_by_imsi(dbc, imsi_str, &subscr); - if (rc) { + if (rc < 0) { LOGP(DDB, LOGL_ERROR, "OsmoNITB DB import to %s: created IMSI %s," " but failed to get new subscriber id: %d: %s\n", dbc->fname, imsi_str, rc, - strerror(rc)); + strerror(-rc)); return; } @@ -374,7 +386,7 @@ OSMO_ASSERT(g_hlr_db_tool_ctx); talloc_set_name_const(g_hlr_db_tool_ctx, "OsmoHLR-db-tool"); - rc = osmo_init_logging(&hlr_log_info); + rc = osmo_init_logging2(g_hlr_db_tool_ctx, &hlr_log_info); if (rc < 0) { fprintf(stderr, "Error initializing logging\n"); exit(EXIT_FAILURE); @@ -387,7 +399,8 @@ goto too_many_actions; main_action = import_nitb_db; } - /* Future: add more main_actions, besides --import-nitb-db, here. */ + /* Future: add more main_actions, besides import-nitb-db, here. + * For command 'create', no action is required. */ /* Just in case any db actions need randomness */ rc = rand_init(); @@ -396,7 +409,7 @@ exit(EXIT_FAILURE); } - g_hlr_db_tool_ctx->dbc = db_open(g_hlr_db_tool_ctx, cmdline_opts.db_file); + g_hlr_db_tool_ctx->dbc = db_open(g_hlr_db_tool_ctx, cmdline_opts.db_file, true); if (!g_hlr_db_tool_ctx->dbc) { LOGP(DMAIN, LOGL_FATAL, "Error opening database\n"); exit(EXIT_FAILURE); diff -Nru osmo-hlr-0.1.0/src/hlr.h osmo-hlr-0.2.1/src/hlr.h --- osmo-hlr-0.1.0/src/hlr.h 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/src/hlr.h 2018-05-04 16:41:35.000000000 +0000 @@ -38,3 +38,7 @@ /* Local bind addr */ char *gsup_bind_addr; }; + +struct hlr_subscriber; + +void osmo_hlr_subscriber_update_notify(struct hlr_subscriber *subscr); diff -Nru osmo-hlr-0.1.0/src/hlr_vty.c osmo-hlr-0.2.1/src/hlr_vty.c --- osmo-hlr-0.1.0/src/hlr_vty.c 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/src/hlr_vty.c 2018-05-04 16:41:35.000000000 +0000 @@ -24,6 +24,7 @@ #include #include #include +#include #include "hlr_vty.h" #include "hlr_vty_subscr.h" @@ -126,14 +127,13 @@ g_hlr = hlr; logging_vty_add_cmds(cat); + osmo_talloc_vty_add_cmds(); install_element(CONFIG_NODE, &cfg_hlr_cmd); install_node(&hlr_node, config_write_hlr); - install_default(HLR_NODE); install_element(HLR_NODE, &cfg_gsup_cmd); install_node(&gsup_node, config_write_hlr_gsup); - install_default(GSUP_NODE); install_element(GSUP_NODE, &cfg_hlr_gsup_bind_ip_cmd); diff -Nru osmo-hlr-0.1.0/src/hlr_vty_subscr.c osmo-hlr-0.2.1/src/hlr_vty_subscr.c --- osmo-hlr-0.1.0/src/hlr_vty_subscr.c 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/src/hlr_vty_subscr.c 2018-05-04 16:41:35.000000000 +0000 @@ -72,14 +72,17 @@ OSMO_ASSERT(g_hlr); rc = db_get_auth_data(g_hlr->dbc, subscr->imsi, &aud2g, &aud3g, NULL); - if (rc) { - if (rc == -ENOENT) { - aud2g.algo = OSMO_AUTH_ALG_NONE; - aud3g.algo = OSMO_AUTH_ALG_NONE; - } else { - vty_out(vty, "%% Error retrieving data from database (%d)%s", rc, VTY_NEWLINE); - return; - } + switch (rc) { + case 0: + break; + case -ENOENT: + case -ENOKEY: + aud2g.algo = OSMO_AUTH_ALG_NONE; + aud3g.algo = OSMO_AUTH_ALG_NONE; + break; + default: + vty_out(vty, "%% Error retrieving data from database (%d)%s", rc, VTY_NEWLINE); + return; } if (aud2g.type != OSMO_AUTH_TYPE_NONE && aud2g.type != OSMO_AUTH_TYPE_GSM) { @@ -254,6 +257,10 @@ vty_out(vty, "%% Updated subscriber IMSI='%s' to MSISDN='%s'%s", subscr.imsi, msisdn, VTY_NEWLINE); + + if (db_subscr_get_by_msisdn(g_hlr->dbc, msisdn, &subscr) == 0) + osmo_hlr_subscriber_update_notify(&subscr); + return CMD_SUCCESS; } @@ -331,7 +338,7 @@ rc = db_subscr_update_aud_by_id(g_hlr->dbc, subscr.id, &aud); - if (rc) { + if (rc && rc != -ENOENT) { vty_out(vty, "%% Error: cannot disable 2G auth data for IMSI='%s'%s", subscr.imsi, VTY_NEWLINE); return CMD_WARNING; @@ -402,7 +409,7 @@ rc = db_subscr_update_aud_by_id(g_hlr->dbc, subscr.id, &aud); - if (rc) { + if (rc && rc != -ENOENT) { vty_out(vty, "%% Error: cannot disable 3G auth data for IMSI='%s'%s", subscr.imsi, VTY_NEWLINE); return CMD_WARNING; diff -Nru osmo-hlr-0.1.0/src/luop.c osmo-hlr-0.2.1/src/luop.c --- osmo-hlr-0.1.0/src/luop.c 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/src/luop.c 2018-05-04 16:41:35.000000000 +0000 @@ -108,8 +108,7 @@ luop = talloc_zero(srv, struct lu_operation); OSMO_ASSERT(luop); luop->gsup_server = srv; - luop->timer.cb = lu_op_timer_cb; - luop->timer.data = luop; + osmo_timer_setup(&luop->timer, lu_op_timer_cb, luop); return luop; } @@ -119,6 +118,10 @@ /* Only attempt to remove when it was ever added to a list. */ if (luop->list.next) llist_del(&luop->list); + + /* Delete timer just in case it is still pending. */ + osmo_timer_del(&luop->timer); + talloc_free(luop); } @@ -162,23 +165,6 @@ luop->state = new_state; } -/* Send a msgb to a given address using routing */ -int osmo_gsup_addr_send(struct osmo_gsup_server *gs, - const uint8_t *addr, size_t addrlen, - struct msgb *msg) -{ - struct osmo_gsup_conn *conn; - - conn = gsup_route_find(gs, addr, addrlen); - if (!conn) { - DEBUGP(DMAIN, "Cannot find route for addr %s\n", addr); - msgb_free(msg); - return -ENODEV; - } - - return osmo_gsup_conn_send(conn, msg); -} - /*! Transmit UPD_LOC_ERROR and destroy lu_operation */ void lu_op_tx_error(struct lu_operation *luop, enum gsm48_gmm_cause cause) { @@ -230,8 +216,8 @@ void lu_op_tx_insert_subscr_data(struct lu_operation *luop) { struct osmo_gsup_message gsup; - uint8_t apn[APN_MAXLEN]; uint8_t msisdn_enc[43]; /* TODO use constant; TS 24.008 10.5.4.7 */ + uint8_t apn[APN_MAXLEN]; int l; OSMO_ASSERT(luop->state == LU_S_LU_RECEIVED || @@ -251,20 +237,16 @@ gsup.msisdn_enc = msisdn_enc; gsup.msisdn_enc_len = l; - /* FIXME: deal with encoding the following data */ - gsup.hlr_enc; + #pragma message "FIXME: deal with encoding the following data: gsup.hlr_enc" if (luop->is_ps) { /* FIXME: PDP infos - use more fine-grained access control instead of wildcard APN */ - l = osmo_apn_from_str(apn, sizeof(apn), "*"); - if (l > 0) { - gsup.pdp_infos[0].apn_enc = apn; - gsup.pdp_infos[0].apn_enc_len = l; - gsup.pdp_infos[0].have_info = 1; - gsup.num_pdp_infos = 1; - /* FIXME: use real value: */ - gsup.pdp_infos[0].context_id = 1; + if (osmo_gsup_configure_wildcard_apn(&gsup, apn, sizeof(apn))) { + LOGP(DMAIN, LOGL_ERROR, "%s: Error: cannot encode wildcard APN\n", + luop->subscr.imsi); + lu_op_tx_error(luop, GMM_CAUSE_PROTO_ERR_UNSPEC); + return; } } diff -Nru osmo-hlr-0.1.0/src/luop.h osmo-hlr-0.2.1/src/luop.h --- osmo-hlr-0.1.0/src/luop.h 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/src/luop.h 2018-05-04 16:41:35.000000000 +0000 @@ -28,6 +28,7 @@ #include #include "db.h" +#include "gsup_server.h" #define CANCEL_TIMEOUT_SECS 30 #define ISD_TIMEOUT_SECS 30 diff -Nru osmo-hlr-0.1.0/src/Makefile.am osmo-hlr-0.2.1/src/Makefile.am --- osmo-hlr-0.1.0/src/Makefile.am 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/src/Makefile.am 2018-05-04 16:41:35.000000000 +0000 @@ -38,10 +38,6 @@ osmo-hlr-db-tool \ $(NULL) -noinst_PROGRAMS = \ - db_test \ - $(NULL) - osmo_hlr_SOURCES = \ auc.c \ ctrl.c \ @@ -56,6 +52,7 @@ rand_urandom.c \ hlr_vty.c \ hlr_vty_subscr.c \ + gsup_send.c \ $(NULL) osmo_hlr_LDADD = \ diff -Nru osmo-hlr-0.1.0/tests/auc/auc_test.c osmo-hlr-0.2.1/tests/auc/auc_test.c --- osmo-hlr-0.1.0/tests/auc/auc_test.c 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/tests/auc/auc_test.c 2018-05-04 16:41:35.000000000 +0000 @@ -610,7 +610,9 @@ handle_options(argc, argv); - osmo_init_logging(&hlr_log_info); + void *tall_ctx = talloc_named_const(NULL, 1, "auc_test"); + + osmo_init_logging2(tall_ctx, &hlr_log_info); log_set_print_filename(osmo_stderr_target, cmdline_opts.verbose); log_set_print_timestamp(osmo_stderr_target, 0); log_set_use_color(osmo_stderr_target, 0); diff -Nru osmo-hlr-0.1.0/tests/auc/auc_test.err osmo-hlr-0.2.1/tests/auc/auc_test.err --- osmo-hlr-0.1.0/tests/auc/auc_test.err 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/tests/auc/auc_test.err 2018-05-04 16:41:35.000000000 +0000 @@ -35,7 +35,7 @@ DAUC vector [0]: ik = 27497388b6cb044648f396aa155b95ef DAUC vector [0]: res = e229c19e791f2e410000000000000000 DAUC vector [0]: res_len = 8 -DAUC vector [0]: deriving 2G from 3G +DAUC vector [0]: calculating 2G separately DAUC vector [0]: kc = 241a5b16aeb8e400 DAUC vector [0]: sres = 429d5b27 DAUC vector [0]: auth_types = 0x3 @@ -55,7 +55,7 @@ DAUC vector [0]: ik = 27497388b6cb044648f396aa155b95ef DAUC vector [0]: res = e229c19e791f2e410000000000000000 DAUC vector [0]: res_len = 8 -DAUC vector [0]: deriving 2G from 3G +DAUC vector [0]: calculating 2G separately DAUC vector [0]: kc = 241a5b16aeb8e400 DAUC vector [0]: sres = 429d5b27 DAUC vector [0]: auth_types = 0x3 @@ -78,6 +78,7 @@ DAUC vector [0]: ik = 27497388b6cb044648f396aa155b95ef DAUC vector [0]: res = e229c19e791f2e410000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = 059a4f668f6fbe39 DAUC vector [0]: sres = 9b36efdf DAUC vector [0]: auth_types = 0x3 @@ -96,6 +97,7 @@ DAUC vector [0]: ik = 27497388b6cb044648f396aa155b95ef DAUC vector [0]: res = e229c19e791f2e410000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = 059a4f668f6fbe39 DAUC vector [0]: sres = 9b36efdf DAUC vector [0]: auth_types = 0x3 @@ -117,6 +119,7 @@ DAUC vector [0]: ik = f19c20ca863137f8892326d959ec5e01 DAUC vector [0]: res = 9af5a557902d2db80000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = 7526fc13c5976685 DAUC vector [0]: sres = 0ad888ef DAUC vector [0]: auth_types = 0x3 @@ -137,6 +140,7 @@ DAUC vector [0]: ik = f19c20ca863137f8892326d959ec5e01 DAUC vector [0]: res = 9af5a557902d2db80000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = 7526fc13c5976685 DAUC vector [0]: sres = 0ad888ef DAUC vector [0]: auth_types = 0x3 @@ -147,6 +151,7 @@ DAUC vector [1]: ik = 79f21ed53bcb47787de57d136ff803a5 DAUC vector [1]: res = 43023475cb29292c0000000000000000 DAUC vector [1]: res_len = 8 +DAUC vector [1]: deriving 2G from 3G DAUC vector [1]: kc = aef73dd515e86c15 DAUC vector [1]: sres = 882b1d59 DAUC vector [1]: auth_types = 0x3 @@ -157,6 +162,7 @@ DAUC vector [2]: ik = 648dab72016181406243420649e63dc9 DAUC vector [2]: res = 010cab11cc63a6e40000000000000000 DAUC vector [2]: res_len = 8 +DAUC vector [2]: deriving 2G from 3G DAUC vector [2]: kc = f0eaf8cb19e0758d DAUC vector [2]: sres = cd6f0df5 DAUC vector [2]: auth_types = 0x3 @@ -179,6 +185,7 @@ DAUC vector [0]: ik = f19c20ca863137f8892326d959ec5e01 DAUC vector [0]: res = 9af5a557902d2db80000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = 7526fc13c5976685 DAUC vector [0]: sres = 0ad888ef DAUC vector [0]: auth_types = 0x3 @@ -189,6 +196,7 @@ DAUC vector [1]: ik = 79f21ed53bcb47787de57d136ff803a5 DAUC vector [1]: res = 43023475cb29292c0000000000000000 DAUC vector [1]: res_len = 8 +DAUC vector [1]: deriving 2G from 3G DAUC vector [1]: kc = aef73dd515e86c15 DAUC vector [1]: sres = 882b1d59 DAUC vector [1]: auth_types = 0x3 @@ -199,6 +207,7 @@ DAUC vector [2]: ik = 648dab72016181406243420649e63dc9 DAUC vector [2]: res = 010cab11cc63a6e40000000000000000 DAUC vector [2]: res_len = 8 +DAUC vector [2]: deriving 2G from 3G DAUC vector [2]: kc = f0eaf8cb19e0758d DAUC vector [2]: sres = cd6f0df5 DAUC vector [2]: auth_types = 0x3 diff -Nru osmo-hlr-0.1.0/tests/auc/auc_ts_55_205_test_sets.err osmo-hlr-0.2.1/tests/auc/auc_ts_55_205_test_sets.err --- osmo-hlr-0.1.0/tests/auc/auc_ts_55_205_test_sets.err 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/tests/auc/auc_ts_55_205_test_sets.err 2018-05-04 16:41:35.000000000 +0000 @@ -12,6 +12,7 @@ DAUC vector [0]: ik = f769bcd751044604127672711c6d3441 DAUC vector [0]: res = a54211d5e3ba50bf0000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = eae4be823af9a08b DAUC vector [0]: sres = 46f8416a DAUC vector [0]: auth_types = 0x3 @@ -34,6 +35,7 @@ DAUC vector [0]: ik = 59a92d3b476a0443487055cf88b2307b DAUC vector [0]: res = 8011c48c0c214ed20000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = aa01739b8caa976d DAUC vector [0]: sres = 8c308a5e DAUC vector [0]: auth_types = 0x3 @@ -56,6 +58,7 @@ DAUC vector [0]: ik = 0c4524adeac041c4dd830d20854fc46b DAUC vector [0]: res = f365cd683cd92e960000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = 9a8ec95f408cc507 DAUC vector [0]: sres = cfbce3fe DAUC vector [0]: auth_types = 0x3 @@ -78,6 +81,7 @@ DAUC vector [0]: ik = 1c42e960d89b8fa99f2744e0708ccb53 DAUC vector [0]: res = 5860fc1bce351e7e0000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = cdc1dc0841b81a22 DAUC vector [0]: sres = 9655e265 DAUC vector [0]: auth_types = 0x3 @@ -100,6 +104,7 @@ DAUC vector [0]: ik = a7466cc1e6b2a1337d49d3b66e95d7b4 DAUC vector [0]: res = 16c8233f05a0ac280000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = df75bc5ea899879f DAUC vector [0]: sres = 13688f17 DAUC vector [0]: auth_types = 0x3 @@ -122,6 +127,7 @@ DAUC vector [0]: ik = 88ab80a415f15c73711254a1d388f696 DAUC vector [0]: res = 8c25a16cd918a1df0000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = 84b417ae3aeab4f3 DAUC vector [0]: sres = 553d00b3 DAUC vector [0]: auth_types = 0x3 @@ -144,6 +150,7 @@ DAUC vector [0]: ik = f9ec0865eb32f22369cade40c59c3a44 DAUC vector [0]: res = a63241e1ffc3e5ab0000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = 3b4e244cdc60ce03 DAUC vector [0]: sres = 59f1a44a DAUC vector [0]: auth_types = 0x3 @@ -166,6 +173,7 @@ DAUC vector [0]: ik = 90527ebaa5588968db41727325a04d9e DAUC vector [0]: res = 4a90b2171ac83a760000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = 8d4ec01de597acfe DAUC vector [0]: sres = 50588861 DAUC vector [0]: auth_types = 0x3 @@ -188,6 +196,7 @@ DAUC vector [0]: ik = ed0318ca5deb9206272f6e8fa64ba411 DAUC vector [0]: res = 4bc2212d8624910a0000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = d8debc4ffbcd60aa DAUC vector [0]: sres = cde6b027 DAUC vector [0]: auth_types = 0x3 @@ -210,6 +219,7 @@ DAUC vector [0]: ik = 74f24e8c26df58e1b38d7dcd4f1b7fbd DAUC vector [0]: res = 6fc30fee6d1235230000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = f0eaa50a1edcebb7 DAUC vector [0]: sres = 02d13acd DAUC vector [0]: auth_types = 0x3 @@ -232,6 +242,7 @@ DAUC vector [0]: ik = c251df0d888dd9329bcf46655b226e40 DAUC vector [0]: res = aefa357beac2a87a0000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = 82dbab7f83f063da DAUC vector [0]: sres = 44389d01 DAUC vector [0]: auth_types = 0x3 @@ -254,6 +265,7 @@ DAUC vector [0]: ik = 0c9fb81613884c2535dd0eabf3b440d8 DAUC vector [0]: res = 98dbbd099b3b408d0000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = 3c66cb98cab2d33d DAUC vector [0]: sres = 03e0fd84 DAUC vector [0]: auth_types = 0x3 @@ -276,6 +288,7 @@ DAUC vector [0]: ik = 7f4d6ae7440e18789a8b75ad3f42f03a DAUC vector [0]: res = af4a411e1139f2c20000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = 9612b5d88a4130bb DAUC vector [0]: sres = be73b3dc DAUC vector [0]: auth_types = 0x3 @@ -298,6 +311,7 @@ DAUC vector [0]: ik = abcbae8fd46115e9961a55d0da5f2078 DAUC vector [0]: res = 7bffa5c2f41fbc050000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = 75a150df3c6aed08 DAUC vector [0]: sres = 8fe019c7 DAUC vector [0]: auth_types = 0x3 @@ -320,6 +334,7 @@ DAUC vector [0]: ik = 0b3f8d024fe6bfafaa982b8f82e319c2 DAUC vector [0]: res = 7e3f44c7591f6f450000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = b7f92e426a36fec5 DAUC vector [0]: sres = 27202b82 DAUC vector [0]: auth_types = 0x3 @@ -342,6 +357,7 @@ DAUC vector [0]: ik = d61c853c280dd9c46f297baec386de17 DAUC vector [0]: res = 70f6bdb9ad21525f0000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = 88d9de10a22004c5 DAUC vector [0]: sres = ddd7efe6 DAUC vector [0]: auth_types = 0x3 @@ -364,6 +380,7 @@ DAUC vector [0]: ik = 66bec707eb2afc476d7408a8f2927b36 DAUC vector [0]: res = 479dd25c20792d630000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = a819e577a8d6175b DAUC vector [0]: sres = 67e4ff3f DAUC vector [0]: auth_types = 0x3 @@ -386,6 +403,7 @@ DAUC vector [0]: ik = 9744871ad32bf9bbd1dd5ce54e3e2e5a DAUC vector [0]: res = 28d7b0f2a2ec3de50000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = 9a8d0e883ff0887a DAUC vector [0]: sres = 8a3b8d17 DAUC vector [0]: auth_types = 0x3 @@ -408,6 +426,7 @@ DAUC vector [0]: ik = b4721368bc16ea67875c5598688bb0ef DAUC vector [0]: res = a95100e2760952cd0000000000000000 DAUC vector [0]: res_len = 8 +DAUC vector [0]: deriving 2G from 3G DAUC vector [0]: kc = ed29b2f1c27f9f34 DAUC vector [0]: sres = df58522f DAUC vector [0]: auth_types = 0x3 diff -Nru osmo-hlr-0.1.0/tests/auc/gen_ts_55_205_test_sets/main_template.c osmo-hlr-0.2.1/tests/auc/gen_ts_55_205_test_sets/main_template.c --- osmo-hlr-0.1.0/tests/auc/gen_ts_55_205_test_sets/main_template.c 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/tests/auc/gen_ts_55_205_test_sets/main_template.c 2018-05-04 16:41:35.000000000 +0000 @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -102,7 +103,9 @@ int main() { printf("3GPP TS 55.205 Test Sets\n"); - osmo_init_logging(&hlr_log_info); + void *tall_ctx = talloc_named_const(NULL, 1, "test"); + msgb_talloc_ctx_init(tall_ctx, 0); + osmo_init_logging2(tall_ctx, &hlr_log_info); log_set_print_filename(osmo_stderr_target, 0); log_set_print_timestamp(osmo_stderr_target, 0); log_set_use_color(osmo_stderr_target, 0); diff -Nru osmo-hlr-0.1.0/tests/db/db_test.c osmo-hlr-0.2.1/tests/db/db_test.c --- osmo-hlr-0.1.0/tests/db/db_test.c 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/tests/db/db_test.c 2018-05-04 16:41:35.000000000 +0000 @@ -100,6 +100,22 @@ fprintf(stderr, "\n"); \ } while (0) +#define N_VECTORS 3 + +#define ASSERT_DB_GET_AUC(imsi, expect_rc) \ + do { \ + struct osmo_auth_vector vec[N_VECTORS]; \ + ASSERT_RC(db_get_auc(dbc, imsi, 3, vec, N_VECTORS, NULL, NULL), expect_rc); \ + } while (0) + +/* Not linking the real auc_compute_vectors(), just returning num_vec. + * This gets called by db_get_auc(), but we're only interested in its rc. */ +int auc_compute_vectors(struct osmo_auth_vector *vec, unsigned int num_vec, + struct osmo_sub_auth_data *aud2g, + struct osmo_sub_auth_data *aud3g, + const uint8_t *rand_auts, const uint8_t *auts) +{ return num_vec; } + static struct db_context *dbc = NULL; static void *ctx = NULL; static struct hlr_subscriber g_subscr; @@ -457,6 +473,7 @@ comment("Get auth data for non-existent subscriber"); ASSERT_SEL_AUD(unknown_imsi, -ENOENT, 0); + ASSERT_DB_GET_AUC(imsi0, -ENOENT); comment("Create subscriber"); @@ -464,7 +481,8 @@ ASSERT_SEL(imsi, imsi0, 0); id = g_subscr.id; - ASSERT_SEL_AUD(imsi0, -ENOENT, id); + ASSERT_SEL_AUD(imsi0, -ENOKEY, id); + ASSERT_DB_GET_AUC(imsi0, -ENOKEY); comment("Set auth data, 2G only"); @@ -473,6 +491,7 @@ mk_aud_2g(OSMO_AUTH_ALG_COMP128v1, "0123456789abcdef0123456789abcdef")), 0); ASSERT_SEL_AUD(imsi0, 0, id); + ASSERT_DB_GET_AUC(imsi0, N_VECTORS); /* same again */ ASSERT_RC(db_subscr_update_aud_by_id(dbc, id, @@ -500,7 +519,8 @@ ASSERT_RC(db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_NONE, NULL)), 0); - ASSERT_SEL_AUD(imsi0, -ENOENT, id); + ASSERT_SEL_AUD(imsi0, -ENOKEY, id); + ASSERT_DB_GET_AUC(imsi0, -ENOKEY); /* Removing nothing results in -ENOENT */ ASSERT_RC(db_subscr_update_aud_by_id(dbc, id, @@ -515,7 +535,8 @@ ASSERT_RC(db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_NONE, "f000000000000f00000000000f000000")), 0); - ASSERT_SEL_AUD(imsi0, -ENOENT, id); + ASSERT_SEL_AUD(imsi0, -ENOKEY, id); + ASSERT_DB_GET_AUC(imsi0, -ENOKEY); comment("Set auth data, 3G only"); @@ -526,6 +547,7 @@ "C01ffedC1cadaeAc1d1f1edAcac1aB0a", 5)), 0); ASSERT_SEL_AUD(imsi0, 0, id); + ASSERT_DB_GET_AUC(imsi0, N_VECTORS); /* same again */ ASSERT_RC(db_subscr_update_aud_by_id(dbc, id, @@ -562,7 +584,8 @@ ASSERT_RC(db_subscr_update_aud_by_id(dbc, id, mk_aud_3g(OSMO_AUTH_ALG_NONE, NULL, false, NULL, 0)), 0); - ASSERT_SEL_AUD(imsi0, -ENOENT, id); + ASSERT_SEL_AUD(imsi0, -ENOKEY, id); + ASSERT_DB_GET_AUC(imsi0, -ENOKEY); /* Removing nothing results in -ENOENT */ ASSERT_RC(db_subscr_update_aud_by_id(dbc, id, @@ -575,13 +598,15 @@ "BeefedCafeFaceAcedAddedDecadeFee", 5)), 0); ASSERT_SEL_AUD(imsi0, 0, id); + ASSERT_DB_GET_AUC(imsi0, N_VECTORS); ASSERT_RC(db_subscr_update_aud_by_id(dbc, id, mk_aud_3g(OSMO_AUTH_ALG_NONE, "asdfasdfasd", false, "asdfasdfasdf", 99999)), 0); - ASSERT_SEL_AUD(imsi0, -ENOENT, id); + ASSERT_SEL_AUD(imsi0, -ENOKEY, id); + ASSERT_DB_GET_AUC(imsi0, -ENOKEY); comment("Set auth data, 2G and 3G"); @@ -595,6 +620,7 @@ "DeafBeddedBabeAcceededFadedDecaf", 5)), 0); ASSERT_SEL_AUD(imsi0, 0, id); + ASSERT_DB_GET_AUC(imsi0, N_VECTORS); comment("Set invalid auth data"); @@ -669,10 +695,12 @@ /* For this test to work, we want to get the same subscriber ID back, * and make sure there are no auth data leftovers for this ID. */ OSMO_ASSERT(id == g_subscr.id); - ASSERT_SEL_AUD(imsi0, -ENOENT, id); + ASSERT_SEL_AUD(imsi0, -ENOKEY, id); + ASSERT_DB_GET_AUC(imsi0, -ENOKEY); ASSERT_RC(db_subscr_delete_by_id(dbc, id), 0); ASSERT_SEL(imsi, imsi0, -ENOENT); + ASSERT_DB_GET_AUC(imsi0, -ENOENT); comment_end(); } @@ -697,15 +725,15 @@ ASSERT_SEL(imsi, imsi0, 0); id = g_subscr.id; - ASSERT_SEL_AUD(imsi0, -ENOENT, id); + ASSERT_SEL_AUD(imsi0, -ENOKEY, id); comment("Set SQN, but no 3G auth data present"); ASSERT_RC(db_update_sqn(dbc, id, 123), -ENOENT); - ASSERT_SEL_AUD(imsi0, -ENOENT, id); + ASSERT_SEL_AUD(imsi0, -ENOKEY, id); ASSERT_RC(db_update_sqn(dbc, id, 543), -ENOENT); - ASSERT_SEL_AUD(imsi0, -ENOENT, id); + ASSERT_SEL_AUD(imsi0, -ENOKEY, id); comment("Set auth 3G data"); @@ -811,7 +839,7 @@ handle_options(argc, argv); - osmo_init_logging(&hlr_log_info); + osmo_init_logging2(ctx, &hlr_log_info); log_set_print_filename(osmo_stderr_target, cmdline_opts.verbose); log_set_print_timestamp(osmo_stderr_target, 0); log_set_use_color(osmo_stderr_target, 0); @@ -820,7 +848,9 @@ /* omit the SQLite version and compilation flags from test output */ log_set_log_level(osmo_stderr_target, LOGL_ERROR); - dbc = db_open(ctx, "db_test.db"); + /* Disable SQLite logging so that we're not vulnerable on SQLite error messages changing across + * library versions. */ + dbc = db_open(ctx, "db_test.db", false); log_set_log_level(osmo_stderr_target, 0); OSMO_ASSERT(dbc); @@ -833,11 +863,6 @@ } /* stubs */ -int auc_compute_vectors(struct osmo_auth_vector *vec, unsigned int num_vec, - struct osmo_sub_auth_data *aud2g, - struct osmo_sub_auth_data *aud3g, - const uint8_t *rand_auts, const uint8_t *auts) -{ OSMO_ASSERT(false); return -1; } void *lu_op_alloc_conn(void *conn) { OSMO_ASSERT(false); return NULL; } void lu_op_tx_del_subscr_data(void *luop) diff -Nru osmo-hlr-0.1.0/tests/db/db_test.err osmo-hlr-0.2.1/tests/db/db_test.err --- osmo-hlr-0.1.0/tests/db/db_test.err 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/tests/db/db_test.err 2018-05-04 16:41:35.000000000 +0000 @@ -28,7 +28,6 @@ } db_subscr_create(dbc, imsi0) --> -EIO -DDB (2067) abort at 18 in [INSERT INTO subscriber (imsi) VALUES ($imsi)]: UNIQUE constraint failed: subscriber.imsi DAUC IMSI='123456789000000': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> 0 @@ -38,11 +37,9 @@ } db_subscr_create(dbc, imsi1) --> -EIO -DDB (2067) abort at 18 in [INSERT INTO subscriber (imsi) VALUES ($imsi)]: UNIQUE constraint failed: subscriber.imsi DAUC IMSI='123456789000001': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi db_subscr_create(dbc, imsi1) --> -EIO -DDB (2067) abort at 18 in [INSERT INTO subscriber (imsi) VALUES ($imsi)]: UNIQUE constraint failed: subscriber.imsi DAUC IMSI='123456789000001': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi db_subscr_get_by_imsi(dbc, imsi1, &g_subscr) --> 0 @@ -52,11 +49,9 @@ } db_subscr_create(dbc, imsi2) --> -EIO -DDB (2067) abort at 18 in [INSERT INTO subscriber (imsi) VALUES ($imsi)]: UNIQUE constraint failed: subscriber.imsi DAUC IMSI='123456789000002': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi db_subscr_create(dbc, imsi2) --> -EIO -DDB (2067) abort at 18 in [INSERT INTO subscriber (imsi) VALUES ($imsi)]: UNIQUE constraint failed: subscriber.imsi DAUC IMSI='123456789000002': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi db_subscr_get_by_imsi(dbc, imsi2, &g_subscr) --> 0 @@ -720,6 +715,9 @@ DAUC IMSI='999999999': No such subscriber +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> -2 +DAUC IMSI='123456789000000': No such subscriber + --- Create subscriber @@ -731,11 +729,15 @@ .imsi = '123456789000000', } -db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -2 +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -126 DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> -126 +DAUC IMSI='123456789000000': No 2G Auth Data +DAUC IMSI='123456789000000': No 3G Auth Data + --- Set auth data, 2G only @@ -751,6 +753,11 @@ } 3G: none +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> 3 +DAUC IMSI='123456789000000': No 3G Auth Data +DAUC IMSI='123456789000000': Calling to generate 3 vectors +DAUC IMSI='123456789000000': Generated 3 vectors + db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_COMP128v1, "0123456789abcdef0123456789abcdef")) --> 0 db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 @@ -804,11 +811,15 @@ db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_NONE, NULL)) --> 0 -db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -2 +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -126 DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> -126 +DAUC IMSI='123456789000000': No 2G Auth Data +DAUC IMSI='123456789000000': No 3G Auth Data + db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_NONE, NULL)) --> -ENOENT db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_XOR, "CededEffacedAceFacedBadFadedBeef")) --> 0 @@ -825,11 +836,15 @@ db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_NONE, "f000000000000f00000000000f000000")) --> 0 -db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -2 +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -126 DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> -126 +DAUC IMSI='123456789000000': No 2G Auth Data +DAUC IMSI='123456789000000': No 3G Auth Data + --- Set auth data, 3G only @@ -849,6 +864,12 @@ .u.umts.ind_bitlen = 5, } +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> 3 +DAUC IMSI='123456789000000': No 2G Auth Data +DAUC IMSI='123456789000000': Calling to generate 3 vectors +DAUC IMSI='123456789000000': Generated 3 vectors +DAUC IMSI='123456789000000': Updating SQN=0 in DB + db_subscr_update_aud_by_id(dbc, id, mk_aud_3g(OSMO_AUTH_ALG_MILENAGE, "BeefedCafeFaceAcedAddedDecadeFee", true, "C01ffedC1cadaeAc1d1f1edAcac1aB0a", 5)) --> 0 db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 @@ -917,11 +938,15 @@ db_subscr_update_aud_by_id(dbc, id, mk_aud_3g(OSMO_AUTH_ALG_NONE, NULL, false, NULL, 0)) --> 0 -db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -2 +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -126 DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> -126 +DAUC IMSI='123456789000000': No 2G Auth Data +DAUC IMSI='123456789000000': No 3G Auth Data + db_subscr_update_aud_by_id(dbc, id, mk_aud_3g(OSMO_AUTH_ALG_NONE, NULL, false, NULL, 0)) --> -ENOENT db_subscr_update_aud_by_id(dbc, id, mk_aud_3g(OSMO_AUTH_ALG_MILENAGE, "CededEffacedAceFacedBadFadedBeef", false, "BeefedCafeFaceAcedAddedDecadeFee", 5)) --> 0 @@ -940,13 +965,23 @@ .u.umts.ind_bitlen = 5, } +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> 3 +DAUC IMSI='123456789000000': No 2G Auth Data +DAUC IMSI='123456789000000': Calling to generate 3 vectors +DAUC IMSI='123456789000000': Generated 3 vectors +DAUC IMSI='123456789000000': Updating SQN=0 in DB + db_subscr_update_aud_by_id(dbc, id, mk_aud_3g(OSMO_AUTH_ALG_NONE, "asdfasdfasd", false, "asdfasdfasdf", 99999)) --> 0 -db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -2 +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -126 DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> -126 +DAUC IMSI='123456789000000': No 2G Auth Data +DAUC IMSI='123456789000000': No 3G Auth Data + --- Set auth data, 2G and 3G @@ -971,6 +1006,11 @@ .u.umts.ind_bitlen = 5, } +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> 3 +DAUC IMSI='123456789000000': Calling to generate 3 vectors +DAUC IMSI='123456789000000': Generated 3 vectors +DAUC IMSI='123456789000000': Updating SQN=0 in DB + --- Set invalid auth data @@ -1179,16 +1219,23 @@ .imsi = '123456789000000', } -db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -2 +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -126 DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> -126 +DAUC IMSI='123456789000000': No 2G Auth Data +DAUC IMSI='123456789000000': No 3G Auth Data + db_subscr_delete_by_id(dbc, id) --> 0 db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> -ENOENT DAUC Cannot read subscriber from db: IMSI='123456789000000': No such subscriber +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> -2 +DAUC IMSI='123456789000000': No such subscriber + ===== test_subscr_aud: SUCCESS @@ -1219,7 +1266,7 @@ .imsi = '123456789000000', } -db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -2 +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -126 DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data @@ -1230,7 +1277,7 @@ db_update_sqn(dbc, id, 123) --> -ENOENT DAUC Cannot update SQN for subscriber ID=1: no auc_3g entry for such subscriber -db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -2 +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -126 DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data @@ -1238,7 +1285,7 @@ db_update_sqn(dbc, id, 543) --> -ENOENT DAUC Cannot update SQN for subscriber ID=1: no auc_3g entry for such subscriber -db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -2 +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -126 DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data diff -Nru osmo-hlr-0.1.0/tests/db/Makefile.am osmo-hlr-0.2.1/tests/db/Makefile.am --- osmo-hlr-0.1.0/tests/db/Makefile.am 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/tests/db/Makefile.am 2018-05-04 16:41:35.000000000 +0000 @@ -6,6 +6,7 @@ -ggdb3 \ $(LIBOSMOCORE_CFLAGS) \ $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ $(SQLITE3_CFLAGS) \ $(NULL) @@ -27,6 +28,7 @@ $(top_srcdir)/src/logging.c \ $(LIBOSMOCORE_LIBS) \ $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ $(SQLITE3_LIBS) \ $(NULL) diff -Nru osmo-hlr-0.1.0/tests/gsup/gsup_test.c osmo-hlr-0.2.1/tests/gsup/gsup_test.c --- osmo-hlr-0.1.0/tests/gsup/gsup_test.c 1970-01-01 00:00:00.000000000 +0000 +++ osmo-hlr-0.2.1/tests/gsup/gsup_test.c 2018-05-04 16:41:35.000000000 +0000 @@ -0,0 +1,91 @@ +/* (C) 2018 by sysmocom - s.f.m.c. GmbH + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include + +#include +#include +#include +#include + +#include "logging.h" +#include "luop.h" + +struct osmo_gsup_server; + +/* override osmo_gsup_addr_send() to not actually send anything. */ +int osmo_gsup_addr_send(struct osmo_gsup_server *gs, + const uint8_t *addr, size_t addrlen, + struct msgb *msg) +{ + LOGP(DMAIN, LOGL_DEBUG, "%s\n", msgb_hexdump(msg)); + msgb_free(msg); + return 0; +} + +int db_subscr_get_by_imsi(struct db_context *dbc, const char *imsi, + struct hlr_subscriber *subscr) +{ + return 0; +} + +/* Verify that the internally allocated msgb is large enough */ +void test_gsup_tx_insert_subscr_data() +{ + struct lu_operation luop = { + .state = LU_S_LU_RECEIVED, + .subscr = { + .imsi = "123456789012345", + .msisdn = "987654321098765", + .nam_cs = true, + .nam_ps = true, + }, + .is_ps = true, + }; + + lu_op_tx_insert_subscr_data(&luop); +} + +const struct log_info_cat default_categories[] = { + [DMAIN] = { + .name = "DMAIN", + .description = "Main Program", + .enabled = 1, .loglevel = LOGL_DEBUG, + }, +}; + +static struct log_info info = { + .cat = default_categories, + .num_cat = ARRAY_SIZE(default_categories), +}; + +int main(int argc, char **argv) +{ + void *ctx = talloc_named_const(NULL, 0, "gsup_test"); + osmo_init_logging2(ctx, &info); + log_set_print_filename(osmo_stderr_target, 0); + log_set_print_timestamp(osmo_stderr_target, 0); + log_set_use_color(osmo_stderr_target, 0); + log_set_print_category(osmo_stderr_target, 1); + + test_gsup_tx_insert_subscr_data(); + + printf("Done.\n"); + return EXIT_SUCCESS; +} diff -Nru osmo-hlr-0.1.0/tests/gsup/gsup_test.err osmo-hlr-0.2.1/tests/gsup/gsup_test.err --- osmo-hlr-0.1.0/tests/gsup/gsup_test.err 1970-01-01 00:00:00.000000000 +0000 +++ osmo-hlr-0.2.1/tests/gsup/gsup_test.err 2018-05-04 16:41:35.000000000 +0000 @@ -0,0 +1,2 @@ +DMAIN 10 01 08 21 43 65 87 09 21 43 f5 08 09 08 89 67 45 23 01 89 67 f5 05 07 10 01 01 12 02 01 2a +DMAIN LU OP state change: LU RECEIVED -> ISD SENT diff -Nru osmo-hlr-0.1.0/tests/gsup/gsup_test.ok osmo-hlr-0.2.1/tests/gsup/gsup_test.ok --- osmo-hlr-0.1.0/tests/gsup/gsup_test.ok 1970-01-01 00:00:00.000000000 +0000 +++ osmo-hlr-0.2.1/tests/gsup/gsup_test.ok 2018-05-04 16:41:35.000000000 +0000 @@ -0,0 +1 @@ +Done. diff -Nru osmo-hlr-0.1.0/tests/gsup/Makefile.am osmo-hlr-0.2.1/tests/gsup/Makefile.am --- osmo-hlr-0.1.0/tests/gsup/Makefile.am 1970-01-01 00:00:00.000000000 +0000 +++ osmo-hlr-0.2.1/tests/gsup/Makefile.am 2018-05-04 16:41:35.000000000 +0000 @@ -0,0 +1,41 @@ +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/src \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(NULL) + +AM_LDFLAGS = \ + $(NULL) + +EXTRA_DIST = \ + gsup_test.ok \ + gsup_test.err \ + $(NULL) + +noinst_PROGRAMS = \ + gsup_test \ + $(NULL) + +gsup_test_SOURCES = \ + gsup_test.c \ + $(NULL) + +gsup_test_LDADD = \ + $(top_srcdir)/src/luop.c \ + $(top_srcdir)/src/gsup_server.c \ + $(top_srcdir)/src/gsup_router.c \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(NULL) + +.PHONY: update_exp +update_exp: + $(builddir)/gsup_test >"$(srcdir)/gsup_test.ok" 2>"$(srcdir)/gsup_test.err" diff -Nru osmo-hlr-0.1.0/tests/Makefile.am osmo-hlr-0.2.1/tests/Makefile.am --- osmo-hlr-0.1.0/tests/Makefile.am 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/tests/Makefile.am 2018-05-04 16:41:35.000000000 +0000 @@ -2,6 +2,7 @@ auc \ gsup_server \ db \ + gsup \ $(NULL) # The `:;' works around a Bash 3.2 bug when the output is not writeable. diff -Nru osmo-hlr-0.1.0/tests/test_nodes.vty osmo-hlr-0.2.1/tests/test_nodes.vty --- osmo-hlr-0.1.0/tests/test_nodes.vty 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/tests/test_nodes.vty 2018-05-04 16:41:35.000000000 +0000 @@ -13,6 +13,9 @@ ... show logging vty show alarms + show talloc-context (application|all) (full|brief|DEPTH) + show talloc-context (application|all) (full|brief|DEPTH) tree ADDRESS + show talloc-context (application|all) (full|brief|DEPTH) filter REGEXP subscriber (imsi|msisdn|id) IDENT show OsmoHLR> enable @@ -100,6 +103,7 @@ logging color 1 logging print category 1 logging print extended-timestamp 1 + logging print file 1 logging level all debug logging level main notice logging level db notice diff -Nru osmo-hlr-0.1.0/tests/test_subscriber_errors.ctrl osmo-hlr-0.2.1/tests/test_subscriber_errors.ctrl --- osmo-hlr-0.1.0/tests/test_subscriber_errors.ctrl 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/tests/test_subscriber_errors.ctrl 2018-05-04 16:41:35.000000000 +0000 @@ -62,26 +62,26 @@ ERROR 28 Invalid value part of 'by-xxx-value' selector. GET 29 subscriber.by-id-1+1.info -ERROR 29 Invalid value part of 'by-xxx-value' selector. +ERROR 29 GET variable contains invalid characters GET 30 subscriber.by-id--.info ERROR 30 Invalid value part of 'by-xxx-value' selector. GET 31 subscriber.by-id-+1.info -ERROR 31 Invalid value part of 'by-xxx-value' selector. +ERROR 31 GET variable contains invalid characters GET 32 subscriber.by-id-+-1.info -ERROR 32 Invalid value part of 'by-xxx-value' selector. +ERROR 32 GET variable contains invalid characters GET 33 subscriber.by-id--+1.info -ERROR 33 Invalid value part of 'by-xxx-value' selector. +ERROR 33 GET variable contains invalid characters GET 34 subscriber.by-id-++1.info -ERROR 34 Invalid value part of 'by-xxx-value' selector. +ERROR 34 GET variable contains invalid characters GET 35 subscriber.by-id---1.info ERROR 35 Invalid value part of 'by-xxx-value' selector. GET 36 subscriber.by-id- 1.info -ERROR 36 Command not present. +ERROR 36 GET with trailing characters GET 37 subscriber.by-id-+ 1.info -ERROR 37 Command not present. +ERROR 37 GET variable contains invalid characters GET 38 subscriber.by-id-- 1.info -ERROR 38 Command not present. +ERROR 38 GET with trailing characters SET 39 subscriber.by-imsi-901990000000001.info foo @@ -97,9 +97,9 @@ ERROR 43 Value failed verification. SET 44 subscriber.by-imsi-901990000000001.ps-enabled -ERROR err Command parser error. +ERROR 44 SET incomplete SET 45 subscriber.by-imsi-901990000000001.cs-enabled -ERROR err Command parser error. +ERROR 45 SET incomplete GET 46 subscriber.by-imsi-1234567890123456.ps-enabled ERROR 46 Invalid value part of 'by-xxx-value' selector. diff -Nru osmo-hlr-0.1.0/tests/testsuite.at osmo-hlr-0.2.1/tests/testsuite.at --- osmo-hlr-0.1.0/tests/testsuite.at 2017-10-28 18:43:12.000000000 +0000 +++ osmo-hlr-0.2.1/tests/testsuite.at 2018-05-04 16:41:35.000000000 +0000 @@ -15,6 +15,13 @@ AT_CHECK([$abs_top_builddir/tests/auc/auc_ts_55_205_test_sets], [], [expout], [experr]) AT_CLEANUP +AT_SETUP([gsup]) +AT_KEYWORDS([gsup]) +cat $abs_srcdir/gsup/gsup_test.ok > expout +cat $abs_srcdir/gsup/gsup_test.err > experr +AT_CHECK([$abs_top_builddir/tests/gsup/gsup_test], [], [expout], [experr]) +AT_CLEANUP + AT_SETUP([gsup_server]) AT_KEYWORDS([gsup_server]) cat $abs_srcdir/gsup_server/gsup_server_test.ok > expout