neels has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/29692 )


Change subject: msc: test auth options, and fall-back to no-auth
......................................................................

msc: test auth options, and fall-back to no-auth

Test 12 permutations of
(auth optional,required) x (a5 '0', '0 3', '3') x (hlr has auth info)

In TC_auth_options_2(), expect behavior after implementing OS#4830: if
the HLR fails to return auth info and auth + ciph are configured
optional, fall back to no authentication. This test will start
succeeding starting with commit
I5feda196fa481dd8a46b0e4721c64b7c6600f0d1 in osmo-msc.git.

All other tests yield the current behavior of osmo-msc.

Related: I5feda196fa481dd8a46b0e4721c64b7c6600f0d1 (osmo-msc)
Related: OS#4830
Change-Id: I8e3b02ca83e56ef5349d85f08407509e19fa353c
---
M msc/BSC_ConnectionHandler.ttcn
M msc/MSC_Tests.ttcn
2 files changed, 409 insertions(+), 32 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks 
refs/changes/92/29692/1

diff --git a/msc/BSC_ConnectionHandler.ttcn b/msc/BSC_ConnectionHandler.ttcn
index 4e736b8..fe9187c 100644
--- a/msc/BSC_ConnectionHandler.ttcn
+++ b/msc/BSC_ConnectionHandler.ttcn
@@ -78,8 +78,24 @@
 }

 type record BSC_ConnHdlrNetworkPars {
+       /* Bitmask of expected A5 levels; in Ciphering, will expect use of the 
highest A5 remaining after masking this
+        * with A5 supported by the MS */
        OCT1    kc_support,
+       /* osmo-msc VTY cfg under 'network': If a test wants to temporarily 
modify auth and encr config, this is the
+        * original config to return to for this test (is *not* sent to vty 
before the test, but maybe it should).
+        * For example: { "authentication optional", "encryption a5 0 3" } */
+       rof_charstring net_config,
+       /* expect_attach_success == true: expect Location Updating / CM Service 
Request to succeed.
+        * expect_attach_success == false: expect the MSC to reject LU / CM 
Service. */
+       boolean expect_attach_success,
+       /* expect_tmsi == true: expect MSC to allocate a new TMSI.
+        * expect_tmsi == false: expect no TMSI to be assigned, operate with 
IMSI Mobile Identity. */
        boolean expect_tmsi,
+       /* expect_auth == true overrides expect_auth_attempt == false */
+       boolean expect_auth_attempt,
+       /* hlr_has_auth_info has an effect only when (expect_auth_attempt or 
expect_auth) == true.
+        * hlr_has_auth_info == false means the HLR responds to Send Auth Info 
Request with a NACK. */
+       boolean hlr_has_auth_info,
        boolean expect_auth,
        boolean expect_ciph,
        boolean expect_imei,
@@ -404,7 +420,11 @@
        } else {
                if (etype != EST_TYPE_PAG_RESP) {
                        /* explicit CM SERVICE ACCEPT */
-                       BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC));
+                       if (g_pars.net.expect_attach_success) {
+                               BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC));
+                       } else {
+                               BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ));
+                       }
                }
        }
 }
@@ -436,34 +456,43 @@
 altstep as_GSUP_SAI() runs on BSC_ConnHdlr {
 var GSUP_IE auth_tuple;
 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)) {
-       if (g_pars.use_umts_aka) {
-               if (not g_pars.vec_keep) {
-                       g_pars.vec := f_gen_auth_vec_3g();
+       if (g_pars.net.hlr_has_auth_info) {
+               if (g_pars.use_umts_aka) {
+                       if (not g_pars.vec_keep) {
+                               g_pars.vec := f_gen_auth_vec_3g();
+                       }
+                       auth_tuple := 
valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
+                                                                       
g_pars.vec.sres,
+                                                                       
g_pars.vec.kc,
+                                                                       
g_pars.vec.ik,
+                                                                       
g_pars.vec.ck,
+                                                                       
g_pars.vec.autn,
+                                                                       
g_pars.vec.res));
+                       GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
+               } else {
+                       if (not g_pars.vec_keep) {
+                               g_pars.vec := f_gen_auth_vec_2g();
+                       }
+                       auth_tuple := 
valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
+                                                                       
g_pars.vec.sres,
+                                                                       
g_pars.vec.kc));
+                       GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
                }
-               auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
-                                                               g_pars.vec.sres,
-                                                               g_pars.vec.kc,
-                                                               g_pars.vec.ik,
-                                                               g_pars.vec.ck,
-                                                               g_pars.vec.autn,
-                                                               
g_pars.vec.res));
-               GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
        } else {
-               if (not g_pars.vec_keep) {
-                       g_pars.vec := f_gen_auth_vec_2g();
-               }
-               auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
-                                                               g_pars.vec.sres,
-                                                               g_pars.vec.kc));
-               GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
+               log("XXX ts_GSUP_SAI_ERR");
+               /* HLR knows the IMSI but has no authentication info; osmo-hlr 
responds with GMM_CAUSE_IMSI_UNKNOWN=2 in
+                * this case, for SAI this merely means there is no auth entry 
for this IMSI. */
+               GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 2));
        }
        }
 }

 function f_mm_auth() runs on BSC_ConnHdlr
 {
-       if (g_pars.net.expect_auth) {
+       if (g_pars.net.expect_auth or g_pars.net.expect_auth_attempt) {
                as_GSUP_SAI();
+       }
+       if (g_pars.net.expect_auth) {
                if (g_pars.use_umts_aka) {
                        
BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ_3G(g_pars.vec.rand, 
g_pars.vec.autn)));
                        var OCT4 res := substr(g_pars.vec.res, 0, 4);
@@ -685,6 +714,9 @@
                f_mm_ciph_utran();
        }

+       if (not g_pars.net.expect_attach_success) {
+               return;
+       }
        f_expect_common_id();
 }

@@ -810,15 +842,18 @@
        f_mm_common();
        f_msc_lu_hlr();
        f_mm_imei();
-       f_accept_reject_lu();
+       as_accept_reject_lu(g_pars.net.expect_attach_success);
        /* FIXME: there could be pending SMS or other common procedures by the 
MSC, let's ignore them */
-       f_expect_clear();
+       f_expect_clear(verify_vlr_cell_id := g_pars.net.expect_attach_success);

        setverdict(pass);
 }

 function f_msc_lu_hlr() runs on BSC_ConnHdlr
 {
+       if (not g_pars.net.expect_attach_success) {
+               return;
+       }
        /* Expect MSC to perform LU with HLR */
        GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
        GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
@@ -826,11 +861,10 @@
        GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
 }

-function f_accept_reject_lu() runs on BSC_ConnHdlr {
+altstep as_accept_reject_lu(boolean expect_accept := true) runs on 
BSC_ConnHdlr {
        var PDU_DTAP_MT dtap_mt;

-       alt {
-       [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) -> value dtap_mt {
+       [expect_accept] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) -> 
value dtap_mt {
                var PDU_ML3_LocationUpdateAccept lu_acc := 
dtap_mt.dtap.msgs.mm.locationUpdateAccept;
                if (g_pars.net.expect_tmsi) {
                        if (not ispresent(lu_acc.mobileIdentityTLV) or
@@ -848,16 +882,23 @@
                                mtc.stop;
                        }
                }
-               }
-       [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
+
+               /* Wait for MM-Information (if enabled) */
+               f_expect_mm_info();
+               setverdict(pass);
+       }
+       [expect_accept] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
                setverdict(fail, "Expected LU ACK, but received LU REJ");
                mtc.stop;
-               }
        }

-       /* Wait for MM-Information (if enabled) */
-       f_expect_mm_info();
-       setverdict(pass);
+       [not expect_accept] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
+               setverdict(pass);
+       }
+       [not expect_accept] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) -> 
value dtap_mt {
+               setverdict(fail, "Expected LU REJ, but received LU ACK");
+               mtc.stop;
+       }
 }

 function f_expect_lu_reject(template OCT1 cause := ?) runs on BSC_ConnHdlr {
diff --git a/msc/MSC_Tests.ttcn b/msc/MSC_Tests.ttcn
index e6d270d..13133de 100644
--- a/msc/MSC_Tests.ttcn
+++ b/msc/MSC_Tests.ttcn
@@ -371,7 +371,11 @@
 runs on MTC_CT return BSC_ConnHdlrPars {
        var BSC_ConnHdlrNetworkPars net_pars := {
                kc_support := '0A'O,    /* A5/1 and A5/3 enabled */
+               net_config := { "authentication optional", "encryption a5 0" },
+               expect_attach_success := true,
                expect_tmsi := true,
+               expect_auth_attempt := false,
+               hlr_has_auth_info := true,
                expect_auth := false,
                expect_ciph := false,
                expect_imei := false,
@@ -4474,7 +4478,7 @@
        /* TODO: Verify MSC is using the best cipher available! How? */

        f_msc_lu_hlr();
-       f_accept_reject_lu();
+       as_accept_reject_lu();
        f_expect_clear();
        setverdict(pass);
 }
@@ -6848,6 +6852,325 @@
        vc_conn.done;
 }

+/*                              a5 0       a5 0        a5 0 3         a5 0 3   
a5 3       a5 3
+ *         HLR has auth info    no         yes         no             yes      
no         yes
+ *
+ *           test case index    [0]        [1]         [2]            [3]      
[4]        [5]
+ *   authentication optional    No auth    No auth     attempt auth,  auth     
reject     auth
+ *                                         (%)         fall back to   +ciph    
           +ciph
+ *                                                     no-auth
+ *
+ *                              [6]        [7]         [8]            [9]      
[10]       [11]
+ *  authentication mandatory    reject     auth        reject         auth     
reject     auth
+ *                                         only                       +ciph    
           +ciph
+ *
+ *  (%): Arguably, when HLR has auth info, the MSC should use it. Current 
behavior of osmo-msc is to not attempt auth at
+ *       all. Related: OS#4830.
+ */
+type record of BSC_ConnHdlrNetworkPars rof_netpars;
+
+const rof_netpars auth_options_testcases := {
+       {
+               /* [0] auth optional, encr a5 0: no-auth" */
+               kc_support := '01'O,
+               net_config := { "authentication optional",
+                               "encryption a5 0" },
+               expect_attach_success := true,
+               expect_tmsi := true,
+               expect_auth_attempt := false,
+               hlr_has_auth_info := false,
+               expect_auth := false,
+               expect_ciph := false,
+               expect_imei := false,
+               expect_imei_early := false,
+               check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
+               check_imei_error := false
+       },
+       {
+               /* [1] auth optional, encr a5 0, HLR HAS auth info: no-auth */
+               kc_support := '01'O,
+               net_config := { "authentication optional",
+                               "encryption a5 0" },
+               expect_attach_success := true,
+               expect_tmsi := true,
+               expect_auth_attempt := false,
+               hlr_has_auth_info := true,
+               expect_auth := false,
+               expect_ciph := false,
+               expect_imei := false,
+               expect_imei_early := false,
+               check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
+               check_imei_error := false
+       },
+       {
+               /* [2] auth optional, encr a5 0 3, HLR has NO Auth Info: Fall 
back to no-auth" */
+               kc_support := '09'O,
+               net_config := { "authentication optional",
+                               "encryption a5 0 3" },
+               expect_attach_success := true,
+               expect_tmsi := true,
+               expect_auth_attempt := true,
+               hlr_has_auth_info := false,
+               expect_auth := false,
+               expect_ciph := false,
+               expect_imei := false,
+               expect_imei_early := false,
+               check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
+               check_imei_error := false
+       },
+       {
+               /* [3] auth optional, encr a5 0 3, HLR HAS Auth Info: Use A5/3 
*/
+               kc_support := '09'O,
+               net_config := { "authentication optional",
+                               "encryption a5 0 3" },
+               expect_attach_success := true,
+               expect_tmsi := true,
+               expect_auth_attempt := true,
+               hlr_has_auth_info := true,
+               expect_auth := true,
+               expect_ciph := true,
+               expect_imei := false,
+               expect_imei_early := false,
+               check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
+               check_imei_error := false
+       },
+       {
+               /* [4] auth optional, encr a5 3, HLR has NO Auth Info: reject.
+                * Auth is required implicitly because ciph is required. */
+               kc_support := '08'O,
+               net_config := { "authentication optional",
+                               "encryption a5 3" },
+               expect_attach_success := false,
+               expect_tmsi := true,
+               expect_auth_attempt := true,
+               hlr_has_auth_info := false,
+               expect_auth := false,
+               expect_ciph := false,
+               expect_imei := false,
+               expect_imei_early := false,
+               check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
+               check_imei_error := false
+       },
+       {
+               /* [5] auth optional, encr a5 3, HLR HAS Auth Info: auth + ciph.
+                * Auth is required implicitly because ciph is required. */
+               kc_support := '08'O,
+               net_config := { "authentication optional",
+                               "encryption a5 3" },
+               expect_attach_success := true,
+               expect_tmsi := true,
+               expect_auth_attempt := true,
+               hlr_has_auth_info := true,
+               expect_auth := true,
+               expect_ciph := true,
+               expect_imei := false,
+               expect_imei_early := false,
+               check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
+               check_imei_error := false
+       },
+
+       /* Same as above, but with 'authentication required' */
+
+       {
+               /* [6] auth required, encr a5 0, HLR has NO auth info: reject */
+               kc_support := '01'O,
+               net_config := { "authentication required",
+                               "encryption a5 0" },
+               expect_attach_success := false,
+               expect_tmsi := true,
+               expect_auth_attempt := true,
+               hlr_has_auth_info := false,
+               expect_auth := false,
+               expect_ciph := false,
+               expect_imei := false,
+               expect_imei_early := false,
+               check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
+               check_imei_error := false
+       },
+       {
+               /* [7] auth required, encr a5 0, HLR HAS auth info: do auth, no 
ciph" */
+               kc_support := '01'O,
+               net_config := { "authentication required",
+                               "encryption a5 0" },
+               expect_attach_success := true,
+               expect_tmsi := true,
+               expect_auth_attempt := true,
+               hlr_has_auth_info := true,
+               expect_auth := true,
+               expect_ciph := false,
+               expect_imei := false,
+               expect_imei_early := false,
+               check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
+               check_imei_error := false
+       },
+       {
+               /* [8] auth required, encr a5 0 3, HLR has NO Auth Info: reject 
*/
+               kc_support := '09'O,
+               net_config := { "authentication required",
+                               "encryption a5 0 3" },
+               expect_attach_success := false,
+               expect_tmsi := true,
+               expect_auth_attempt := true,
+               hlr_has_auth_info := false,
+               expect_auth := false,
+               expect_ciph := false,
+               expect_imei := false,
+               expect_imei_early := false,
+               check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
+               check_imei_error := false
+       },
+       {
+               /* [9] auth required, encr a5 0 3, HLR HAS Auth Info: Use A5/3 
*/
+               kc_support := '09'O,
+               net_config := { "authentication required",
+                               "encryption a5 0 3" },
+               expect_attach_success := true,
+               expect_tmsi := true,
+               expect_auth_attempt := true,
+               hlr_has_auth_info := true,
+               expect_auth := true,
+               expect_ciph := true,
+               expect_imei := false,
+               expect_imei_early := false,
+               check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
+               check_imei_error := false
+       },
+       {
+               /* [10] auth required, encr a5 3, HLR has NO Auth Info: reject. 
*/
+               kc_support := '08'O,
+               net_config := { "authentication required",
+                               "encryption a5 3" },
+               expect_attach_success := false,
+               expect_tmsi := true,
+               expect_auth_attempt := true,
+               hlr_has_auth_info := false,
+               expect_auth := false,
+               expect_ciph := false,
+               expect_imei := false,
+               expect_imei_early := false,
+               check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
+               check_imei_error := false
+       },
+       {
+               /* [11] auth required, encr a5 3, HLR HAS Auth Info: auth + 
ciph. */
+               kc_support := '08'O,
+               net_config := { "authentication required",
+                               "encryption a5 3" },
+               expect_attach_success := true,
+               expect_tmsi := true,
+               expect_auth_attempt := true,
+               hlr_has_auth_info := true,
+               expect_auth := true,
+               expect_ciph := true,
+               expect_imei := false,
+               expect_imei_early := false,
+               check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
+               check_imei_error := false
+       }
+};
+
+private function f_tc_auth_options(charstring id, BSC_ConnHdlrPars pars) runs 
on BSC_ConnHdlr {
+       f_init_handler(pars);
+
+       /* Location Updating */
+       f_logp(MSCVTY, "f_perform_lu() starting");
+       f_perform_lu();
+       f_logp(MSCVTY, "f_perform_lu() done");
+
+       f_sleep(1.0);
+
+       if (not pars.net.expect_attach_success) {
+               /* Expected above LU to fail. In order to test CM Service 
Request below, a LU has to succeed first. So
+                * run another LU that will be successful. Careful not to load 
auth tokens into the VLR that may taint
+                * the test for CM Service Request below. */
+
+               f_logp(MSCVTY, "Running a successful LU so that CM Service 
Request can be tested");
+               var BSC_ConnHdlrNetworkPars saved_net := g_pars.net;
+               g_pars.net.kc_support := '01'O;
+               g_pars.net.expect_attach_success := true;
+               g_pars.net.expect_auth_attempt := false;
+               g_pars.net.expect_auth := false;
+               g_pars.net.expect_ciph := false;
+               f_vty_config3(MSCVTY, {"network"}, {"authentication optional", 
"encryption a5 0"});
+               f_perform_lu();
+
+               /* Reconfigure like it was before */
+               g_pars.net := saved_net;
+               f_vty_config3(MSCVTY, {"network"}, g_pars.net.net_config);
+               f_logp(MSCVTY, "Running a successful LU done");
+       }
+
+       /* CM Service Request */
+       f_logp(MSCVTY, "f_establish_fully() starting");
+       f_establish_fully();
+       f_logp(MSCVTY, "f_establish_fully() done");
+       BSSAP.send(ts_BSSMAP_ClearRequest(0));
+       f_expect_clear();
+}
+
+function f_TC_auth_options(integer tc_i) runs on MTC_CT {
+       f_init();
+
+       var BSC_ConnHdlrNetworkPars tc := auth_options_testcases[tc_i];
+
+       f_vty_config3(MSCVTY, {"network"}, tc.net_config);
+
+       var BSC_ConnHdlrPars pars := f_init_pars(42300 + tc_i);
+       pars.net := tc;
+
+       var BSC_ConnHdlr vc_conn;
+       vc_conn := f_start_handler_with_pars(refers(f_tc_auth_options), pars);
+       vc_conn.done;
+}
+
+testcase TC_auth_options_0() runs on MTC_CT {
+       f_TC_auth_options(0);
+}
+
+testcase TC_auth_options_1() runs on MTC_CT {
+       f_TC_auth_options(1);
+}
+
+testcase TC_auth_options_2() runs on MTC_CT {
+       f_TC_auth_options(2);
+}
+
+testcase TC_auth_options_3() runs on MTC_CT {
+       f_TC_auth_options(3);
+}
+
+testcase TC_auth_options_4() runs on MTC_CT {
+       f_TC_auth_options(4);
+}
+
+testcase TC_auth_options_5() runs on MTC_CT {
+       f_TC_auth_options(5);
+}
+
+testcase TC_auth_options_6() runs on MTC_CT {
+       f_TC_auth_options(6);
+}
+
+testcase TC_auth_options_7() runs on MTC_CT {
+       f_TC_auth_options(7);
+}
+
+testcase TC_auth_options_8() runs on MTC_CT {
+       f_TC_auth_options(8);
+}
+
+testcase TC_auth_options_9() runs on MTC_CT {
+       f_TC_auth_options(9);
+}
+
+testcase TC_auth_options_10() runs on MTC_CT {
+       f_TC_auth_options(10);
+}
+
+testcase TC_auth_options_11() runs on MTC_CT {
+       f_TC_auth_options(11);
+}
+
 control {
        execute( TC_cr_before_reset() );
        execute( TC_lu_imsi_noauth_tmsi() );
@@ -7012,6 +7335,19 @@
        execute( TC_call_re_establishment_ciph() );

        execute( TC_cm_serv_wrong_mi() );
+
+       execute( TC_auth_options_0() );
+       execute( TC_auth_options_1() );
+       execute( TC_auth_options_2() );
+       execute( TC_auth_options_3() );
+       execute( TC_auth_options_4() );
+       execute( TC_auth_options_5() );
+       execute( TC_auth_options_6() );
+       execute( TC_auth_options_7() );
+       execute( TC_auth_options_8() );
+       execute( TC_auth_options_9() );
+       execute( TC_auth_options_10() );
+       execute( TC_auth_options_11() );
 }



--
To view, visit https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/29692
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Change-Id: I8e3b02ca83e56ef5349d85f08407509e19fa353c
Gerrit-Change-Number: 29692
Gerrit-PatchSet: 1
Gerrit-Owner: neels <nhofm...@sysmocom.de>
Gerrit-MessageType: newchange

Reply via email to