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: f7198d7dbb ("gprs_gmm: introduce a GMM Attach Request FSM")
Change-Id: I1e12b0a32e58c6f78dba7b548f7d7016567229db
This commit is contained in:
Alexander Couzens 2018-09-27 21:15:30 +02:00
parent 47cf6bd001
commit 545575695f
3 changed files with 44 additions and 3 deletions

View File

@ -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,

View File

@ -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);

View File

@ -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 }