aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/gsupclient/gsup_req.h4
-rw-r--r--include/osmocom/hlr/db.h1
-rw-r--r--include/osmocom/hlr/imsi_pseudo.h1
-rw-r--r--src/db.c5
-rw-r--r--src/db_imsi_pseudo.c34
-rw-r--r--src/gsup_server.c6
-rw-r--r--src/hlr.c14
7 files changed, 65 insertions, 0 deletions
diff --git a/include/osmocom/gsupclient/gsup_req.h b/include/osmocom/gsupclient/gsup_req.h
index 2d3cf38..c219d00 100644
--- a/include/osmocom/gsupclient/gsup_req.h
+++ b/include/osmocom/gsupclient/gsup_req.h
@@ -80,6 +80,10 @@ struct osmo_gsup_req {
/* A decoded GSUP message still points into the received msgb. For a decoded osmo_gsup_message to remain valid,
* we also need to keep the msgb. */
struct msgb *msg;
+
+ /* The pseudonymous IMSI in gsup->imsi is replaced with the real IMSI right after receiving the message. A
+ * copy of the pseudonymous IMSI is stored here for the reply. */
+ char imsi_pseudo[OSMO_IMSI_BUF_SIZE];
};
struct osmo_gsup_req *osmo_gsup_req_new(void *ctx, const struct osmo_cni_peer_id *from_peer, struct msgb *msg,
diff --git a/include/osmocom/hlr/db.h b/include/osmocom/hlr/db.h
index abb7357..35357a6 100644
--- a/include/osmocom/hlr/db.h
+++ b/include/osmocom/hlr/db.h
@@ -37,6 +37,7 @@ enum stmt_idx {
DB_STMT_PSEUDO_INSERT,
DB_STMT_PSEUDO_DELETE,
DB_STMT_PSEUDO_NEXT,
+ DB_STMT_PSEUDO_RESOLVE,
_NUM_DB_STMT
};
diff --git a/include/osmocom/hlr/imsi_pseudo.h b/include/osmocom/hlr/imsi_pseudo.h
index e1118c3..329d1ba 100644
--- a/include/osmocom/hlr/imsi_pseudo.h
+++ b/include/osmocom/hlr/imsi_pseudo.h
@@ -17,3 +17,4 @@ int db_get_imsi_pseudo_data(struct db_context *dbc, int64_t subscr_id, struct im
int db_alloc_imsi_pseudo(struct db_context *dbc, int64_t subscr_id, const char *imsi_pseudo, int64_t imsi_pseudo_i);
int db_dealloc_imsi_pseudo(struct db_context *dbc, const char *imsi_pseudo);
int db_get_imsi_pseudo_next(struct db_context *dbc, char *imsi_pseudo);
+int db_get_imsi_pseudo_resolve(struct db_context *dbc, const char *imsi_pseudo, char *imsi);
diff --git a/src/db.c b/src/db.c
index 2949d2f..7ed05fc 100644
--- a/src/db.c
+++ b/src/db.c
@@ -102,6 +102,11 @@ static const char *stmt_sql[] = {
" WHERE imsi_pseudo IS NULL"
" ORDER BY RANDOM()"
" LIMIT 1",
+ [DB_STMT_PSEUDO_RESOLVE] =
+ "SELECT imsi"
+ " FROM subscriber"
+ " LEFT JOIN subscriber_imsi_pseudo ON subscriber_id = subscriber.id"
+ " WHERE imsi_pseudo = $imsi_pseudo",
};
static void sql3_error_log_cb(void *arg, int err_code, const char *msg)
diff --git a/src/db_imsi_pseudo.c b/src/db_imsi_pseudo.c
index d1c09ab..e6fd68f 100644
--- a/src/db_imsi_pseudo.c
+++ b/src/db_imsi_pseudo.c
@@ -141,3 +141,37 @@ int db_get_imsi_pseudo_next(struct db_context *dbc, char *imsi_pseudo)
db_remove_reset(stmt);
return ret;
}
+
+/*! Resolve a pseudo IMSI to the real IMSI.
+ * \param[in] dbc database context.
+ * \param[in] imsi_pseudo the IMSI to be resolved
+ * \param[out] imsi buffer with length GSM23003_IMSI_MAX_DIGITS+1.
+ * \returns 0: success, -1: no associated real IMSI, -2: SQL error. */
+int db_get_imsi_pseudo_resolve(struct db_context *dbc, const char *imsi_pseudo, char *imsi)
+{
+ sqlite3_stmt *stmt = dbc->stmt[DB_STMT_PSEUDO_RESOLVE];
+ int rc, ret=0;
+
+ if (!db_bind_text(stmt, "$imsi_pseudo", imsi_pseudo))
+ return -EIO;
+
+ rc = sqlite3_step(stmt);
+ switch (rc) {
+ case SQLITE_ROW:
+ /* Can't use copy_sqlite3_text_to_buf, as it assumes the wrong size for imsi_pseudo */
+ osmo_strlcpy(imsi, (const char *)sqlite3_column_text(stmt, 0), GSM23003_IMSI_MAX_DIGITS + 1);
+ break;
+ case SQLITE_DONE:
+ LOGP(DPSEUDO, LOGL_NOTICE, "cannot resolve pseudonymous IMSI '%s': no associated real IMSI found\n",
+ imsi_pseudo);
+ ret = -1;
+ break;
+ default:
+ LOGP(DPSEUDO, LOGL_ERROR, "cannot resolve pseudonymous IMSI '%s': SQL error: %d\n", imsi_pseudo, rc);
+ ret = -2;
+ break;
+ }
+
+ db_remove_reset(stmt);
+ return ret;
+}
diff --git a/src/gsup_server.c b/src/gsup_server.c
index 888507c..ca2ad5f 100644
--- a/src/gsup_server.c
+++ b/src/gsup_server.c
@@ -30,6 +30,7 @@
#include <osmocom/hlr/gsup_server.h>
#include <osmocom/hlr/gsup_router.h>
+#include <osmocom/hlr/logging.h>
#define LOG_GSUP_CONN(conn, level, fmt, args...) \
LOGP(DLGSUP, level, "GSUP peer %s: " fmt, \
@@ -95,6 +96,11 @@ static void gsup_server_send_req_response(struct osmo_gsup_req *req, struct osmo
return;
}
+ if (req->imsi_pseudo[0]) {
+ LOGP(DPSEUDO, LOGL_DEBUG, "pseudo IMSI scramble: '%s' => '%s'\n", response->imsi, req->imsi_pseudo);
+ strncpy(response->imsi, req->imsi_pseudo, sizeof(response->imsi));
+ }
+
rc = osmo_gsup_encode(msg, response);
if (rc) {
LOG_GSUP_REQ(req, LOGL_ERROR, "Unable to encode: {%s}\n",
diff --git a/src/hlr.c b/src/hlr.c
index e4d6c23..634312c 100644
--- a/src/hlr.c
+++ b/src/hlr.c
@@ -48,6 +48,7 @@
#include <osmocom/hlr/rand.h>
#include <osmocom/hlr/hlr_vty.h>
#include <osmocom/hlr/hlr_ussd.h>
+#include <osmocom/hlr/imsi_pseudo.h>
#include <osmocom/hlr/dgsm.h>
#include <osmocom/hlr/proxy.h>
#include <osmocom/hlr/lu_fsm.h>
@@ -512,6 +513,19 @@ static int read_cb(struct osmo_gsup_conn *conn, struct msgb *msg)
return 0;
}
+ /* Resolve pseudonymous IMSI */
+ if (g_hlr->imsi_pseudo) {
+ char imsi[OSMO_IMSI_BUF_SIZE];
+ if (db_get_imsi_pseudo_resolve(g_hlr->dbc, req->gsup.imsi, imsi) == 0) {
+ LOGP(DPSEUDO, LOGL_DEBUG, "pseudo IMSI resolve: '%s' => '%s'\n", req->gsup.imsi, imsi);
+ strncpy(req->imsi_pseudo, req->gsup.imsi, sizeof(req->imsi_pseudo));
+ strncpy((char *)req->gsup.imsi, imsi, sizeof(req->gsup.imsi));
+ } else {
+ osmo_gsup_req_respond_err(req, GMM_CAUSE_IMSI_UNKNOWN, "pseudonymous IMSI unknown");
+ return -1;
+ }
+ }
+
/* HLR related messages that are handled at this HLR instance */
switch (req->gsup.message_type) {
/* requests sent to us */