diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/db.c | 2 | ||||
-rw-r--r-- | src/db.h | 5 | ||||
-rw-r--r-- | src/db_auc.c | 16 | ||||
-rw-r--r-- | src/db_test.c | 2 | ||||
-rw-r--r-- | src/gsup_server.c | 45 | ||||
-rw-r--r-- | src/gsup_server.h | 2 | ||||
-rw-r--r-- | src/hlr.c | 3 |
7 files changed, 64 insertions, 11 deletions
@@ -29,7 +29,7 @@ static const char *stmt_sql[] = { [SEL_BY_IMSI] = "SELECT id,imsi,msisdn,vlr_number,sgsn_number,sgsn_address,periodic_lu_tmr,periodic_rau_tau_tmr,nam_cs,nam_ps,lmsi,ms_purged_cs,ms_purged_ps FROM subscriber WHERE imsi = ?", [UPD_VLR_BY_ID] = "UPDATE subscriber SET vlr_number = ? WHERE id = ?", [UPD_SGSN_BY_ID] = "UPDATE subscriber SET sgsn_number = ? WHERE id = ?", - [AUC_BY_IMSI] = "SELECT id, algo_id_2g, ki, algo_id_3g, k, op, opc, sqn FROM subscriber LEFT JOIN auc_2g ON auc_2g.subscriber_id = subscriber.id LEFT JOIN auc_3g ON auc_3g.subscriber_id = subscriber.id WHERE imsi = ?", + [AUC_BY_IMSI] = "SELECT id, algo_id_2g, ki, algo_id_3g, k, op, opc, sqn, ind_bitlen FROM subscriber LEFT JOIN auc_2g ON auc_2g.subscriber_id = subscriber.id LEFT JOIN auc_3g ON auc_3g.subscriber_id = subscriber.id WHERE imsi = ?", [AUC_UPD_SQN] = "UPDATE auc_3g SET sqn = ? WHERE subscriber_id = ?", [UPD_PURGE_CS_BY_IMSI] = "UPDATE subscriber SET ms_purged_cs=1 WHERE imsi = ?", [UPD_PURGE_PS_BY_IMSI] = "UPDATE subscriber SET ms_purged_ps=1 WHERE imsi = ?", @@ -39,8 +39,9 @@ int db_update_sqn(struct db_context *dbc, uint64_t id, uint64_t new_sqn); int db_get_auc(struct db_context *dbc, const char *imsi, - struct osmo_auth_vector *vec, unsigned int num_vec, - const uint8_t *rand_auts, const uint8_t *auts); + unsigned int auc_3g_ind, struct osmo_auth_vector *vec, + unsigned int num_vec, const uint8_t *rand_auts, + const uint8_t *auts); #include <osmocom/core/linuxlist.h> #include <osmocom/gsm/protocol/gsm_23_003.h> diff --git a/src/db_auc.c b/src/db_auc.c index ac81404..8a369b5 100644 --- a/src/db_auc.c +++ b/src/db_auc.c @@ -159,6 +159,7 @@ int db_get_auth_data(struct db_context *dbc, const char *imsi, aud3g->u.umts.opc_is_op = 1; } aud3g->u.umts.sqn = sqlite3_column_int64(stmt, 7); + aud3g->u.umts.ind_bitlen = sqlite3_column_int(stmt, 8); /* FIXME: amf? */ aud3g->type = OSMO_AUTH_TYPE_UMTS; } else @@ -186,8 +187,9 @@ out: /* return -1 in case of error, 0 for unknown imsi, positive for number * of vectors generated */ int db_get_auc(struct db_context *dbc, const char *imsi, - struct osmo_auth_vector *vec, unsigned int num_vec, - const uint8_t *rand_auts, const uint8_t *auts) + unsigned int auc_3g_ind, struct osmo_auth_vector *vec, + unsigned int num_vec, const uint8_t *rand_auts, + const uint8_t *auts) { struct osmo_sub_auth_data aud2g, aud3g; uint64_t subscr_id; @@ -198,6 +200,16 @@ int db_get_auc(struct db_context *dbc, const char *imsi, if (rc <= 0) return rc; + aud3g.u.umts.ind = auc_3g_ind; + if (aud3g.type == OSMO_AUTH_TYPE_UMTS + && aud3g.u.umts.ind >= (1U << aud3g.u.umts.ind_bitlen)) { + LOGAUC(imsi, LOGL_NOTICE, "3G auth: SQN's IND bitlen %u is" + " too small to hold an index of %u. Truncating. This" + " may cause numerous additional AUTS resyncing.\n", + aud3g.u.umts.ind_bitlen, aud3g.u.umts.ind); + aud3g.u.umts.ind &= (1U << aud3g.u.umts.ind_bitlen) - 1; + } + LOGAUC(imsi, LOGL_DEBUG, "Calling to generate %u vectors\n", num_vec); rc = auc_compute_vectors(vec, num_vec, &aud2g, &aud3g, rand_auts, auts); if (rc < 0) { diff --git a/src/db_test.c b/src/db_test.c index 998a37a..0e823f9 100644 --- a/src/db_test.c +++ b/src/db_test.c @@ -20,7 +20,7 @@ static int test(const char *imsi, struct db_context *dbc) for (i = 0; i < ARRAY_SIZE(vec); i++) vec[i].res_len = 0; - rc = db_get_auc(dbc, imsi, vec, ARRAY_SIZE(vec), NULL, NULL); + rc = db_get_auc(dbc, imsi, 0, vec, ARRAY_SIZE(vec), NULL, NULL); if (rc <= 0) { LOGP(DMAIN, LOGL_ERROR, "Cannot obtain auth tuples for '%s'\n", imsi); return rc; diff --git a/src/gsup_server.c b/src/gsup_server.c index b0e1858..b382c86 100644 --- a/src/gsup_server.c +++ b/src/gsup_server.c @@ -211,6 +211,43 @@ static int osmo_gsup_server_closed_cb(struct ipa_server_conn *conn) return 0; } +/* Add conn to the clients list in a way that conn->auc_3g_ind takes the lowest + * unused integer and the list of clients remains sorted by auc_3g_ind. + * Keep this function non-static to allow linking in a unit test. */ +void osmo_gsup_server_add_conn(struct llist_head *clients, + struct osmo_gsup_conn *conn) +{ + struct osmo_gsup_conn *c; + struct osmo_gsup_conn *prev_conn; + + c = llist_first_entry_or_null(clients, struct osmo_gsup_conn, list); + + /* Is the first index, 0, unused? */ + if (!c || c->auc_3g_ind > 0) { + conn->auc_3g_ind = 0; + llist_add(&conn->list, clients); + return; + } + + /* Look for a gap later on */ + prev_conn = NULL; + llist_for_each_entry(c, clients, list) { + /* skip first item, we know it has auc_3g_ind == 0. */ + if (!prev_conn) { + prev_conn = c; + continue; + } + if (c->auc_3g_ind > prev_conn->auc_3g_ind + 1) + break; + prev_conn = c; + } + + OSMO_ASSERT(prev_conn); + + conn->auc_3g_ind = prev_conn->auc_3g_ind + 1; + llist_add(&conn->list, &prev_conn->list); +} + /* a client has connected to the server socket and we have accept()ed it */ static int osmo_gsup_server_accept_cb(struct ipa_server_link *link, int fd) { @@ -225,15 +262,15 @@ static int osmo_gsup_server_accept_cb(struct ipa_server_link *link, int fd) conn->conn = ipa_server_conn_create(gsups, link, fd, osmo_gsup_server_read_cb, osmo_gsup_server_closed_cb, conn); - conn->conn->ccm_cb = osmo_gsup_server_ccm_cb; OSMO_ASSERT(conn->conn); + conn->conn->ccm_cb = osmo_gsup_server_ccm_cb; /* link data structure with server structure */ conn->server = gsups; - llist_add_tail(&conn->list, &gsups->clients); + osmo_gsup_server_add_conn(&gsups->clients, conn); - LOGP(DLGSUP, LOGL_INFO, "New GSUP client %s:%d\n", - conn->conn->addr, conn->conn->port); + LOGP(DLGSUP, LOGL_INFO, "New GSUP client %s:%d (IND=%u)\n", + conn->conn->addr, conn->conn->port, conn->auc_3g_ind); /* request the identity of the client */ rc = ipa_ccm_send_id_req(fd); diff --git a/src/gsup_server.h b/src/gsup_server.h index 885fe52..74062d4 100644 --- a/src/gsup_server.h +++ b/src/gsup_server.h @@ -31,6 +31,8 @@ struct osmo_gsup_conn { struct ipa_server_conn *conn; //struct oap_state oap_state; struct tlv_parsed ccm; + + unsigned int auc_3g_ind; /*!< IND index used for UMTS AKA SQN */ }; @@ -63,7 +63,8 @@ static int rx_send_auth_info(struct osmo_gsup_conn *conn, memset(&gsup_out, 0, sizeof(gsup_out)); memcpy(&gsup_out.imsi, &gsup->imsi, sizeof(gsup_out.imsi)); - rc = db_get_auc(dbc, gsup->imsi, gsup_out.auth_vectors, + rc = db_get_auc(dbc, gsup->imsi, conn->auc_3g_ind, + gsup_out.auth_vectors, ARRAY_SIZE(gsup_out.auth_vectors), gsup->rand, gsup->auts); if (rc < 0) { |