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
This commit is contained in:
parent
7b4e5b1390
commit
fca8a0a935
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
5
src/db.c
5
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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
14
src/hlr.c
14
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 */
|
||||
|
|
Loading…
Reference in New Issue