diff options
author | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2022-10-11 00:18:04 +0200 |
---|---|---|
committer | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2022-10-12 13:52:39 +0200 |
commit | 29b59cc975f24c59be8e00bb12b4549a3e07d058 (patch) | |
tree | 9f2fd8e0535b409d21858709e3b1a303ddc3d403 | |
parent | 88f88bdbcdd485fad42fee8bae457d6e4a84dd0e (diff) |
vlr: implement fallback to no-auth
When the HLR fails to return auth info and authentication and ciphering
are configured to be optional, fall back to no-auth.
This patch concludes a series of preparatory patches and implements the
actual functional change.
Related: OS#4830
Change-Id: I5feda196fa481dd8a46b0e4721c64b7c6600f0d1
-rw-r--r-- | include/osmocom/msc/vlr.h | 2 | ||||
-rw-r--r-- | src/libvlr/vlr_access_req_fsm.c | 22 | ||||
-rw-r--r-- | src/libvlr/vlr_lu_fsm.c | 20 | ||||
-rw-r--r-- | tests/msc_vlr/msc_vlr_test_hlr_reject.err | 8 |
4 files changed, 44 insertions, 8 deletions
diff --git a/include/osmocom/msc/vlr.h b/include/osmocom/msc/vlr.h index 251769364..e112360ac 100644 --- a/include/osmocom/msc/vlr.h +++ b/include/osmocom/msc/vlr.h @@ -68,6 +68,7 @@ enum vlr_lu_event { VLR_ULA_E_SEND_ID_ACK, /* Result of Send-ID from PVLR */ VLR_ULA_E_SEND_ID_NACK, /* Result of Send-ID from PVLR */ VLR_ULA_E_AUTH_RES, /* Successful result of auth procedure */ + VLR_ULA_E_AUTH_NO_INFO, /* HLR returned SAI NACK, possibly continue without auth */ VLR_ULA_E_AUTH_FAILURE, /* Auth procedure failed */ VLR_ULA_E_CIPH_RES, /* Result of Ciphering Mode Command */ VLR_ULA_E_ID_IMSI, /* IMSI received from MS */ @@ -438,6 +439,7 @@ enum proc_arq_vlr_event { PR_ARQ_E_START, PR_ARQ_E_ID_IMSI, PR_ARQ_E_AUTH_RES, + PR_ARQ_E_AUTH_NO_INFO, PR_ARQ_E_AUTH_FAILURE, PR_ARQ_E_CIPH_RES, PR_ARQ_E_UPD_LOC_RES, diff --git a/src/libvlr/vlr_access_req_fsm.c b/src/libvlr/vlr_access_req_fsm.c index 377376201..3469cc018 100644 --- a/src/libvlr/vlr_access_req_fsm.c +++ b/src/libvlr/vlr_access_req_fsm.c @@ -40,6 +40,7 @@ static const struct value_string proc_arq_vlr_event_names[] = { OSMO_VALUE_STRING(PR_ARQ_E_START), OSMO_VALUE_STRING(PR_ARQ_E_ID_IMSI), OSMO_VALUE_STRING(PR_ARQ_E_AUTH_RES), + OSMO_VALUE_STRING(PR_ARQ_E_AUTH_NO_INFO), OSMO_VALUE_STRING(PR_ARQ_E_AUTH_FAILURE), OSMO_VALUE_STRING(PR_ARQ_E_CIPH_RES), OSMO_VALUE_STRING(PR_ARQ_E_UPD_LOC_RES), @@ -285,7 +286,10 @@ static void _proc_arq_vlr_node2(struct osmo_fsm_inst *fi) LOGPFSM(fi, "%s()\n", __func__); - if (!try_cmc_smc(par)) { + /* Continue with ciphering, if enabled. + * If auth/ciph is optional and the HLR returned no auth info, continue without ciphering. */ + if (!try_cmc_smc(par) + || (vsub->sec_ctx == VLR_SEC_CTX_NONE && !par->ciphering_required)) { _proc_arq_vlr_node2_post_ciph(fi); return; } @@ -341,7 +345,7 @@ static void proc_arq_vlr_fn_post_imsi(struct osmo_fsm_inst *fi) 0, 0); vsub->auth_fsm = auth_fsm_start(vsub, fi, PR_ARQ_E_AUTH_RES, - PR_ARQ_E_AUTH_FAILURE, + PR_ARQ_E_AUTH_NO_INFO, PR_ARQ_E_AUTH_FAILURE, par->is_r99, par->is_utran); @@ -435,6 +439,7 @@ static void proc_arq_vlr_fn_w_obt_imsi(struct osmo_fsm_inst *fi, static void proc_arq_vlr_fn_w_auth(struct osmo_fsm_inst *fi, uint32_t event, void *data) { + struct proc_arq_priv *par = fi->priv; enum gsm48_reject_value *cause = data; switch (event) { @@ -447,6 +452,18 @@ static void proc_arq_vlr_fn_w_auth(struct osmo_fsm_inst *fi, proc_arq_fsm_done(fi, cause? *cause : GSM48_REJECT_NETWORK_FAILURE); return; + case PR_ARQ_E_AUTH_NO_INFO: + /* HLR returned no auth info for the subscriber. Continue only if authentication is optional. */ + if (par->authentication_required) { + proc_arq_fsm_done(fi, cause? *cause : GSM48_REJECT_NETWORK_FAILURE); + return; + } + LOGPFSML(fi, LOGL_INFO, + "Attaching subscriber without auth (auth is optional, and no auth info received from HLR)\n"); + /* Node 2 */ + _proc_arq_vlr_node2(fi); + return; + default: OSMO_ASSERT(false); } @@ -555,6 +572,7 @@ static const struct osmo_fsm_state proc_arq_vlr_states[] = { [PR_ARQ_S_WAIT_AUTH] = { .name = OSMO_STRINGIFY(PR_ARQ_S_WAIT_AUTH), .in_event_mask = S(PR_ARQ_E_AUTH_RES) | + S(PR_ARQ_E_AUTH_NO_INFO) | S(PR_ARQ_E_AUTH_FAILURE), .out_state_mask = S(PR_ARQ_S_DONE) | S(PR_ARQ_S_WAIT_CIPH) | diff --git a/src/libvlr/vlr_lu_fsm.c b/src/libvlr/vlr_lu_fsm.c index 9a76db8f9..8bfce88b5 100644 --- a/src/libvlr/vlr_lu_fsm.c +++ b/src/libvlr/vlr_lu_fsm.c @@ -643,6 +643,7 @@ static const struct value_string fsm_lu_event_names[] = { OSMO_VALUE_STRING(VLR_ULA_E_SEND_ID_ACK), OSMO_VALUE_STRING(VLR_ULA_E_SEND_ID_NACK), OSMO_VALUE_STRING(VLR_ULA_E_AUTH_RES), + OSMO_VALUE_STRING(VLR_ULA_E_AUTH_NO_INFO), OSMO_VALUE_STRING(VLR_ULA_E_AUTH_FAILURE), OSMO_VALUE_STRING(VLR_ULA_E_CIPH_RES), OSMO_VALUE_STRING(VLR_ULA_E_ID_IMSI), @@ -857,7 +858,10 @@ static void vlr_loc_upd_post_auth(struct osmo_fsm_inst *fi) OSMO_ASSERT(vsub); - if (!try_cmc_smc(lfp)) { + /* Continue with ciphering, if enabled. + * If auth/ciph is optional and the HLR returned no auth info, continue without ciphering. */ + if (!try_cmc_smc(lfp) + || (vsub->sec_ctx == VLR_SEC_CTX_NONE && !lfp->ciphering_required)) { vlr_loc_upd_post_ciph(fi); return; } @@ -909,7 +913,7 @@ static void vlr_loc_upd_node1(struct osmo_fsm_inst *fi) vsub->auth_fsm = auth_fsm_start(lfp->vsub, fi, VLR_ULA_E_AUTH_RES, - VLR_ULA_E_AUTH_FAILURE, + VLR_ULA_E_AUTH_NO_INFO, VLR_ULA_E_AUTH_FAILURE, lfp->is_r99, lfp->is_utran); @@ -1155,6 +1159,17 @@ static void lu_fsm_wait_auth(struct osmo_fsm_inst *fi, uint32_t event, lu_fsm_failure(fi, res? *res : GSM48_REJECT_NETWORK_FAILURE); return; + case VLR_ULA_E_AUTH_NO_INFO: + /* HLR returned no auth info for the subscriber. Continue only if authentication is optional. */ + if (lfp->authentication_required || lfp->ciphering_required) { + lu_fsm_failure(fi, res? *res : GSM48_REJECT_NETWORK_FAILURE); + return; + } + LOGPFSML(fi, LOGL_INFO, + "Attaching subscriber without auth (auth is optional, and no auth info received from HLR)\n"); + vlr_loc_upd_post_auth(fi); + return; + default: OSMO_ASSERT(false); } @@ -1373,6 +1388,7 @@ static const struct osmo_fsm_state vlr_lu_fsm_states[] = { }, [VLR_ULA_S_WAIT_AUTH] = { .in_event_mask = S(VLR_ULA_E_AUTH_RES) | + S(VLR_ULA_E_AUTH_NO_INFO) | S(VLR_ULA_E_AUTH_FAILURE), .out_state_mask = S(VLR_ULA_S_WAIT_CIPH) | S(VLR_ULA_S_WAIT_LU_COMPL) | diff --git a/tests/msc_vlr/msc_vlr_test_hlr_reject.err b/tests/msc_vlr/msc_vlr_test_hlr_reject.err index 441bc2faa..291086af7 100644 --- a/tests/msc_vlr/msc_vlr_test_hlr_reject.err +++ b/tests/msc_vlr/msc_vlr_test_hlr_reject.err @@ -47,7 +47,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAI DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_FAILURE +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_NO_INFO - sending LU Reject for IMSI-901700000004620:GERAN-A:LU, cause 2 DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE @@ -146,7 +146,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAI DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_FAILURE +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_NO_INFO - sending LU Reject for IMSI-901700000004620:GERAN-A:LU, cause 17 DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE @@ -742,7 +742,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_N DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_FAILURE +DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_NO_INFO - sending LU Reject for IMSI-901700000004620:MSISDN-46071:GERAN-A:LU, cause 17 DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE @@ -1010,7 +1010,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_N DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_FAILURE +DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_NO_INFO - sending LU Reject for IMSI-901700000004620:MSISDN-46071:GERAN-A:LU, cause 2 DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE |