diff options
author | Oliver Smith <osmith@sysmocom.de> | 2020-05-06 11:25:29 +0200 |
---|---|---|
committer | Oliver Smith <osmith@sysmocom.de> | 2020-05-06 15:09:01 +0200 |
commit | fca8a0a93593e0fe1d616a1473ad7295c7092b43 (patch) | |
tree | 10f2baac43fcb5c5d2accbb97ba2f4cb2c4489ae | |
parent | 7b4e5b1390cad9087e5d8f7b8b3344b9e2c677fa (diff) |
src/hlr.c: resolve/scramble pseudo IMSI in GSUP
Resolve the pseudonymous IMSI to the real IMSI as soon as possible, when
a GSUP message arrives. Use the real IMSI internally in OsmoHLR, so the
existing logic does not need to be changed. Scramble the IMSI back to the
pseudonymous IMSI in one common place (gsup_server_send_req_response)
right before responding to GSUP messages.
Related: OS#4476
Change-Id: I400810f96efca7746dd4ba1bed666acaea425e8a
-rw-r--r-- | include/osmocom/gsupclient/gsup_req.h | 4 | ||||
-rw-r--r-- | include/osmocom/hlr/db.h | 1 | ||||
-rw-r--r-- | include/osmocom/hlr/imsi_pseudo.h | 1 | ||||
-rw-r--r-- | src/db.c | 5 | ||||
-rw-r--r-- | src/db_imsi_pseudo.c | 34 | ||||
-rw-r--r-- | src/gsup_server.c | 6 | ||||
-rw-r--r-- | src/hlr.c | 14 |
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); @@ -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", @@ -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 */ |