<p>Harald Welte has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/10259">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">migrate to oap_client in libosmogsm<br><br>libosmogsm in libosmocore.git from Change-Id<br>Ie36729996abd30b84d1c30a09f62ebc6a9794950 onwards contains oap_client.c,<br>so we don't need our local copy here in this repo anymore.<br><br>Change-Id: I7b194f98ef3f925b6178d8a8dbd9fcf2f0c6e132<br>Requires: libosmocore.git Change-Id Ie36729996abd30b84d1c30a09f62ebc6a9794950<br>---<br>M include/osmocom/sgsn/Makefile.am<br>M include/osmocom/sgsn/gsup_client.h<br>D include/osmocom/sgsn/oap_client.h<br>M include/osmocom/sgsn/sgsn.h<br>M src/gprs/Makefile.am<br>M src/gprs/gsup_client.c<br>D src/gprs/oap_client.c<br>M src/libcommon/gsup_client.c<br>D src/libcommon/oap_client.c<br>M tests/Makefile.am<br>D tests/oap/Makefile.am<br>D tests/oap/oap_client_test.c<br>D tests/oap/oap_client_test.err<br>D tests/oap/oap_client_test.ok<br>M tests/testsuite.at<br>15 files changed, 15 insertions(+), 1,008 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-sgsn refs/changes/59/10259/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/sgsn/Makefile.am b/include/osmocom/sgsn/Makefile.am</span><br><span>index 3f63b9f..269cebc 100644</span><br><span>--- a/include/osmocom/sgsn/Makefile.am</span><br><span>+++ b/include/osmocom/sgsn/Makefile.am</span><br><span>@@ -17,7 +17,6 @@</span><br><span>     gprs_utils.h \</span><br><span>       gsup_client.h \</span><br><span>      gtphub.h \</span><br><span style="color: hsl(0, 100%, 40%);">-      oap_client.h \</span><br><span>       sgsn.h \</span><br><span>     signal.h \</span><br><span>   slhc.h \</span><br><span>diff --git a/include/osmocom/sgsn/gsup_client.h b/include/osmocom/sgsn/gsup_client.h</span><br><span>index 29092ad..6ba0d15 100644</span><br><span>--- a/include/osmocom/sgsn/gsup_client.h</span><br><span>+++ b/include/osmocom/sgsn/gsup_client.h</span><br><span>@@ -23,7 +23,7 @@</span><br><span> </span><br><span> #include <osmocom/core/timer.h></span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/sgsn/oap_client.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/oap_client.h></span><br><span> </span><br><span> #define GSUP_CLIENT_RECONNECT_INTERVAL 10</span><br><span> #define GSUP_CLIENT_PING_INTERVAL 20</span><br><span>@@ -43,7 +43,7 @@</span><br><span>         gsup_client_read_cb_t read_cb;</span><br><span>       void *data;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- struct oap_client_state oap_state;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct osmo_oap_client_state oap_state;</span><br><span> </span><br><span>  struct osmo_timer_list ping_timer;</span><br><span>   struct osmo_timer_list connect_timer;</span><br><span>@@ -55,7 +55,7 @@</span><br><span>                                   const char *ip_addr,</span><br><span>                                 unsigned int tcp_port,</span><br><span>                                       gsup_client_read_cb_t read_cb,</span><br><span style="color: hsl(0, 100%, 40%);">-                                  struct oap_client_config *oapc_config);</span><br><span style="color: hsl(120, 100%, 40%);">+                                       struct osmo_oap_client_config *oapc_config);</span><br><span> </span><br><span> void gsup_client_destroy(struct gsup_client *gsupc);</span><br><span> int gsup_client_send(struct gsup_client *gsupc, struct msgb *msg);</span><br><span>diff --git a/include/osmocom/sgsn/oap_client.h b/include/osmocom/sgsn/oap_client.h</span><br><span>deleted file mode 100644</span><br><span>index 80c86d5..0000000</span><br><span>--- a/include/osmocom/sgsn/oap_client.h</span><br><span>+++ /dev/null</span><br><span>@@ -1,82 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/* Osmocom Authentication Protocol API */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* (C) 2015 by Sysmocom s.f.m.c. GmbH</span><br><span style="color: hsl(0, 100%, 40%);">- * All Rights Reserved</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * Author: Neels Hofmeyr</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(0, 100%, 40%);">- * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(0, 100%, 40%);">- * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(0, 100%, 40%);">- * (at your option) any later version.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(0, 100%, 40%);">- * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(0, 100%, 40%);">- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(0, 100%, 40%);">- * GNU Affero General Public License for more details.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(0, 100%, 40%);">- * along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#pragma once</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <stdint.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct msgb;</span><br><span style="color: hsl(0, 100%, 40%);">-struct osmo_oap_message;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* This is the config part for vty. It is essentially copied in</span><br><span style="color: hsl(0, 100%, 40%);">- * oap_client_state, where values are copied over once the config is</span><br><span style="color: hsl(0, 100%, 40%);">- * considered valid. */</span><br><span style="color: hsl(0, 100%, 40%);">-struct oap_client_config {</span><br><span style="color: hsl(0, 100%, 40%);">-      uint16_t client_id;</span><br><span style="color: hsl(0, 100%, 40%);">-     int secret_k_present;</span><br><span style="color: hsl(0, 100%, 40%);">-   uint8_t secret_k[16];</span><br><span style="color: hsl(0, 100%, 40%);">-   int secret_opc_present;</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t secret_opc[16];</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* The runtime state of the OAP client. client_id and the secrets are in fact</span><br><span style="color: hsl(0, 100%, 40%);">- * duplicated from oap_client_config, so that a separate validation of the</span><br><span style="color: hsl(0, 100%, 40%);">- * config data is possible, and so that only a struct oap_client_state* is</span><br><span style="color: hsl(0, 100%, 40%);">- * passed around. */</span><br><span style="color: hsl(0, 100%, 40%);">-struct oap_client_state {</span><br><span style="color: hsl(0, 100%, 40%);">- enum {</span><br><span style="color: hsl(0, 100%, 40%);">-          OAP_UNINITIALIZED = 0,  /* just allocated. */</span><br><span style="color: hsl(0, 100%, 40%);">-           OAP_DISABLED,           /* disabled by config. */</span><br><span style="color: hsl(0, 100%, 40%);">-               OAP_INITIALIZED,        /* enabled, config is valid. */</span><br><span style="color: hsl(0, 100%, 40%);">-         OAP_REQUESTED_CHALLENGE,</span><br><span style="color: hsl(0, 100%, 40%);">-                OAP_SENT_CHALLENGE_RESULT,</span><br><span style="color: hsl(0, 100%, 40%);">-              OAP_REGISTERED</span><br><span style="color: hsl(0, 100%, 40%);">-  } state;</span><br><span style="color: hsl(0, 100%, 40%);">-        uint16_t client_id;</span><br><span style="color: hsl(0, 100%, 40%);">-     uint8_t secret_k[16];</span><br><span style="color: hsl(0, 100%, 40%);">-   uint8_t secret_opc[16];</span><br><span style="color: hsl(0, 100%, 40%);">- int registration_failures;</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* From config, initialize state. Return 0 on success. */</span><br><span style="color: hsl(0, 100%, 40%);">-int oap_client_init(struct oap_client_config *config,</span><br><span style="color: hsl(0, 100%, 40%);">-                  struct oap_client_state *state);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Construct an OAP registration message and return in *msg_tx. Use</span><br><span style="color: hsl(0, 100%, 40%);">- * state->client_id and update state->state.</span><br><span style="color: hsl(0, 100%, 40%);">- * Return 0 on success, or a negative value on error.</span><br><span style="color: hsl(0, 100%, 40%);">- * If an error is returned, *msg_tx is guaranteed to be NULL. */</span><br><span style="color: hsl(0, 100%, 40%);">-int oap_client_register(struct oap_client_state *state, struct msgb **msg_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Decode and act on a received OAP message msg_rx. Update state->state.  If a</span><br><span style="color: hsl(0, 100%, 40%);">- * non-NULL pointer is returned in *msg_tx, that msgb should be sent to the OAP</span><br><span style="color: hsl(0, 100%, 40%);">- * server (and freed) by the caller. The received msg_rx is not freed.</span><br><span style="color: hsl(0, 100%, 40%);">- * Return 0 on success, or a negative value on error.</span><br><span style="color: hsl(0, 100%, 40%);">- * If an error is returned, *msg_tx is guaranteed to be NULL. */</span><br><span style="color: hsl(0, 100%, 40%);">-int oap_client_handle(struct oap_client_state *state,</span><br><span style="color: hsl(0, 100%, 40%);">-                  const struct msgb *msg_rx, struct msgb **msg_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Allocate a msgb and in it, return the encoded oap_client_msg. Return</span><br><span style="color: hsl(0, 100%, 40%);">- * NULL on error. (Like oap_client_encode(), but also allocates a msgb.)</span><br><span style="color: hsl(0, 100%, 40%);">- * About the name: the idea is do_something(oap_client_encoded(my_struct))</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-struct msgb *oap_client_encoded(const struct osmo_oap_message *oap_client_msg);</span><br><span>diff --git a/include/osmocom/sgsn/sgsn.h b/include/osmocom/sgsn/sgsn.h</span><br><span>index dae9d12..59d0bd7 100644</span><br><span>--- a/include/osmocom/sgsn/sgsn.h</span><br><span>+++ b/include/osmocom/sgsn/sgsn.h</span><br><span>@@ -6,7 +6,7 @@</span><br><span> #include <osmocom/crypt/gprs_cipher.h></span><br><span> #include <osmocom/gprs/gprs_ns.h></span><br><span> #include <osmocom/sgsn/gprs_sgsn.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/sgsn/oap_client.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/oap_client.h></span><br><span> #include <osmocom/sgsn/common.h></span><br><span> </span><br><span> #include "../../bscconfig.h"</span><br><span>@@ -101,7 +101,7 @@</span><br><span> </span><br><span>         int dynamic_lookup;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- struct oap_client_config oap;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_oap_client_config oap;</span><br><span> </span><br><span>       /* RFC1144 TCP/IP header compression */</span><br><span>      struct {</span><br><span>diff --git a/src/gprs/Makefile.am b/src/gprs/Makefile.am</span><br><span>index 1cf6785..46d94d4 100644</span><br><span>--- a/src/gprs/Makefile.am</span><br><span>+++ b/src/gprs/Makefile.am</span><br><span>@@ -84,7 +84,6 @@</span><br><span>    gprs_llc_xid.c \</span><br><span>     v42bis.c \</span><br><span>   gsup_client.c \</span><br><span style="color: hsl(0, 100%, 40%);">- oap_client.c \</span><br><span>       $(NULL)</span><br><span> osmo_sgsn_LDADD = \</span><br><span>       $(OSMO_LIBS) \</span><br><span>diff --git a/src/gprs/gsup_client.c b/src/gprs/gsup_client.c</span><br><span>index 48357b4..95c4988 100644</span><br><span>--- a/src/gprs/gsup_client.c</span><br><span>+++ b/src/gprs/gsup_client.c</span><br><span>@@ -116,7 +116,7 @@</span><br><span> {</span><br><span>       struct msgb *msg_tx;</span><br><span>         int rc;</span><br><span style="color: hsl(0, 100%, 40%);">- rc = oap_client_register(&gsupc->oap_state, &msg_tx);</span><br><span style="color: hsl(120, 100%, 40%);">+      rc = osmo_oap_client_register(&gsupc->oap_state, &msg_tx);</span><br><span> </span><br><span>    if ((rc < 0) || (!msg_tx)) {</span><br><span>              LOGP(DLGSUP, LOGL_ERROR, "GSUP OAP set up, but cannot register.\n");</span><br><span>@@ -138,7 +138,7 @@</span><br><span>         if (up) {</span><br><span>            start_test_procedure(gsupc);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                if (gsupc->oap_state.state == OAP_INITIALIZED)</span><br><span style="color: hsl(120, 100%, 40%);">+             if (gsupc->oap_state.state == OSMO_OAP_INITIALIZED)</span><br><span>                       gsup_client_oap_register(gsupc);</span><br><span> </span><br><span>                 osmo_timer_del(&gsupc->connect_timer);</span><br><span>@@ -156,7 +156,7 @@</span><br><span>  struct msgb *msg_tx;</span><br><span> </span><br><span>     /* If the oap_state is disabled, this will reject the messages. */</span><br><span style="color: hsl(0, 100%, 40%);">-      rc = oap_client_handle(&gsupc->oap_state, msg_rx, &msg_tx);</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = osmo_oap_client_handle(&gsupc->oap_state, msg_rx, &msg_tx);</span><br><span>  msgb_free(msg_rx);</span><br><span>   if (rc < 0)</span><br><span>               return rc;</span><br><span>@@ -269,7 +269,7 @@</span><br><span>                                    const char *ip_addr,</span><br><span>                                 unsigned int tcp_port,</span><br><span>                                       gsup_client_read_cb_t read_cb,</span><br><span style="color: hsl(0, 100%, 40%);">-                                  struct oap_client_config *oapc_config)</span><br><span style="color: hsl(120, 100%, 40%);">+                                struct osmo_oap_client_config *oapc_config)</span><br><span> {</span><br><span>      struct gsup_client *gsupc;</span><br><span>   int rc;</span><br><span>@@ -284,7 +284,7 @@</span><br><span>        OSMO_ASSERT(gsupc->unit_name);</span><br><span> </span><br><span>        /* a NULL oapc_config will mark oap_state disabled. */</span><br><span style="color: hsl(0, 100%, 40%);">-  rc = oap_client_init(oapc_config, &gsupc->oap_state);</span><br><span style="color: hsl(120, 100%, 40%);">+  rc = osmo_oap_client_init(oapc_config, &gsupc->oap_state);</span><br><span>    if (rc != 0)</span><br><span>                 goto failed;</span><br><span> </span><br><span>diff --git a/src/gprs/oap_client.c b/src/gprs/oap_client.c</span><br><span>deleted file mode 100644</span><br><span>index 9ff84a6..0000000</span><br><span>--- a/src/gprs/oap_client.c</span><br><span>+++ /dev/null</span><br><span>@@ -1,280 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/* Osmocom Authentication Protocol API */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* (C) 2015 by Sysmocom s.f.m.c. GmbH</span><br><span style="color: hsl(0, 100%, 40%);">- * All Rights Reserved</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * Author: Neels Hofmeyr</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(0, 100%, 40%);">- * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(0, 100%, 40%);">- * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(0, 100%, 40%);">- * (at your option) any later version.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(0, 100%, 40%);">- * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(0, 100%, 40%);">- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(0, 100%, 40%);">- * GNU Affero General Public License for more details.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(0, 100%, 40%);">- * along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <string.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <errno.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/utils.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/crypt/auth.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/gsm/oap.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/sgsn/oap_client.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/sgsn/debug.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int oap_client_init(struct oap_client_config *config,</span><br><span style="color: hsl(0, 100%, 40%);">-              struct oap_client_state *state)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    OSMO_ASSERT(state->state == OAP_UNINITIALIZED);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      if (!config)</span><br><span style="color: hsl(0, 100%, 40%);">-            goto disable;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (config->client_id == 0)</span><br><span style="color: hsl(0, 100%, 40%);">-          goto disable;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (config->secret_k_present == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGP(DLOAP, LOGL_NOTICE, "OAP: client ID set, but secret K missing.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-              goto disable;</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (config->secret_opc_present == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-               LOGP(DLOAP, LOGL_NOTICE, "OAP: client ID set, but secret OPC missing.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-            goto disable;</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       state->client_id = config->client_id;</span><br><span style="color: hsl(0, 100%, 40%);">-     memcpy(state->secret_k, config->secret_k, sizeof(state->secret_k));</span><br><span style="color: hsl(0, 100%, 40%);">-    memcpy(state->secret_opc, config->secret_opc, sizeof(state->secret_opc));</span><br><span style="color: hsl(0, 100%, 40%);">-      state->state = OAP_INITIALIZED;</span><br><span style="color: hsl(0, 100%, 40%);">-      return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-disable:</span><br><span style="color: hsl(0, 100%, 40%);">-       state->state = OAP_DISABLED;</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* From the given state and received RAND and AUTN octets, validate the</span><br><span style="color: hsl(0, 100%, 40%);">- * server's authenticity and formulate the matching milenage reply octets in</span><br><span style="color: hsl(0, 100%, 40%);">- * *tx_xres. The state is not modified.</span><br><span style="color: hsl(0, 100%, 40%);">- * On success, and if tx_res is not NULL, exactly 8 octets will be written to</span><br><span style="color: hsl(0, 100%, 40%);">- * *tx_res. If not NULL, tx_res must point at allocated memory of at least 8</span><br><span style="color: hsl(0, 100%, 40%);">- * octets. The caller will want to send XRES back to the server in a challenge</span><br><span style="color: hsl(0, 100%, 40%);">- * response message and update the state.</span><br><span style="color: hsl(0, 100%, 40%);">- * Return 0 on success; -1 if OAP is disabled; -2 if rx_random and rx_autn fail</span><br><span style="color: hsl(0, 100%, 40%);">- * the authentication check; -3 for any other errors. */</span><br><span style="color: hsl(0, 100%, 40%);">-static int oap_evaluate_challenge(const struct oap_client_state *state,</span><br><span style="color: hsl(0, 100%, 40%);">-                            const uint8_t *rx_random,</span><br><span style="color: hsl(0, 100%, 40%);">-                               const uint8_t *rx_autn,</span><br><span style="color: hsl(0, 100%, 40%);">-                                 uint8_t *tx_xres)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    struct osmo_auth_vector vec;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    struct osmo_sub_auth_data auth = {</span><br><span style="color: hsl(0, 100%, 40%);">-              .type           = OSMO_AUTH_TYPE_UMTS,</span><br><span style="color: hsl(0, 100%, 40%);">-          .algo           = OSMO_AUTH_ALG_MILENAGE,</span><br><span style="color: hsl(0, 100%, 40%);">-       };</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      osmo_static_assert(sizeof(((struct osmo_sub_auth_data*)0)->u.umts.k)</span><br><span style="color: hsl(0, 100%, 40%);">-                    == sizeof(state->secret_k), _secret_k_size_match);</span><br><span style="color: hsl(0, 100%, 40%);">-        osmo_static_assert(sizeof(((struct osmo_sub_auth_data*)0)->u.umts.opc)</span><br><span style="color: hsl(0, 100%, 40%);">-                          == sizeof(state->secret_opc), _secret_opc_size_match);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    switch (state->state) {</span><br><span style="color: hsl(0, 100%, 40%);">-      case OAP_UNINITIALIZED:</span><br><span style="color: hsl(0, 100%, 40%);">- case OAP_DISABLED:</span><br><span style="color: hsl(0, 100%, 40%);">-              return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      default:</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       memcpy(auth.u.umts.k, state->secret_k, sizeof(auth.u.umts.k));</span><br><span style="color: hsl(0, 100%, 40%);">-       memcpy(auth.u.umts.opc, state->secret_opc, sizeof(auth.u.umts.opc));</span><br><span style="color: hsl(0, 100%, 40%);">- memset(auth.u.umts.amf, '\0', sizeof(auth.u.umts.amf));</span><br><span style="color: hsl(0, 100%, 40%);">- auth.u.umts.sqn = 41; /* TODO use incrementing sequence nr */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   memset(&vec, 0, sizeof(vec));</span><br><span style="color: hsl(0, 100%, 40%);">-       osmo_auth_gen_vec(&vec, &auth, rx_random);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      if (vec.res_len != 8) {</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGP(DLOAP, LOGL_ERROR, "OAP: Expected XRES to be 8 octets, got %d\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                     vec.res_len);</span><br><span style="color: hsl(0, 100%, 40%);">-              return -3;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (osmo_constant_time_cmp(vec.autn, rx_autn, sizeof(vec.autn)) != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGP(DLOAP, LOGL_ERROR, "OAP: AUTN mismatch!\n");</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGP(DLOAP, LOGL_INFO, "OAP: AUTN from server: %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-              osmo_hexdump_nospc(rx_autn, sizeof(vec.autn)));</span><br><span style="color: hsl(0, 100%, 40%);">-            LOGP(DLOAP, LOGL_INFO, "OAP: AUTN expected:    %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-              osmo_hexdump_nospc(vec.autn, sizeof(vec.autn)));</span><br><span style="color: hsl(0, 100%, 40%);">-           return -2;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (tx_xres != NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-            memcpy(tx_xres, vec.res, 8);</span><br><span style="color: hsl(0, 100%, 40%);">-    return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct msgb *oap_client_encoded(const struct osmo_oap_message *oap_msg)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      struct msgb *msg = msgb_alloc_headroom(1000, 64, __func__);</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_ASSERT(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-       osmo_oap_encode(msg, oap_msg);</span><br><span style="color: hsl(0, 100%, 40%);">-  return msg;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Create a new msgb containing an OAP registration message.</span><br><span style="color: hsl(0, 100%, 40%);">- * On error, return NULL. */</span><br><span style="color: hsl(0, 100%, 40%);">-static struct msgb* oap_msg_register(uint16_t client_id)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   struct osmo_oap_message oap_msg = {0};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  if (client_id < 1) {</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGP(DLOAP, LOGL_ERROR, "OAP: Invalid client ID: %d\n", client_id);</span><br><span style="color: hsl(0, 100%, 40%);">-           return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       oap_msg.message_type = OAP_MSGT_REGISTER_REQUEST;</span><br><span style="color: hsl(0, 100%, 40%);">-       oap_msg.client_id = client_id;</span><br><span style="color: hsl(0, 100%, 40%);">-  return oap_client_encoded(&oap_msg);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int oap_client_register(struct oap_client_state *state, struct msgb **msg_tx)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- *msg_tx = oap_msg_register(state->client_id);</span><br><span style="color: hsl(0, 100%, 40%);">-        if (!(*msg_tx))</span><br><span style="color: hsl(0, 100%, 40%);">-         return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      state->state = OAP_REQUESTED_CHALLENGE;</span><br><span style="color: hsl(0, 100%, 40%);">-      return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Create a new msgb containing an OAP challenge response message.</span><br><span style="color: hsl(0, 100%, 40%);">- * xres must point at 8 octets to return as challenge response.</span><br><span style="color: hsl(0, 100%, 40%);">- * On error, return NULL. */</span><br><span style="color: hsl(0, 100%, 40%);">-static struct msgb* oap_msg_challenge_response(uint8_t *xres)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   struct osmo_oap_message oap_reply = {0};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        oap_reply.message_type = OAP_MSGT_CHALLENGE_RESULT;</span><br><span style="color: hsl(0, 100%, 40%);">-     memcpy(oap_reply.xres, xres, sizeof(oap_reply.xres));</span><br><span style="color: hsl(0, 100%, 40%);">-   oap_reply.xres_present = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-     return oap_client_encoded(&oap_reply);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int handle_challenge(struct oap_client_state *state,</span><br><span style="color: hsl(0, 100%, 40%);">-                      struct osmo_oap_message *oap_rx,</span><br><span style="color: hsl(0, 100%, 40%);">-                        struct msgb **msg_tx)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      int rc;</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t xres[8];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        if (!(oap_rx->rand_present && oap_rx->autn_present)) {</span><br><span style="color: hsl(0, 100%, 40%);">-            LOGP(DLOAP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-              "OAP challenge incomplete (rand_present: %d, autn_present: %d)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                    oap_rx->rand_present, oap_rx->autn_present);</span><br><span style="color: hsl(0, 100%, 40%);">-         rc = -2;</span><br><span style="color: hsl(0, 100%, 40%);">-                goto failure;</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       rc = oap_evaluate_challenge(state,</span><br><span style="color: hsl(0, 100%, 40%);">-                                  oap_rx->rand,</span><br><span style="color: hsl(0, 100%, 40%);">-                                oap_rx->autn,</span><br><span style="color: hsl(0, 100%, 40%);">-                                xres);</span><br><span style="color: hsl(0, 100%, 40%);">-      if (rc < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-          goto failure;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   *msg_tx = oap_msg_challenge_response(xres);</span><br><span style="color: hsl(0, 100%, 40%);">-     if ((*msg_tx) == NULL) {</span><br><span style="color: hsl(0, 100%, 40%);">-                rc = -1;</span><br><span style="color: hsl(0, 100%, 40%);">-                goto failure;</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       state->state = OAP_SENT_CHALLENGE_RESULT;</span><br><span style="color: hsl(0, 100%, 40%);">-    return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-failure:</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(rc < 0);</span><br><span style="color: hsl(0, 100%, 40%);">- state->state = OAP_INITIALIZED;</span><br><span style="color: hsl(0, 100%, 40%);">-      return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int oap_client_handle(struct oap_client_state *state,</span><br><span style="color: hsl(0, 100%, 40%);">-                      const struct msgb *msg_rx, struct msgb **msg_tx)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t *data = msgb_l2(msg_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-        size_t data_len = msgb_l2len(msg_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-   struct osmo_oap_message oap_msg = {0};</span><br><span style="color: hsl(0, 100%, 40%);">-  int rc = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     *msg_tx = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(data);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      rc = osmo_oap_decode(&oap_msg, data, data_len);</span><br><span style="color: hsl(0, 100%, 40%);">-     if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DLOAP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-              "Decoding OAP message failed with error '%s' (%d)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                 get_value_string(gsm48_gmm_cause_names, -rc), -rc);</span><br><span style="color: hsl(0, 100%, 40%);">-                return -10;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       switch (state->state) {</span><br><span style="color: hsl(0, 100%, 40%);">-      case OAP_UNINITIALIZED:</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGP(DLOAP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-              "Received OAP message %d, but the OAP client is"</span><br><span style="color: hsl(0, 100%, 40%);">-              " not initialized\n", oap_msg.message_type);</span><br><span style="color: hsl(0, 100%, 40%);">-             return -ENOTCONN;</span><br><span style="color: hsl(0, 100%, 40%);">-       case OAP_DISABLED:</span><br><span style="color: hsl(0, 100%, 40%);">-              LOGP(DLOAP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-              "Received OAP message %d, but the OAP client is"</span><br><span style="color: hsl(0, 100%, 40%);">-              " disabled\n", oap_msg.message_type);</span><br><span style="color: hsl(0, 100%, 40%);">-            return -ENOTCONN;</span><br><span style="color: hsl(0, 100%, 40%);">-       default:</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       switch (oap_msg.message_type) {</span><br><span style="color: hsl(0, 100%, 40%);">- case OAP_MSGT_CHALLENGE_REQUEST:</span><br><span style="color: hsl(0, 100%, 40%);">-                return handle_challenge(state, &oap_msg, msg_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   case OAP_MSGT_REGISTER_RESULT:</span><br><span style="color: hsl(0, 100%, 40%);">-          /* successfully registered */</span><br><span style="color: hsl(0, 100%, 40%);">-           state->state = OAP_REGISTERED;</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  case OAP_MSGT_REGISTER_ERROR:</span><br><span style="color: hsl(0, 100%, 40%);">-           LOGP(DLOAP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-              "OAP registration failed\n");</span><br><span style="color: hsl(0, 100%, 40%);">-            state->state = OAP_INITIALIZED;</span><br><span style="color: hsl(0, 100%, 40%);">-              if (state->registration_failures < 3) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   state->registration_failures ++;</span><br><span style="color: hsl(0, 100%, 40%);">-                     return oap_client_register(state, msg_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-              }</span><br><span style="color: hsl(0, 100%, 40%);">-               return -11;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     case OAP_MSGT_REGISTER_REQUEST:</span><br><span style="color: hsl(0, 100%, 40%);">- case OAP_MSGT_CHALLENGE_RESULT:</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGP(DLOAP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-              "Received invalid OAP message type for OAP client side: %d\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                (int)oap_msg.message_type);</span><br><span style="color: hsl(0, 100%, 40%);">-                return -12;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     default:</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DLOAP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-              "Unknown OAP message type: %d\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                     (int)oap_msg.message_type);</span><br><span style="color: hsl(0, 100%, 40%);">-                return -13;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span>diff --git a/src/libcommon/gsup_client.c b/src/libcommon/gsup_client.c</span><br><span>index 89a9f70..0520045 100644</span><br><span>--- a/src/libcommon/gsup_client.c</span><br><span>+++ b/src/libcommon/gsup_client.c</span><br><span>@@ -116,7 +116,7 @@</span><br><span> {</span><br><span>       struct msgb *msg_tx;</span><br><span>         int rc;</span><br><span style="color: hsl(0, 100%, 40%);">- rc = oap_client_register(&gsupc->oap_state, &msg_tx);</span><br><span style="color: hsl(120, 100%, 40%);">+      rc = osmo_oap_client_register(&gsupc->oap_state, &msg_tx);</span><br><span> </span><br><span>    if ((rc < 0) || (!msg_tx)) {</span><br><span>              LOGP(DLGSUP, LOGL_ERROR, "GSUP OAP set up, but cannot register.\n");</span><br><span>@@ -138,7 +138,7 @@</span><br><span>         if (up) {</span><br><span>            start_test_procedure(gsupc);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                if (gsupc->oap_state.state == OAP_INITIALIZED)</span><br><span style="color: hsl(120, 100%, 40%);">+             if (gsupc->osmo_oap_state.state == OSMO_OAP_INITIALIZED)</span><br><span>                  gsup_client_oap_register(gsupc);</span><br><span> </span><br><span>                 osmo_timer_del(&gsupc->connect_timer);</span><br><span>@@ -156,7 +156,7 @@</span><br><span>  struct msgb *msg_tx;</span><br><span> </span><br><span>     /* If the oap_state is disabled, this will reject the messages. */</span><br><span style="color: hsl(0, 100%, 40%);">-      rc = oap_client_handle(&gsupc->oap_state, msg_rx, &msg_tx);</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = osmo_oap_client_handle(&gsupc->oap_state, msg_rx, &msg_tx);</span><br><span>  msgb_free(msg_rx);</span><br><span>   if (rc < 0)</span><br><span>               return rc;</span><br><span>@@ -269,7 +269,7 @@</span><br><span>                                    const char *ip_addr,</span><br><span>                                 unsigned int tcp_port,</span><br><span>                                       gsup_client_read_cb_t read_cb,</span><br><span style="color: hsl(0, 100%, 40%);">-                                  struct oap_client_config *oapc_config)</span><br><span style="color: hsl(120, 100%, 40%);">+                                struct osmo_oap_client_config *oapc_config)</span><br><span> {</span><br><span>      struct gsup_client *gsupc;</span><br><span>   int rc;</span><br><span>@@ -284,7 +284,7 @@</span><br><span>        OSMO_ASSERT(gsupc->unit_name);</span><br><span> </span><br><span>        /* a NULL oapc_config will mark oap_state disabled. */</span><br><span style="color: hsl(0, 100%, 40%);">-  rc = oap_client_init(oapc_config, &gsupc->oap_state);</span><br><span style="color: hsl(120, 100%, 40%);">+  rc = osmo_oap_client_init(oapc_config, &gsupc->oap_state);</span><br><span>    if (rc != 0)</span><br><span>                 goto failed;</span><br><span> </span><br><span>diff --git a/src/libcommon/oap_client.c b/src/libcommon/oap_client.c</span><br><span>deleted file mode 100644</span><br><span>index 9ff84a6..0000000</span><br><span>--- a/src/libcommon/oap_client.c</span><br><span>+++ /dev/null</span><br><span>@@ -1,280 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/* Osmocom Authentication Protocol API */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* (C) 2015 by Sysmocom s.f.m.c. GmbH</span><br><span style="color: hsl(0, 100%, 40%);">- * All Rights Reserved</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * Author: Neels Hofmeyr</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(0, 100%, 40%);">- * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(0, 100%, 40%);">- * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(0, 100%, 40%);">- * (at your option) any later version.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(0, 100%, 40%);">- * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(0, 100%, 40%);">- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(0, 100%, 40%);">- * GNU Affero General Public License for more details.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(0, 100%, 40%);">- * along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <string.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <errno.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/utils.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/crypt/auth.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/gsm/oap.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/sgsn/oap_client.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/sgsn/debug.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int oap_client_init(struct oap_client_config *config,</span><br><span style="color: hsl(0, 100%, 40%);">-               struct oap_client_state *state)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    OSMO_ASSERT(state->state == OAP_UNINITIALIZED);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      if (!config)</span><br><span style="color: hsl(0, 100%, 40%);">-            goto disable;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (config->client_id == 0)</span><br><span style="color: hsl(0, 100%, 40%);">-          goto disable;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (config->secret_k_present == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGP(DLOAP, LOGL_NOTICE, "OAP: client ID set, but secret K missing.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-              goto disable;</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (config->secret_opc_present == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-               LOGP(DLOAP, LOGL_NOTICE, "OAP: client ID set, but secret OPC missing.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-            goto disable;</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       state->client_id = config->client_id;</span><br><span style="color: hsl(0, 100%, 40%);">-     memcpy(state->secret_k, config->secret_k, sizeof(state->secret_k));</span><br><span style="color: hsl(0, 100%, 40%);">-    memcpy(state->secret_opc, config->secret_opc, sizeof(state->secret_opc));</span><br><span style="color: hsl(0, 100%, 40%);">-      state->state = OAP_INITIALIZED;</span><br><span style="color: hsl(0, 100%, 40%);">-      return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-disable:</span><br><span style="color: hsl(0, 100%, 40%);">-       state->state = OAP_DISABLED;</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* From the given state and received RAND and AUTN octets, validate the</span><br><span style="color: hsl(0, 100%, 40%);">- * server's authenticity and formulate the matching milenage reply octets in</span><br><span style="color: hsl(0, 100%, 40%);">- * *tx_xres. The state is not modified.</span><br><span style="color: hsl(0, 100%, 40%);">- * On success, and if tx_res is not NULL, exactly 8 octets will be written to</span><br><span style="color: hsl(0, 100%, 40%);">- * *tx_res. If not NULL, tx_res must point at allocated memory of at least 8</span><br><span style="color: hsl(0, 100%, 40%);">- * octets. The caller will want to send XRES back to the server in a challenge</span><br><span style="color: hsl(0, 100%, 40%);">- * response message and update the state.</span><br><span style="color: hsl(0, 100%, 40%);">- * Return 0 on success; -1 if OAP is disabled; -2 if rx_random and rx_autn fail</span><br><span style="color: hsl(0, 100%, 40%);">- * the authentication check; -3 for any other errors. */</span><br><span style="color: hsl(0, 100%, 40%);">-static int oap_evaluate_challenge(const struct oap_client_state *state,</span><br><span style="color: hsl(0, 100%, 40%);">-                            const uint8_t *rx_random,</span><br><span style="color: hsl(0, 100%, 40%);">-                               const uint8_t *rx_autn,</span><br><span style="color: hsl(0, 100%, 40%);">-                                 uint8_t *tx_xres)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    struct osmo_auth_vector vec;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    struct osmo_sub_auth_data auth = {</span><br><span style="color: hsl(0, 100%, 40%);">-              .type           = OSMO_AUTH_TYPE_UMTS,</span><br><span style="color: hsl(0, 100%, 40%);">-          .algo           = OSMO_AUTH_ALG_MILENAGE,</span><br><span style="color: hsl(0, 100%, 40%);">-       };</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      osmo_static_assert(sizeof(((struct osmo_sub_auth_data*)0)->u.umts.k)</span><br><span style="color: hsl(0, 100%, 40%);">-                    == sizeof(state->secret_k), _secret_k_size_match);</span><br><span style="color: hsl(0, 100%, 40%);">-        osmo_static_assert(sizeof(((struct osmo_sub_auth_data*)0)->u.umts.opc)</span><br><span style="color: hsl(0, 100%, 40%);">-                          == sizeof(state->secret_opc), _secret_opc_size_match);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    switch (state->state) {</span><br><span style="color: hsl(0, 100%, 40%);">-      case OAP_UNINITIALIZED:</span><br><span style="color: hsl(0, 100%, 40%);">- case OAP_DISABLED:</span><br><span style="color: hsl(0, 100%, 40%);">-              return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      default:</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       memcpy(auth.u.umts.k, state->secret_k, sizeof(auth.u.umts.k));</span><br><span style="color: hsl(0, 100%, 40%);">-       memcpy(auth.u.umts.opc, state->secret_opc, sizeof(auth.u.umts.opc));</span><br><span style="color: hsl(0, 100%, 40%);">- memset(auth.u.umts.amf, '\0', sizeof(auth.u.umts.amf));</span><br><span style="color: hsl(0, 100%, 40%);">- auth.u.umts.sqn = 41; /* TODO use incrementing sequence nr */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   memset(&vec, 0, sizeof(vec));</span><br><span style="color: hsl(0, 100%, 40%);">-       osmo_auth_gen_vec(&vec, &auth, rx_random);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      if (vec.res_len != 8) {</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGP(DLOAP, LOGL_ERROR, "OAP: Expected XRES to be 8 octets, got %d\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                     vec.res_len);</span><br><span style="color: hsl(0, 100%, 40%);">-              return -3;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (osmo_constant_time_cmp(vec.autn, rx_autn, sizeof(vec.autn)) != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGP(DLOAP, LOGL_ERROR, "OAP: AUTN mismatch!\n");</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGP(DLOAP, LOGL_INFO, "OAP: AUTN from server: %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-              osmo_hexdump_nospc(rx_autn, sizeof(vec.autn)));</span><br><span style="color: hsl(0, 100%, 40%);">-            LOGP(DLOAP, LOGL_INFO, "OAP: AUTN expected:    %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-              osmo_hexdump_nospc(vec.autn, sizeof(vec.autn)));</span><br><span style="color: hsl(0, 100%, 40%);">-           return -2;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (tx_xres != NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-            memcpy(tx_xres, vec.res, 8);</span><br><span style="color: hsl(0, 100%, 40%);">-    return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct msgb *oap_client_encoded(const struct osmo_oap_message *oap_msg)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      struct msgb *msg = msgb_alloc_headroom(1000, 64, __func__);</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_ASSERT(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-       osmo_oap_encode(msg, oap_msg);</span><br><span style="color: hsl(0, 100%, 40%);">-  return msg;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Create a new msgb containing an OAP registration message.</span><br><span style="color: hsl(0, 100%, 40%);">- * On error, return NULL. */</span><br><span style="color: hsl(0, 100%, 40%);">-static struct msgb* oap_msg_register(uint16_t client_id)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   struct osmo_oap_message oap_msg = {0};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  if (client_id < 1) {</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGP(DLOAP, LOGL_ERROR, "OAP: Invalid client ID: %d\n", client_id);</span><br><span style="color: hsl(0, 100%, 40%);">-           return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       oap_msg.message_type = OAP_MSGT_REGISTER_REQUEST;</span><br><span style="color: hsl(0, 100%, 40%);">-       oap_msg.client_id = client_id;</span><br><span style="color: hsl(0, 100%, 40%);">-  return oap_client_encoded(&oap_msg);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int oap_client_register(struct oap_client_state *state, struct msgb **msg_tx)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- *msg_tx = oap_msg_register(state->client_id);</span><br><span style="color: hsl(0, 100%, 40%);">-        if (!(*msg_tx))</span><br><span style="color: hsl(0, 100%, 40%);">-         return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      state->state = OAP_REQUESTED_CHALLENGE;</span><br><span style="color: hsl(0, 100%, 40%);">-      return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Create a new msgb containing an OAP challenge response message.</span><br><span style="color: hsl(0, 100%, 40%);">- * xres must point at 8 octets to return as challenge response.</span><br><span style="color: hsl(0, 100%, 40%);">- * On error, return NULL. */</span><br><span style="color: hsl(0, 100%, 40%);">-static struct msgb* oap_msg_challenge_response(uint8_t *xres)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   struct osmo_oap_message oap_reply = {0};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        oap_reply.message_type = OAP_MSGT_CHALLENGE_RESULT;</span><br><span style="color: hsl(0, 100%, 40%);">-     memcpy(oap_reply.xres, xres, sizeof(oap_reply.xres));</span><br><span style="color: hsl(0, 100%, 40%);">-   oap_reply.xres_present = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-     return oap_client_encoded(&oap_reply);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int handle_challenge(struct oap_client_state *state,</span><br><span style="color: hsl(0, 100%, 40%);">-                      struct osmo_oap_message *oap_rx,</span><br><span style="color: hsl(0, 100%, 40%);">-                        struct msgb **msg_tx)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      int rc;</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t xres[8];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        if (!(oap_rx->rand_present && oap_rx->autn_present)) {</span><br><span style="color: hsl(0, 100%, 40%);">-            LOGP(DLOAP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-              "OAP challenge incomplete (rand_present: %d, autn_present: %d)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                    oap_rx->rand_present, oap_rx->autn_present);</span><br><span style="color: hsl(0, 100%, 40%);">-         rc = -2;</span><br><span style="color: hsl(0, 100%, 40%);">-                goto failure;</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       rc = oap_evaluate_challenge(state,</span><br><span style="color: hsl(0, 100%, 40%);">-                                  oap_rx->rand,</span><br><span style="color: hsl(0, 100%, 40%);">-                                oap_rx->autn,</span><br><span style="color: hsl(0, 100%, 40%);">-                                xres);</span><br><span style="color: hsl(0, 100%, 40%);">-      if (rc < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-          goto failure;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   *msg_tx = oap_msg_challenge_response(xres);</span><br><span style="color: hsl(0, 100%, 40%);">-     if ((*msg_tx) == NULL) {</span><br><span style="color: hsl(0, 100%, 40%);">-                rc = -1;</span><br><span style="color: hsl(0, 100%, 40%);">-                goto failure;</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       state->state = OAP_SENT_CHALLENGE_RESULT;</span><br><span style="color: hsl(0, 100%, 40%);">-    return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-failure:</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(rc < 0);</span><br><span style="color: hsl(0, 100%, 40%);">- state->state = OAP_INITIALIZED;</span><br><span style="color: hsl(0, 100%, 40%);">-      return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int oap_client_handle(struct oap_client_state *state,</span><br><span style="color: hsl(0, 100%, 40%);">-                      const struct msgb *msg_rx, struct msgb **msg_tx)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t *data = msgb_l2(msg_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-        size_t data_len = msgb_l2len(msg_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-   struct osmo_oap_message oap_msg = {0};</span><br><span style="color: hsl(0, 100%, 40%);">-  int rc = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     *msg_tx = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(data);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      rc = osmo_oap_decode(&oap_msg, data, data_len);</span><br><span style="color: hsl(0, 100%, 40%);">-     if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DLOAP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-              "Decoding OAP message failed with error '%s' (%d)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                 get_value_string(gsm48_gmm_cause_names, -rc), -rc);</span><br><span style="color: hsl(0, 100%, 40%);">-                return -10;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       switch (state->state) {</span><br><span style="color: hsl(0, 100%, 40%);">-      case OAP_UNINITIALIZED:</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGP(DLOAP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-              "Received OAP message %d, but the OAP client is"</span><br><span style="color: hsl(0, 100%, 40%);">-              " not initialized\n", oap_msg.message_type);</span><br><span style="color: hsl(0, 100%, 40%);">-             return -ENOTCONN;</span><br><span style="color: hsl(0, 100%, 40%);">-       case OAP_DISABLED:</span><br><span style="color: hsl(0, 100%, 40%);">-              LOGP(DLOAP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-              "Received OAP message %d, but the OAP client is"</span><br><span style="color: hsl(0, 100%, 40%);">-              " disabled\n", oap_msg.message_type);</span><br><span style="color: hsl(0, 100%, 40%);">-            return -ENOTCONN;</span><br><span style="color: hsl(0, 100%, 40%);">-       default:</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       switch (oap_msg.message_type) {</span><br><span style="color: hsl(0, 100%, 40%);">- case OAP_MSGT_CHALLENGE_REQUEST:</span><br><span style="color: hsl(0, 100%, 40%);">-                return handle_challenge(state, &oap_msg, msg_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   case OAP_MSGT_REGISTER_RESULT:</span><br><span style="color: hsl(0, 100%, 40%);">-          /* successfully registered */</span><br><span style="color: hsl(0, 100%, 40%);">-           state->state = OAP_REGISTERED;</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  case OAP_MSGT_REGISTER_ERROR:</span><br><span style="color: hsl(0, 100%, 40%);">-           LOGP(DLOAP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-              "OAP registration failed\n");</span><br><span style="color: hsl(0, 100%, 40%);">-            state->state = OAP_INITIALIZED;</span><br><span style="color: hsl(0, 100%, 40%);">-              if (state->registration_failures < 3) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   state->registration_failures ++;</span><br><span style="color: hsl(0, 100%, 40%);">-                     return oap_client_register(state, msg_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-              }</span><br><span style="color: hsl(0, 100%, 40%);">-               return -11;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     case OAP_MSGT_REGISTER_REQUEST:</span><br><span style="color: hsl(0, 100%, 40%);">- case OAP_MSGT_CHALLENGE_RESULT:</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGP(DLOAP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-              "Received invalid OAP message type for OAP client side: %d\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                (int)oap_msg.message_type);</span><br><span style="color: hsl(0, 100%, 40%);">-                return -12;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     default:</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DLOAP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-              "Unknown OAP message type: %d\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                     (int)oap_msg.message_type);</span><br><span style="color: hsl(0, 100%, 40%);">-                return -13;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span>diff --git a/tests/Makefile.am b/tests/Makefile.am</span><br><span>index f6a1efc..035cfb0 100644</span><br><span>--- a/tests/Makefile.am</span><br><span>+++ b/tests/Makefile.am</span><br><span>@@ -3,7 +3,6 @@</span><br><span>        gbproxy \</span><br><span>    gtphub \</span><br><span>     sgsn \</span><br><span style="color: hsl(0, 100%, 40%);">-  oap \</span><br><span>        xid \</span><br><span>        sndcp_xid \</span><br><span>  slhc \</span><br><span>diff --git a/tests/oap/Makefile.am b/tests/oap/Makefile.am</span><br><span>deleted file mode 100644</span><br><span>index ccc6d8c..0000000</span><br><span>--- a/tests/oap/Makefile.am</span><br><span>+++ /dev/null</span><br><span>@@ -1,32 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-AM_CPPFLAGS = \</span><br><span style="color: hsl(0, 100%, 40%);">- $(all_includes) \</span><br><span style="color: hsl(0, 100%, 40%);">-       -I$(top_srcdir)/include \</span><br><span style="color: hsl(0, 100%, 40%);">-       $(NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-AM_CFLAGS = \</span><br><span style="color: hsl(0, 100%, 40%);">-    -Wall \</span><br><span style="color: hsl(0, 100%, 40%);">- -ggdb3 \</span><br><span style="color: hsl(0, 100%, 40%);">-        $(LIBOSMOCORE_CFLAGS) \</span><br><span style="color: hsl(0, 100%, 40%);">- $(LIBOSMOGSM_CFLAGS) \</span><br><span style="color: hsl(0, 100%, 40%);">-  $(NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-EXTRA_DIST = \</span><br><span style="color: hsl(0, 100%, 40%);">-   oap_client_test.ok \</span><br><span style="color: hsl(0, 100%, 40%);">-    oap_client_test.err \</span><br><span style="color: hsl(0, 100%, 40%);">-   $(NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-noinst_PROGRAMS = \</span><br><span style="color: hsl(0, 100%, 40%);">-      oap_client_test \</span><br><span style="color: hsl(0, 100%, 40%);">-       $(NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-oap_client_test_SOURCES = \</span><br><span style="color: hsl(0, 100%, 40%);">-      oap_client_test.c \</span><br><span style="color: hsl(0, 100%, 40%);">-     $(NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-oap_client_test_LDADD = \</span><br><span style="color: hsl(0, 100%, 40%);">-        $(top_builddir)/src/gprs/gprs_utils.o \</span><br><span style="color: hsl(0, 100%, 40%);">- $(top_builddir)/src/gprs/oap_client.o \</span><br><span style="color: hsl(0, 100%, 40%);">- $(LIBOSMOCORE_LIBS) \</span><br><span style="color: hsl(0, 100%, 40%);">-   $(LIBOSMOGSM_LIBS) \</span><br><span style="color: hsl(0, 100%, 40%);">-    -lrt</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>diff --git a/tests/oap/oap_client_test.c b/tests/oap/oap_client_test.c</span><br><span>deleted file mode 100644</span><br><span>index 87d2070..0000000</span><br><span>--- a/tests/oap/oap_client_test.c</span><br><span>+++ /dev/null</span><br><span>@@ -1,271 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/* Test Osmocom Authentication Protocol */</span><br><span style="color: hsl(0, 100%, 40%);">-/*</span><br><span style="color: hsl(0, 100%, 40%);">- * (C) 2015 by sysmocom s.f.m.c. GmbH</span><br><span style="color: hsl(0, 100%, 40%);">- * All Rights Reserved</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(0, 100%, 40%);">- * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(0, 100%, 40%);">- * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(0, 100%, 40%);">- * (at your option) any later version.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(0, 100%, 40%);">- * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(0, 100%, 40%);">- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(0, 100%, 40%);">- * GNU Affero General Public License for more details.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(0, 100%, 40%);">- * along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/application.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/gsm/oap.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/sgsn/debug.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/sgsn/oap_client.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <stdio.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <string.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void test_oap_api(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        printf("Testing OAP API\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  struct oap_client_config _config;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct oap_client_config *config = &_config;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        struct oap_client_state _state;</span><br><span style="color: hsl(0, 100%, 40%);">- struct oap_client_state *state = &_state;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   struct osmo_oap_message oap_rx;</span><br><span style="color: hsl(0, 100%, 40%);">- struct msgb *msg_rx;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    struct osmo_oap_message oap_tx;</span><br><span style="color: hsl(0, 100%, 40%);">- struct msgb *msg_tx;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    memset(config, 0, sizeof(*config));</span><br><span style="color: hsl(0, 100%, 40%);">-     memset(state, 0, sizeof(*state));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(osmo_hexparse("0102030405060708090a0b0c0d0e0f10", config->secret_k, 16) == 16);</span><br><span style="color: hsl(0, 100%, 40%);">-        OSMO_ASSERT(osmo_hexparse("1112131415161718191a1b1c1d1e1f20", config->secret_opc, 16) == 16);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      fprintf(stderr, "- make sure filling with zeros means uninitialized\n");</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(state->state == OAP_UNINITIALIZED);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      fprintf(stderr, "- reject messages in uninitialized state\n");</span><br><span style="color: hsl(0, 100%, 40%);">-        memset(&oap_rx, 0, sizeof(oap_rx));</span><br><span style="color: hsl(0, 100%, 40%);">- state->client_id = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-        oap_rx.message_type = OAP_MSGT_REGISTER_ERROR;</span><br><span style="color: hsl(0, 100%, 40%);">-  msg_rx = oap_client_encoded(&oap_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) < 0);</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(state->state == OAP_UNINITIALIZED);</span><br><span style="color: hsl(0, 100%, 40%);">-      msgb_free(msg_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(!msg_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   fprintf(stderr, "- NULL config should disable\n");</span><br><span style="color: hsl(0, 100%, 40%);">-    OSMO_ASSERT( oap_client_init(NULL, state) == 0 );</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(state->state == OAP_DISABLED);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   fprintf(stderr, "- reject messages in disabled state\n");</span><br><span style="color: hsl(0, 100%, 40%);">-     memset(state, 0, sizeof(*state));</span><br><span style="color: hsl(0, 100%, 40%);">-       memset(&oap_rx, 0, sizeof(oap_rx));</span><br><span style="color: hsl(0, 100%, 40%);">- state->state = OAP_DISABLED;</span><br><span style="color: hsl(0, 100%, 40%);">- state->client_id = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-        oap_rx.message_type = OAP_MSGT_REGISTER_ERROR;</span><br><span style="color: hsl(0, 100%, 40%);">-  msg_rx = oap_client_encoded(&oap_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) < 0);</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(state->state == OAP_DISABLED);</span><br><span style="color: hsl(0, 100%, 40%);">-   msgb_free(msg_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(!msg_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   fprintf(stderr, "- invalid client_id and shared secret\n");</span><br><span style="color: hsl(0, 100%, 40%);">-   memset(state, 0, sizeof(*state));</span><br><span style="color: hsl(0, 100%, 40%);">-       config->client_id = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       config->secret_k_present = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-        config->secret_opc_present = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT( oap_client_init(config, state) == 0 );</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_ASSERT(state->state == OAP_DISABLED);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   fprintf(stderr, "- reset state\n");</span><br><span style="color: hsl(0, 100%, 40%);">-   memset(state, 0, sizeof(*state));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       fprintf(stderr, "- only client_id is invalid\n");</span><br><span style="color: hsl(0, 100%, 40%);">-     config->client_id = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       config->secret_k_present = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-        config->secret_opc_present = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT( oap_client_init(config, state) == 0 );</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_ASSERT(state->state == OAP_DISABLED);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   memset(state, 0, sizeof(*state));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       fprintf(stderr, "- valid id, but omitted shared_secret (1/2)\n");</span><br><span style="color: hsl(0, 100%, 40%);">-     config->client_id = 12345;</span><br><span style="color: hsl(0, 100%, 40%);">-   config->secret_k_present = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-        config->secret_opc_present = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT( oap_client_init(config, state) == 0 );</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_ASSERT(state->state == OAP_DISABLED);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   memset(state, 0, sizeof(*state));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       fprintf(stderr, "- valid id, but omitted shared_secret (2/2)\n");</span><br><span style="color: hsl(0, 100%, 40%);">-     config->client_id = 12345;</span><br><span style="color: hsl(0, 100%, 40%);">-   config->secret_k_present = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-        config->secret_opc_present = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT( oap_client_init(config, state) == 0 );</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_ASSERT(state->state == OAP_DISABLED);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   memset(state, 0, sizeof(*state));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       fprintf(stderr, "- mint configuration\n");</span><br><span style="color: hsl(0, 100%, 40%);">-    config->client_id = 12345;</span><br><span style="color: hsl(0, 100%, 40%);">-   config->secret_k_present = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-        config->secret_opc_present = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-      /*config->secret_* buffers are still set from the top */</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_ASSERT( oap_client_init(config, state) == 0 );</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_ASSERT(state->state == OAP_INITIALIZED);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        fprintf(stderr, "- Missing challenge data\n");</span><br><span style="color: hsl(0, 100%, 40%);">-        memset(&oap_rx, 0, sizeof(oap_rx));</span><br><span style="color: hsl(0, 100%, 40%);">- oap_rx.message_type = OAP_MSGT_CHALLENGE_REQUEST;</span><br><span style="color: hsl(0, 100%, 40%);">-       oap_rx.rand_present = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-        oap_rx.autn_present = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-        msg_rx = oap_client_encoded(&oap_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == -2);</span><br><span style="color: hsl(0, 100%, 40%);">-       msgb_free(msg_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(!msg_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   fprintf(stderr, "- AUTN missing\n");</span><br><span style="color: hsl(0, 100%, 40%);">-  osmo_hexparse("0102030405060708090a0b0c0d0e0f10",</span><br><span style="color: hsl(0, 100%, 40%);">-                   oap_rx.rand, 16);</span><br><span style="color: hsl(0, 100%, 40%);">- oap_rx.rand_present = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-        msg_rx = oap_client_encoded(&oap_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == -2);</span><br><span style="color: hsl(0, 100%, 40%);">-       msgb_free(msg_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(!msg_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   fprintf(stderr, "- RAND missing\n");</span><br><span style="color: hsl(0, 100%, 40%);">-  oap_rx.rand_present = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-        osmo_hexparse("cec4e3848a33000086781158ca40f136",</span><br><span style="color: hsl(0, 100%, 40%);">-                   oap_rx.autn, 16);</span><br><span style="color: hsl(0, 100%, 40%);">- oap_rx.autn_present = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-        msg_rx = oap_client_encoded(&oap_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == -2);</span><br><span style="color: hsl(0, 100%, 40%);">-       msgb_free(msg_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(!msg_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   fprintf(stderr, "- wrong autn (by one bit)\n");</span><br><span style="color: hsl(0, 100%, 40%);">-       osmo_hexparse("0102030405060708090a0b0c0d0e0f10",</span><br><span style="color: hsl(0, 100%, 40%);">-                   oap_rx.rand, 16);</span><br><span style="color: hsl(0, 100%, 40%);">- osmo_hexparse("dec4e3848a33000086781158ca40f136",</span><br><span style="color: hsl(0, 100%, 40%);">-                   oap_rx.autn, 16);</span><br><span style="color: hsl(0, 100%, 40%);">- oap_rx.rand_present = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-        oap_rx.autn_present = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-        msg_rx = oap_client_encoded(&oap_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == -2);</span><br><span style="color: hsl(0, 100%, 40%);">-       msgb_free(msg_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(!msg_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   fprintf(stderr, "- all data correct\n");</span><br><span style="color: hsl(0, 100%, 40%);">-      osmo_hexparse("cec4e3848a33000086781158ca40f136",</span><br><span style="color: hsl(0, 100%, 40%);">-                   oap_rx.autn, 16);</span><br><span style="color: hsl(0, 100%, 40%);">- msg_rx = oap_client_encoded(&oap_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       fprintf(stderr, "- but refuse to evaluate in uninitialized state\n");</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(state->state == OAP_INITIALIZED);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        state->state = OAP_UNINITIALIZED;</span><br><span style="color: hsl(0, 100%, 40%);">-    OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) < 0);</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(!msg_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   state->state = OAP_DISABLED;</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) < 0);</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(!msg_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   state->state = OAP_INITIALIZED;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      fprintf(stderr, "- now everything is correct\n");</span><br><span style="color: hsl(0, 100%, 40%);">-     /* a successful return value here indicates correct autn */</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == 0);</span><br><span style="color: hsl(0, 100%, 40%);">-        msgb_free(msg_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      fprintf(stderr, "- Expect the challenge response in msg_tx\n");</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(msg_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-    OSMO_ASSERT(osmo_oap_decode(&oap_tx, msg_tx->data, msg_tx->len) == 0);</span><br><span style="color: hsl(0, 100%, 40%);">-        OSMO_ASSERT(oap_tx.message_type == OAP_MSGT_CHALLENGE_RESULT);</span><br><span style="color: hsl(0, 100%, 40%);">-  OSMO_ASSERT(strcmp("e2d05b598c61d9ba",</span><br><span style="color: hsl(0, 100%, 40%);">-                           osmo_hexdump_nospc(oap_tx.xres, sizeof(oap_tx.xres)))</span><br><span style="color: hsl(0, 100%, 40%);">-                    == 0);</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(state->state == OAP_SENT_CHALLENGE_RESULT);</span><br><span style="color: hsl(0, 100%, 40%);">-      msgb_free(msg_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-      msg_tx = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     struct oap_client_state saved_state = _state;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   fprintf(stderr, "- Receive registration error for the first time.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        memset(&oap_rx, 0, sizeof(oap_rx));</span><br><span style="color: hsl(0, 100%, 40%);">- oap_rx.message_type = OAP_MSGT_REGISTER_ERROR;</span><br><span style="color: hsl(0, 100%, 40%);">-  oap_rx.cause = GMM_CAUSE_PROTO_ERR_UNSPEC;</span><br><span style="color: hsl(0, 100%, 40%);">-      msg_rx = oap_client_encoded(&oap_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(state->registration_failures == 0);</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == 0);</span><br><span style="color: hsl(0, 100%, 40%);">-        OSMO_ASSERT(state->registration_failures == 1);</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(msg_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-    OSMO_ASSERT(osmo_oap_decode(&oap_tx, msg_tx->data, msg_tx->len) == 0);</span><br><span style="color: hsl(0, 100%, 40%);">-        OSMO_ASSERT(oap_tx.message_type == OAP_MSGT_REGISTER_REQUEST);</span><br><span style="color: hsl(0, 100%, 40%);">-  OSMO_ASSERT(state->state == OAP_REQUESTED_CHALLENGE);</span><br><span style="color: hsl(0, 100%, 40%);">-        msgb_free(msg_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-      msg_tx = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     fprintf(stderr, "- Receive registration error for the Nth time.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-  state->registration_failures = 999;</span><br><span style="color: hsl(0, 100%, 40%);">-  OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == -11);</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(!msg_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-   OSMO_ASSERT(state->state == OAP_INITIALIZED);</span><br><span style="color: hsl(0, 100%, 40%);">-        msgb_free(msg_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-      msg_tx = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     msgb_free(msg_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      fprintf(stderr, "- Registration success\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  _state = saved_state;</span><br><span style="color: hsl(0, 100%, 40%);">-   memset(&oap_rx, 0, sizeof(oap_rx));</span><br><span style="color: hsl(0, 100%, 40%);">- oap_rx.message_type = OAP_MSGT_REGISTER_RESULT;</span><br><span style="color: hsl(0, 100%, 40%);">- msg_rx = oap_client_encoded(&oap_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == 0);</span><br><span style="color: hsl(0, 100%, 40%);">-        OSMO_ASSERT(!msg_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-   OSMO_ASSERT(state->state == OAP_REGISTERED);</span><br><span style="color: hsl(0, 100%, 40%);">- msgb_free(msg_rx);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct log_info_cat oap_client_test_categories[] = {</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct log_info info = {</span><br><span style="color: hsl(0, 100%, 40%);">- .cat = oap_client_test_categories,</span><br><span style="color: hsl(0, 100%, 40%);">-      .num_cat = ARRAY_SIZE(oap_client_test_categories),</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int main(int argc, char **argv)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    void *ctx = talloc_named_const(NULL, 0, "oap_client_test");</span><br><span style="color: hsl(0, 100%, 40%);">-   msgb_talloc_ctx_init(ctx, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-   osmo_init_logging2(ctx, &info);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_ASSERT(osmo_stderr_target);</span><br><span style="color: hsl(0, 100%, 40%);">-        log_set_use_color(osmo_stderr_target, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-       log_set_print_timestamp(osmo_stderr_target, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- log_set_print_filename(osmo_stderr_target, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-  log_set_print_category(osmo_stderr_target, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-  log_parse_category_mask(osmo_stderr_target, "DLOAP,1");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       test_oap_api();</span><br><span style="color: hsl(0, 100%, 40%);">- printf("Done\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>diff --git a/tests/oap/oap_client_test.err b/tests/oap/oap_client_test.err</span><br><span>deleted file mode 100644</span><br><span>index 62ddc9e..0000000</span><br><span>--- a/tests/oap/oap_client_test.err</span><br><span>+++ /dev/null</span><br><span>@@ -1,35 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-- make sure filling with zeros means uninitialized</span><br><span style="color: hsl(0, 100%, 40%);">-- reject messages in uninitialized state</span><br><span style="color: hsl(0, 100%, 40%);">-DLOAP Received OAP message 5, but the OAP client is not initialized</span><br><span style="color: hsl(0, 100%, 40%);">-- NULL config should disable</span><br><span style="color: hsl(0, 100%, 40%);">-- reject messages in disabled state</span><br><span style="color: hsl(0, 100%, 40%);">-DLOAP Received OAP message 5, but the OAP client is disabled</span><br><span style="color: hsl(0, 100%, 40%);">-- invalid client_id and shared secret</span><br><span style="color: hsl(0, 100%, 40%);">-- reset state</span><br><span style="color: hsl(0, 100%, 40%);">-- only client_id is invalid</span><br><span style="color: hsl(0, 100%, 40%);">-- valid id, but omitted shared_secret (1/2)</span><br><span style="color: hsl(0, 100%, 40%);">-DLOAP OAP: client ID set, but secret K missing.</span><br><span style="color: hsl(0, 100%, 40%);">-- valid id, but omitted shared_secret (2/2)</span><br><span style="color: hsl(0, 100%, 40%);">-DLOAP OAP: client ID set, but secret OPC missing.</span><br><span style="color: hsl(0, 100%, 40%);">-- mint configuration</span><br><span style="color: hsl(0, 100%, 40%);">-- Missing challenge data</span><br><span style="color: hsl(0, 100%, 40%);">-DLOAP OAP challenge incomplete (rand_present: 0, autn_present: 0)</span><br><span style="color: hsl(0, 100%, 40%);">-- AUTN missing</span><br><span style="color: hsl(0, 100%, 40%);">-DLOAP OAP challenge incomplete (rand_present: 1, autn_present: 0)</span><br><span style="color: hsl(0, 100%, 40%);">-- RAND missing</span><br><span style="color: hsl(0, 100%, 40%);">-DLOAP OAP challenge incomplete (rand_present: 0, autn_present: 1)</span><br><span style="color: hsl(0, 100%, 40%);">-- wrong autn (by one bit)</span><br><span style="color: hsl(0, 100%, 40%);">-DLOAP OAP: AUTN mismatch!</span><br><span style="color: hsl(0, 100%, 40%);">-DLOAP OAP: AUTN from server: dec4e3848a33000086781158ca40f136</span><br><span style="color: hsl(0, 100%, 40%);">-DLOAP OAP: AUTN expected:    cec4e3848a33000086781158ca40f136</span><br><span style="color: hsl(0, 100%, 40%);">-- all data correct</span><br><span style="color: hsl(0, 100%, 40%);">-- but refuse to evaluate in uninitialized state</span><br><span style="color: hsl(0, 100%, 40%);">-DLOAP Received OAP message 8, but the OAP client is not initialized</span><br><span style="color: hsl(0, 100%, 40%);">-DLOAP Received OAP message 8, but the OAP client is disabled</span><br><span style="color: hsl(0, 100%, 40%);">-- now everything is correct</span><br><span style="color: hsl(0, 100%, 40%);">-- Expect the challenge response in msg_tx</span><br><span style="color: hsl(0, 100%, 40%);">-- Receive registration error for the first time.</span><br><span style="color: hsl(0, 100%, 40%);">-DLOAP OAP registration failed</span><br><span style="color: hsl(0, 100%, 40%);">-- Receive registration error for the Nth time.</span><br><span style="color: hsl(0, 100%, 40%);">-DLOAP OAP registration failed</span><br><span style="color: hsl(0, 100%, 40%);">-- Registration success</span><br><span>diff --git a/tests/oap/oap_client_test.ok b/tests/oap/oap_client_test.ok</span><br><span>deleted file mode 100644</span><br><span>index 59108a7..0000000</span><br><span>--- a/tests/oap/oap_client_test.ok</span><br><span>+++ /dev/null</span><br><span>@@ -1,2 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-Testing OAP API</span><br><span style="color: hsl(0, 100%, 40%);">-Done</span><br><span>diff --git a/tests/testsuite.at b/tests/testsuite.at</span><br><span>index 81cd713..d30115e 100644</span><br><span>--- a/tests/testsuite.at</span><br><span>+++ b/tests/testsuite.at</span><br><span>@@ -20,14 +20,6 @@</span><br><span> AT_CHECK([$abs_top_builddir/tests/sgsn/sgsn_test], [], [expout], [ignore])</span><br><span> AT_CLEANUP</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-AT_SETUP([oap])</span><br><span style="color: hsl(0, 100%, 40%);">-AT_KEYWORDS([oap])</span><br><span style="color: hsl(0, 100%, 40%);">-AT_CHECK([test "$enable_oap_test" != no || exit 77])</span><br><span style="color: hsl(0, 100%, 40%);">-cat $abs_srcdir/oap/oap_client_test.ok > expout</span><br><span style="color: hsl(0, 100%, 40%);">-cat $abs_srcdir/oap/oap_client_test.err > experr</span><br><span style="color: hsl(0, 100%, 40%);">-AT_CHECK([$abs_top_builddir/tests/oap/oap_client_test], [], [expout], [experr])</span><br><span style="color: hsl(0, 100%, 40%);">-AT_CLEANUP</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> AT_SETUP([gtphub])</span><br><span> AT_KEYWORDS([gtphub])</span><br><span> AT_CHECK([test "$enable_gtphub_test" != no || exit 77])</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/10259">change 10259</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/10259"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-sgsn </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I7b194f98ef3f925b6178d8a8dbd9fcf2f0c6e132 </div>
<div style="display:none"> Gerrit-Change-Number: 10259 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Harald Welte <laforge@gnumonks.org> </div>