nitb: Add a mode to not use TMSI for normal operation

In case foreign simcards are used we can not do authentication
and ciphering. In case a TMSI is re-used too early and we do
page using TMSI we can't know which of the two MS is responding
to us. We could change the "secure channel" routine to ask for
the IMSI and only then stop the paging.

As we don't have ciphering there is not much use in using the
TMSI. Add a mode "no assign-tmsi" that will not assign the TMSI
during LU. Now CM Service Request and Paging Response  will
work using the IMSI. There can't be a clash with that.

[ciaby fixed the vty write to use the right name]
This commit is contained in:
Holger Hans Peter Freyther 2015-07-13 20:33:08 +02:00
parent 5f8a0c5c70
commit 666e36aea9
3 changed files with 88 additions and 31 deletions

View File

@ -281,6 +281,9 @@ struct gsm_network {
struct gsm_subscriber_group *subscr_group;
struct gsm_sms_queue *sms_queue;
/* nitb related control */
int avoid_tmsi;
/* control interface */
struct ctrl_handle *ctrl;
};

View File

@ -67,7 +67,7 @@
void *tall_locop_ctx;
void *tall_authciphop_ctx;
int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn, uint32_t tmsi);
static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn);
static int gsm48_tx_simple(struct gsm_subscriber_connection *conn,
uint8_t pdisc, uint8_t msg_type);
static void schedule_reject(struct gsm_subscriber_connection *conn);
@ -294,6 +294,42 @@ static void allocate_loc_updating_req(struct gsm_subscriber_connection *conn)
struct gsm_loc_updating_operation);
}
static int finish_lu(struct gsm_subscriber_connection *conn)
{
int rc = 0;
int avoid_tmsi = conn->bts->network->avoid_tmsi;
/* We're all good */
if (avoid_tmsi) {
conn->subscr->tmsi = GSM_RESERVED_TMSI;
db_sync_subscriber(conn->subscr);
} else {
db_subscriber_alloc_tmsi(conn->subscr);
}
rc = gsm0408_loc_upd_acc(conn);
if (conn->bts->network->send_mm_info) {
/* send MM INFO with network name */
rc = gsm48_tx_mm_info(conn);
}
/* call subscr_update after putting the loc_upd_acc
* in the transmit queue, since S_SUBSCR_ATTACHED might
* trigger further action like SMS delivery */
subscr_update(conn->subscr, conn->bts,
GSM_SUBSCRIBER_UPDATE_ATTACHED);
/*
* The gsm0408_loc_upd_acc sends a MI with the TMSI. The
* MS needs to respond with a TMSI REALLOCATION COMPLETE
* (even if the TMSI is the same).
*/
if (avoid_tmsi)
release_loc_updating_req(conn, 1);
return rc;
}
static int _gsm0408_authorize_sec_cb(unsigned int hooknum, unsigned int event,
struct msgb *msg, void *data, void *param)
{
@ -312,25 +348,7 @@ static int _gsm0408_authorize_sec_cb(unsigned int hooknum, unsigned int event,
case GSM_SECURITY_NOAVAIL:
case GSM_SECURITY_SUCCEEDED:
/* We're all good */
db_subscriber_alloc_tmsi(conn->subscr);
rc = gsm0408_loc_upd_acc(conn, conn->subscr->tmsi);
if (conn->bts->network->send_mm_info) {
/* send MM INFO with network name */
rc = gsm48_tx_mm_info(conn);
}
/* call subscr_update after putting the loc_upd_acc
* in the transmit queue, since S_SUBSCR_ATTACHED might
* trigger further action like SMS delivery */
subscr_update(conn->subscr, conn->bts,
GSM_SUBSCRIBER_UPDATE_ATTACHED);
/*
* The gsm0408_loc_upd_acc sends a MI with the TMSI. The
* MS needs to respond with a TMSI REALLOCATION COMPLETE
* (even if the TMSI is the same).
*/
rc = finish_lu(conn);
break;
default:
@ -434,7 +452,7 @@ int gsm0408_loc_upd_rej(struct gsm_subscriber_connection *conn, uint8_t cause)
}
/* Chapter 9.2.13 : Send LOCATION UPDATE ACCEPT */
int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn, uint32_t tmsi)
static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn)
{
struct gsm_bts *bts = conn->bts;
struct msgb *msg = gsm48_msgb_alloc();
@ -452,8 +470,16 @@ int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn, uint32_t tmsi)
gsm48_generate_lai(lai, bts->network->country_code,
bts->network->network_code, bts->location_area_code);
mid = msgb_put(msg, GSM48_MID_TMSI_LEN);
gsm48_generate_mid_from_tmsi(mid, tmsi);
if (conn->subscr->tmsi == GSM_RESERVED_TMSI) {
uint8_t mi[10];
int len;
len = gsm48_generate_mid_from_imsi(mi, conn->subscr->imsi);
mid = msgb_put(msg, len);
memcpy(mid, mi, len);
} else {
mid = msgb_put(msg, GSM48_MID_TMSI_LEN);
gsm48_generate_mid_from_tmsi(mid, conn->subscr->tmsi);
}
DEBUGP(DMM, "-> LOCATION UPDATE ACCEPT\n");
@ -946,24 +972,30 @@ static int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct m
GSM48_REJECT_INCORRECT_MESSAGE);
}
gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len);
mi_type = mi[0] & GSM_MI_TYPE_MASK;
if (mi_type != GSM_MI_TYPE_TMSI) {
DEBUGPC(DMM, "mi_type is not TMSI: %d\n", mi_type);
if (mi_type == GSM_MI_TYPE_IMSI) {
DEBUGPC(DMM, "serv_type=0x%02x mi_type=0x%02x M(%s)\n",
req->cm_service_type, mi_type, mi_string);
subscr = subscr_get_by_imsi(bts->network->subscr_group,
mi_string);
} else if (mi_type == GSM_MI_TYPE_TMSI) {
DEBUGPC(DMM, "serv_type=0x%02x mi_type=0x%02x M(%s)\n",
req->cm_service_type, mi_type, mi_string);
subscr = subscr_get_by_tmsi(bts->network->subscr_group,
tmsi_from_string(mi_string));
} else {
DEBUGPC(DMM, "mi_type is not expected: %d\n", mi_type);
return gsm48_tx_mm_serv_rej(conn,
GSM48_REJECT_INCORRECT_MESSAGE);
}
gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len);
DEBUGPC(DMM, "serv_type=0x%02x mi_type=0x%02x M(%s)\n",
req->cm_service_type, mi_type, mi_string);
osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, (classmark2 + classmark2_len));
if (is_siemens_bts(bts))
send_siemens_mrpci(msg->lchan, classmark2-1);
subscr = subscr_get_by_tmsi(bts->network->subscr_group,
tmsi_from_string(mi_string));
/* FIXME: if we don't know the TMSI, inquire abit IMSI and allocate new TMSI */
if (!subscr)

View File

@ -1037,12 +1037,32 @@ DEFUN(cfg_nitb_no_subscr_create, cfg_nitb_no_subscr_create_cmd,
return CMD_SUCCESS;
}
DEFUN(cfg_nitb_assign_tmsi, cfg_nitb_assign_tmsi_cmd,
"assign-tmsi",
"Assign TMSI during Location Updating.\n")
{
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
gsmnet->avoid_tmsi = 0;
return CMD_SUCCESS;
}
DEFUN(cfg_nitb_no_assign_tmsi, cfg_nitb_no_assign_tmsi_cmd,
"no assign-tmsi",
NO_STR "Assign TMSI during Location Updating.\n")
{
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
gsmnet->avoid_tmsi = 1;
return CMD_SUCCESS;
}
static int config_write_nitb(struct vty *vty)
{
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
vty_out(vty, "nitb%s", VTY_NEWLINE);
vty_out(vty, " %ssubscriber-create-on-demand%s",
gsmnet->create_subscriber ? "" : "no ", VTY_NEWLINE);
vty_out(vty, " %sassign-tmsi%s",
gsmnet->avoid_tmsi ? "no " : "", VTY_NEWLINE);
return CMD_SUCCESS;
}
@ -1096,6 +1116,8 @@ int bsc_vty_init_extra(void)
install_node(&nitb_node, config_write_nitb);
install_element(NITB_NODE, &cfg_nitb_subscr_create_cmd);
install_element(NITB_NODE, &cfg_nitb_no_subscr_create_cmd);
install_element(NITB_NODE, &cfg_nitb_assign_tmsi_cmd);
install_element(NITB_NODE, &cfg_nitb_no_assign_tmsi_cmd);
return 0;
}