aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Couzens <lynxis@fe80.eu>2018-09-27 21:15:30 +0200
committerAlexander Couzens <lynxis@fe80.eu>2018-10-02 20:19:35 +0200
commit545575695fd24f915215ff8a90a2ece808b63029 (patch)
tree243aec0518c244d0860c14a9216564aa6d786e27
parent47cf6bd001899680a0e0d1a4f920d2a37c19ec1e (diff)
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
-rw-r--r--include/osmocom/sgsn/gprs_gmm_attach.h2
-rw-r--r--src/gprs/gprs_gmm.c2
-rw-r--r--src/gprs/gprs_gmm_attach.c43
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 22fbd6f9..0aa2123a 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 a86fe2bb..a0221ea8 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 272fec79..60c4398e 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 }