From 545575695fd24f915215ff8a90a2ece808b63029 Mon Sep 17 00:00:00 2001 From: Alexander Couzens Date: Thu, 27 Sep 2018 21:15:30 +0200 Subject: gprs_gmm: Fix missing Security Command for 3G when attaching Introduce a new FSM step in GMM Attach to send the Security Command to the RNC after completing the Authentication. Fixes: f7198d7dbb84 ("gprs_gmm: introduce a GMM Attach Request FSM") Change-Id: I1e12b0a32e58c6f78dba7b548f7d7016567229db --- include/osmocom/sgsn/gprs_gmm_attach.h | 2 ++ src/gprs/gprs_gmm.c | 2 +- src/gprs/gprs_gmm_attach.c | 43 ++++++++++++++++++++++++++++++++-- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/include/osmocom/sgsn/gprs_gmm_attach.h b/include/osmocom/sgsn/gprs_gmm_attach.h index 22fbd6f9d..0aa2123a8 100644 --- a/include/osmocom/sgsn/gprs_gmm_attach.h +++ b/include/osmocom/sgsn/gprs_gmm_attach.h @@ -11,6 +11,7 @@ enum gmm_attach_req_fsm_states { ST_RETRIEVE_AUTH, ST_AUTH, ST_ASK_VLR, + ST_IU_SECURITY_CMD, ST_ACCEPT, ST_REJECT }; @@ -20,6 +21,7 @@ enum gmm_attach_req_fsm_events { E_IDEN_RESP_RECV, E_AUTH_RESP_RECV_SUCCESS, E_AUTH_RESP_RECV_RESYNC, + E_IU_SECURITY_CMD_COMPLETE, E_ATTACH_ACCEPTED, E_ATTACH_ACCEPT_SENT, E_ATTACH_COMPLETE_RECV, diff --git a/src/gprs/gprs_gmm.c b/src/gprs/gprs_gmm.c index a86fe2bb4..a0221ea8b 100644 --- a/src/gprs/gprs_gmm.c +++ b/src/gprs/gprs_gmm.c @@ -205,7 +205,7 @@ int sgsn_ranap_iu_event(struct ranap_ue_conn_ctx *ctx, enum ranap_iu_event_type REQUIRE_MM /* Continue authentication here */ mm->iu.ue_ctx->integrity_active = 1; - rc = gsm48_gmm_authorize(mm); + osmo_fsm_inst_dispatch(mm->gmm_att_req.fsm, E_IU_SECURITY_CMD_COMPLETE, NULL); break; default: LOGP(DRANAP, LOGL_NOTICE, "Unknown event received: %i\n", type); diff --git a/src/gprs/gprs_gmm_attach.c b/src/gprs/gprs_gmm_attach.c index 272fec797..60c4398ec 100644 --- a/src/gprs/gprs_gmm_attach.c +++ b/src/gprs/gprs_gmm_attach.c @@ -157,7 +157,12 @@ static void st_auth(struct osmo_fsm_inst *fi, uint32_t event, void *data) switch (event) { case E_AUTH_RESP_RECV_SUCCESS: sgsn_auth_request(ctx); - osmo_fsm_inst_state_chg(fi, ST_ACCEPT, sgsn->cfg.timers.T3350, 3350); +#ifdef BUILD_IU + if (ctx->ran_type == MM_CTX_T_UTRAN_Iu && !ctx->iu.ue_ctx->integrity_active) + osmo_fsm_inst_state_chg(fi, ST_IU_SECURITY_CMD, sgsn->cfg.timers.T3350, 3350); + else +#endif /* BUILD_IU */ + osmo_fsm_inst_state_chg(fi, ST_ACCEPT, sgsn->cfg.timers.T3350, 3350); break; case E_AUTH_RESP_RECV_RESYNC: if (ctx->gmm_att_req.auth_reattempt <= 1) @@ -228,6 +233,32 @@ static void st_ask_vlr(struct osmo_fsm_inst *fi, uint32_t event, void *data) } } +static void st_iu_security_cmd_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ +#ifdef BUILD_IU + struct sgsn_mm_ctx *ctx = fi->priv; + int rc = 0; + + /* TODO: shouldn't this set always? not only when the integrity_active? */ + if (ctx->iu.ue_ctx->integrity_active) { + osmo_fsm_inst_state_chg(fi, ST_ACCEPT, sgsn->cfg.timers.T3350, 3350); + return; + } + + ranap_iu_tx_sec_mode_cmd(ctx->iu.ue_ctx, &ctx->auth_triplet.vec, 0, ctx->iu.new_key); + ctx->iu.new_key = 0; +#endif +} + +static void st_iu_security_cmd(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch(event) { + case E_IU_SECURITY_CMD_COMPLETE: + osmo_fsm_inst_state_chg(fi, ST_ACCEPT, sgsn->cfg.timers.T3350, 3350); + break; + } +} + static struct osmo_fsm_state gmm_attach_req_fsm_states[] = { /* default state for non-DTX and DTX when SPEECH is in progress */ [ST_INIT] = { @@ -252,11 +283,18 @@ static struct osmo_fsm_state gmm_attach_req_fsm_states[] = { }, [ST_AUTH] = { .in_event_mask = X(E_AUTH_RESP_RECV_SUCCESS) | X(E_AUTH_RESP_RECV_RESYNC), - .out_state_mask = X(ST_INIT) | X(ST_AUTH) | X(ST_ACCEPT) | X(ST_ASK_VLR) | X(ST_REJECT), + .out_state_mask = X(ST_INIT) | X(ST_AUTH) | X(ST_IU_SECURITY_CMD) | X(ST_ACCEPT) | X(ST_ASK_VLR) | X(ST_REJECT), .name = "Authenticate", .onenter = st_auth_on_enter, .action = st_auth, }, + [ST_IU_SECURITY_CMD] = { + .in_event_mask = X(E_IU_SECURITY_CMD_COMPLETE), + .out_state_mask = X(ST_INIT) | X(ST_AUTH) | X(ST_ACCEPT) | X(ST_REJECT), + .name = "IuSecurityCommand", + .onenter = st_iu_security_cmd_on_enter, + .action = st_iu_security_cmd, + }, [ST_ACCEPT] = { .in_event_mask = X(E_ATTACH_COMPLETE_RECV), .out_state_mask = X(ST_INIT) | X(ST_REJECT), @@ -280,6 +318,7 @@ const struct value_string gmm_attach_req_fsm_event_names[] = { { E_ATTACH_ACCEPTED, "Attach accepted" }, { E_ATTACH_ACCEPT_SENT, "Attach accept sent" }, { E_ATTACH_COMPLETE_RECV, "Attach complete received." }, + { E_IU_SECURITY_CMD_COMPLETE, "IU Security Command Complete received." }, { E_REJECT, "Reject the MS"}, { E_VLR_ANSWERED, "VLR answered"}, { 0, NULL } -- cgit v1.2.3