From: Arran Cudbard-Bell Date: Wed, 6 Dec 2017 22:39:57 +0000 (+0000) Subject: Change xlats to work on the username portion only X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=75634c6fd628184203953df9eaebd7dc77aebedb;p=thirdparty%2Ffreeradius-server.git Change xlats to work on the username portion only as required by the 3gpp standard --- diff --git a/src/modules/rlm_eap/lib/sim/id.c b/src/modules/rlm_eap/lib/sim/id.c index 229b89e2ab8..10a4baaecee 100644 --- a/src/modules/rlm_eap/lib/sim/id.c +++ b/src/modules/rlm_eap/lib/sim/id.c @@ -143,14 +143,14 @@ ssize_t fr_sim_3gpp_root_nai_domain_mcc_mnc(uint16_t *mnc, uint16_t *mcc, * See #fr_sim_id_user_len. * @return Length of the ID written to out. */ -int fr_sim_id_type(fr_sim_id_type_t *type, fr_sim_method_hint_t *hint, - char const *id, size_t id_len) +int fr_sim_id_type(fr_sim_id_type_t *type, fr_sim_method_hint_t *hint, char const *id, size_t id_len) { size_t i; if (id_len < 1) { *hint = SIM_METHOD_HINT_UNKNOWN; *type = SIM_ID_TYPE_UNKNOWN; + fr_strerror_printf("ID length too short"); return -1; } @@ -163,7 +163,6 @@ int fr_sim_id_type(fr_sim_id_type_t *type, fr_sim_method_hint_t *hint, if (i == id_len) { switch (id[0]) { - case SIM_ID_TAG_PERMANENT_SIM: *hint = SIM_METHOD_HINT_SIM; *type = SIM_ID_TYPE_PERMANENT; /* All digits */ @@ -226,6 +225,7 @@ int fr_sim_id_type(fr_sim_id_type_t *type, fr_sim_method_hint_t *hint, default: *hint = SIM_METHOD_HINT_UNKNOWN; *type = SIM_ID_TYPE_UNKNOWN; + fr_strerror_printf("Unrecognised tag '%c'", id[0]); return -1; } } @@ -273,7 +273,7 @@ int fr_sim_id_3gpp_pseudonym_encrypt(char out[SIM_3GPP_PSEUDONYM_LEN + 1], fr_strerror_printf("Invalid tag value, expected value between 0-63, got %u", tag); return -1; } - if (unlikely(imsi_len != 15)) { + if (unlikely(imsi_len != SIM_IMSI_MAX_LEN)) { fr_strerror_printf("Invalid ID len, expected length of 15, got %zu", imsi_len); return -1; } @@ -451,7 +451,7 @@ int fr_sim_id_3gpp_pseudonym_decrypt(char out[SIM_IMSI_MAX_LEN + 1], for (i = 0; i < SIM_3GPP_PSEUDONYM_LEN; i++) { if (!fr_is_base64(encr_id[i])) { - fr_strerror_printf("Encrypted IMSI contains non-base64 char"); + fr_strerror_printf("Encrypted IMSI contains non-base64 char '%c'", encr_id[i]); return -1; } } diff --git a/src/modules/rlm_eap/lib/sim/xlat.c b/src/modules/rlm_eap/lib/sim/xlat.c index 6d58420f123..d03c9ec8f8d 100644 --- a/src/modules/rlm_eap/lib/sim/xlat.c +++ b/src/modules/rlm_eap/lib/sim/xlat.c @@ -37,7 +37,7 @@ static ssize_t sim_xlat_id_method(TALLOC_CTX *ctx, char **out, UNUSED size_t out { vp_tmpl_t *vpt; TALLOC_CTX *our_ctx = talloc_init("sim_xlat"); - ssize_t slen, len, id_len; + ssize_t slen, id_len; char const *p = fmt, *id, *method; fr_sim_id_type_t type_hint; fr_sim_method_hint_t method_hint; @@ -62,13 +62,7 @@ static ssize_t sim_xlat_id_method(TALLOC_CTX *ctx, char **out, UNUSED size_t out } id_len = talloc_array_length(id) - 1; - len = fr_sim_id_user_len(id, id_len); - if (len == id_len ) { - RPEDEBUG2("SIM ID \"%pS\" is not an NAI", id); - goto error; - } - - if (fr_sim_id_type(&type_hint, &method_hint, id, len) < 0) { + if (fr_sim_id_type(&type_hint, &method_hint, id, id_len) < 0) { RPEDEBUG2("SIM ID \"%pS\" has unrecognised format", id); goto error; } @@ -100,7 +94,7 @@ static ssize_t sim_xlat_id_type(TALLOC_CTX *ctx, char **out, UNUSED size_t outle { vp_tmpl_t *vpt; TALLOC_CTX *our_ctx = talloc_init("sim_xlat"); - ssize_t slen, user_len, id_len; + ssize_t slen, id_len; char const *p = fmt, *id, *method; fr_sim_id_type_t type_hint; fr_sim_method_hint_t method_hint; @@ -125,13 +119,7 @@ static ssize_t sim_xlat_id_type(TALLOC_CTX *ctx, char **out, UNUSED size_t outle } id_len = talloc_array_length(id) - 1; - user_len = fr_sim_id_user_len(id, id_len); - if (user_len == id_len ) { - RPEDEBUG2("SIM ID \"%pS\" is not an NAI", id); - goto error; - } - - if (fr_sim_id_type(&type_hint, &method_hint, id, user_len) < 0) { + if (fr_sim_id_type(&type_hint, &method_hint, id, id_len) < 0) { RPEDEBUG2("SIM ID \"%pS\" has unrecognised format", id); goto error; } @@ -164,7 +152,7 @@ static ssize_t sim_xlat_3gpp_pseudonym_key_index(TALLOC_CTX *ctx, char **out, UN { vp_tmpl_t *vpt; TALLOC_CTX *our_ctx = talloc_init("sim_xlat"); - ssize_t slen, user_len, id_len; + ssize_t slen, id_len; char const *p = fmt, *id; /* @@ -186,10 +174,9 @@ static ssize_t sim_xlat_3gpp_pseudonym_key_index(TALLOC_CTX *ctx, char **out, UN } id_len = talloc_array_length(id) - 1; - user_len = fr_sim_id_user_len(id, id_len); - if (user_len != SIM_3GPP_PSEUDONYM_LEN) { + if (id_len != SIM_3GPP_PSEUDONYM_LEN) { REDEBUG2("3gpp pseudonym incorrect length, expected %i bytes, got %zu bytes", - SIM_3GPP_PSEUDONYM_LEN, user_len); + SIM_3GPP_PSEUDONYM_LEN, id_len); goto error; } @@ -199,18 +186,13 @@ static ssize_t sim_xlat_3gpp_pseudonym_key_index(TALLOC_CTX *ctx, char **out, UN return talloc_array_length(*out) - 1; } -/** Decrypts a 3gpp pseudonym - * - * %{sim_id_3gpp_pseudonym_decrypt_nai:&id_attr &key_attr} - * - */ -static ssize_t sim_xlat_3gpp_pseudonym_decrypt_nai(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen, - UNUSED void const *mod_inst, UNUSED void const *xlat_inst, - REQUEST *request, char const *fmt) +static ssize_t sim_xlat_3gpp_pseudonym_decrypt(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen, + UNUSED void const *mod_inst, UNUSED void const *xlat_inst, + REQUEST *request, char const *fmt) { vp_tmpl_t *id_vpt, *key_vpt; TALLOC_CTX *our_ctx = talloc_init("sim_xlat"); - ssize_t slen, user_len, id_len, key_len; + ssize_t slen, id_len, key_len; uint8_t tag; char out_tag; uint8_t *key; @@ -255,10 +237,9 @@ static ssize_t sim_xlat_3gpp_pseudonym_decrypt_nai(TALLOC_CTX *ctx, char **out, } id_len = talloc_array_length(id); - user_len = fr_sim_id_user_len(id, id_len); - if (user_len != SIM_3GPP_PSEUDONYM_LEN) { + if (id_len != (SIM_3GPP_PSEUDONYM_LEN + 1)) { REDEBUG2("3gpp pseudonym incorrect length, expected %i bytes, got %zu bytes", - SIM_3GPP_PSEUDONYM_LEN, user_len); + SIM_3GPP_PSEUDONYM_LEN + 1, id_len); return -1; } @@ -287,16 +268,16 @@ static ssize_t sim_xlat_3gpp_pseudonym_decrypt_nai(TALLOC_CTX *ctx, char **out, return -1; } - RDEBUG2("Decrypting \"%.*s\"", (int)user_len, id); + RDEBUG2("Decrypting \"%pS\"", id); if (fr_sim_id_3gpp_pseudonym_decrypt(decrypted, id, key) < 0) { RPEDEBUG2("Failed decrypting SIM ID"); return -1; } /* - * Recombine unencrypted IMSI with @domain + * Recombine unencrypted IMSI with tag */ - MEM(*out = talloc_typed_asprintf(ctx, "%c%s%s", out_tag, decrypted, id + user_len)); + MEM(*out = talloc_typed_asprintf(ctx, "%c%s", out_tag, decrypted)); talloc_free(our_ctx); return talloc_array_length(*out) - 1; @@ -307,13 +288,13 @@ static ssize_t sim_xlat_3gpp_pseudonym_decrypt_nai(TALLOC_CTX *ctx, char **out, * %{sim_id_3gpp_pseudonym_encrypt:&id_attr &key_attr key_index} * */ -static ssize_t sim_xlat_3gpp_pseudonym_encrypt_nai(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen, - UNUSED void const *mod_inst, UNUSED void const *xlat_inst, - REQUEST *request, char const *fmt) +static ssize_t sim_xlat_3gpp_pseudonym_encrypt(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen, + UNUSED void const *mod_inst, UNUSED void const *xlat_inst, + REQUEST *request, char const *fmt) { vp_tmpl_t *id_vpt, *key_vpt; TALLOC_CTX *our_ctx = talloc_init("sim_xlat"); - ssize_t slen, user_len, id_len, key_len; + ssize_t slen, id_len, key_len; uint8_t *key, tag = 0; unsigned long key_index; char encrypted[SIM_3GPP_PSEUDONYM_LEN + 1]; @@ -371,14 +352,6 @@ static ssize_t sim_xlat_3gpp_pseudonym_encrypt_nai(TALLOC_CTX *ctx, char **out, goto error; } - id_len = talloc_array_length(id) - 1; - user_len = fr_sim_id_user_len(id, id_len); - if (user_len > (SIM_IMSI_MAX_LEN + 1)) { /* +1 for tag */ - REDEBUG2("3gpp pseudonym incorrect length, expected less than %i bytes, got %zu bytes", - SIM_IMSI_MAX_LEN + 1, user_len); - return -1; - } - /* * Get the key */ @@ -397,7 +370,14 @@ static ssize_t sim_xlat_3gpp_pseudonym_encrypt_nai(TALLOC_CTX *ctx, char **out, * Determine what type/method hints are in * the current ID. */ - if (fr_sim_id_type(&type_hint, &method_hint, id, user_len) < 0) { + id_len = talloc_array_length(id) - 1; + if (id_len != (SIM_IMSI_MAX_LEN + 1)) { /* +1 for ID tag */ + REDEBUG2("IMSI incorrect length, expected %i bytes, got %zu bytes", + SIM_IMSI_MAX_LEN + 1, id_len); + return -1; + } + + if (fr_sim_id_type(&type_hint, &method_hint, id, id_len) < 0) { RPEDEBUG2("SIM ID \"%pS\" has unrecognised format", id); goto error; } @@ -430,15 +410,12 @@ static ssize_t sim_xlat_3gpp_pseudonym_encrypt_nai(TALLOC_CTX *ctx, char **out, * * Strip existing tag from the permanent id */ - if (fr_sim_id_3gpp_pseudonym_encrypt(encrypted, id + 1, user_len - 1, tag, (uint8_t)key_index, key) < 0) { + if (fr_sim_id_3gpp_pseudonym_encrypt(encrypted, id + 1, id_len - 1, tag, (uint8_t)key_index, key) < 0) { RPEDEBUG2("Failed encrypting SIM ID \"%pS\"", id); return -1; } - /* - * Recombine encrypted IMSI with @domain - */ - MEM(*out = talloc_typed_asprintf(ctx, "%s%s", encrypted, id + user_len)); + MEM(*out = talloc_typed_asprintf(ctx, "%s", encrypted)); talloc_free(our_ctx); return talloc_array_length(*out) - 1; @@ -455,10 +432,10 @@ void sim_xlat_register(void) xlat_register(NULL, "sim_id_type", sim_xlat_id_type, NULL, NULL, 0, 0, true); xlat_register(NULL, "3gpp_pseudonym_key_index", sim_xlat_3gpp_pseudonym_key_index, NULL, NULL, 0, 0, true); - xlat_register(NULL, "3gpp_pseudonym_decrypt_nai", - sim_xlat_3gpp_pseudonym_decrypt_nai, NULL, NULL, 0, 0, true); - xlat_register(NULL, "3gpp_pseudonym_encrypt_nai", - sim_xlat_3gpp_pseudonym_encrypt_nai, NULL, NULL, 0, 0, true); + xlat_register(NULL, "3gpp_pseudonym_decrypt", + sim_xlat_3gpp_pseudonym_decrypt, NULL, NULL, 0, 0, true); + xlat_register(NULL, "3gpp_pseudonym_encrypt", + sim_xlat_3gpp_pseudonym_encrypt, NULL, NULL, 0, 0, true); sim_xlat_refs = 1; } @@ -472,7 +449,7 @@ void sim_xlat_unregister(void) xlat_unregister("sim_id_method"); xlat_unregister("sim_id_type"); xlat_unregister("3gpp_pseudonym_key_index"); - xlat_unregister("3gpp_pseudonym_decrypt_nai"); - xlat_unregister("3gpp_pseudonym_encrypt_nai"); + xlat_unregister("3gpp_pseudonym_decrypt"); + xlat_unregister("3gpp_pseudonym_encrypt"); sim_xlat_refs = 0; } diff --git a/src/tests/modules/eap_sim/sim_xlat_id_aka.attrs b/src/tests/modules/eap_sim/sim_xlat_id_aka.attrs index 7723ccbcced..678d57bf7fa 100644 --- a/src/tests/modules/eap_sim/sim_xlat_id_aka.attrs +++ b/src/tests/modules/eap_sim/sim_xlat_id_aka.attrs @@ -1,7 +1,7 @@ # # Input packet # -User-Name = "0420032219455258@wlan.mnc003.mcc420.3gppnetwork.org" +User-Name = "0420032219455258" # # Expected answer diff --git a/src/tests/modules/eap_sim/sim_xlat_id_aka.unlang b/src/tests/modules/eap_sim/sim_xlat_id_aka.unlang index 3c12a8333d6..935326c6196 100644 --- a/src/tests/modules/eap_sim/sim_xlat_id_aka.unlang +++ b/src/tests/modules/eap_sim/sim_xlat_id_aka.unlang @@ -14,10 +14,10 @@ if ("%{sim_id_type:&User-Name}" != 'Permanent') { # Encrypt the permanent ID # update control { - Tmp-String-0 := '1234567812345678' + Tmp-String-0 := '1420032219455258' } update control { - User-Name := "%{3gpp_pseudonym_encrypt_nai:&User-Name &control:Tmp-String-0 6}" + User-Name := "%{3gpp_pseudonym_encrypt:&User-Name &control:Tmp-String-0 6}" } # @@ -41,7 +41,7 @@ if ("%{sim_id_type:&control:User-Name}" != 'Pseudonym') { # # We should refuse to re-encrypt an encrypted NAI # -if ("%{3gpp_pseudonym_encrypt_nai:&control:User-Name &control:Tmp-String-0 6}" != '') { +if ("%{3gpp_pseudonym_encrypt:&control:User-Name &control:Tmp-String-0 6}" != '') { test_fail } else { test_pass @@ -51,7 +51,7 @@ if ("%{3gpp_pseudonym_encrypt_nai:&control:User-Name &control:Tmp-String-0 6}" ! # Get the original IMSI back again # update control { - Tmp-String-1 := "%{3gpp_pseudonym_decrypt_nai:&control:User-Name &control:Tmp-String-0}" + Tmp-String-1 := "%{3gpp_pseudonym_decrypt:&control:User-Name &control:Tmp-String-0}" } if (&control:Tmp-String-1 != &User-Name) { diff --git a/src/tests/modules/eap_sim/sim_xlat_id_error.unlang b/src/tests/modules/eap_sim/sim_xlat_id_error.unlang index 0da78e62207..a50b5bb4402 100644 --- a/src/tests/modules/eap_sim/sim_xlat_id_error.unlang +++ b/src/tests/modules/eap_sim/sim_xlat_id_error.unlang @@ -2,7 +2,7 @@ # No domain separator # update request { - User-Name := '1420032219455258wlan.mnc003.mcc420.3gppnetwork.org' + User-Name := '14200322194552581' } if ("%{sim_id_method:&User-Name}" != '') { diff --git a/src/tests/modules/eap_sim/sim_xlat_id_sim.attrs b/src/tests/modules/eap_sim/sim_xlat_id_sim.attrs index 272590d8e12..8ea2eb8a0b9 100644 --- a/src/tests/modules/eap_sim/sim_xlat_id_sim.attrs +++ b/src/tests/modules/eap_sim/sim_xlat_id_sim.attrs @@ -1,7 +1,7 @@ # # Input packet # -User-Name = "1420032219455258@wlan.mnc003.mcc420.3gppnetwork.org" +User-Name = "1420032219455258" # # Expected answer diff --git a/src/tests/modules/eap_sim/sim_xlat_id_sim.unlang b/src/tests/modules/eap_sim/sim_xlat_id_sim.unlang index 52fe29ed7db..463cafb24ac 100644 --- a/src/tests/modules/eap_sim/sim_xlat_id_sim.unlang +++ b/src/tests/modules/eap_sim/sim_xlat_id_sim.unlang @@ -17,7 +17,7 @@ update control { Tmp-String-0 := '1234567812345678' } update control { - User-Name := "%{3gpp_pseudonym_encrypt_nai:&User-Name &control:Tmp-String-0 6}" + User-Name := "%{3gpp_pseudonym_encrypt:&User-Name &control:Tmp-String-0 6}" } # @@ -41,7 +41,7 @@ if ("%{sim_id_type:&control:User-Name}" != 'Pseudonym') { # # We should refuse to re-encrypt an encrypted NAI # -if ("%{3gpp_pseudonym_encrypt_nai:&control:User-Name &control:Tmp-String-0 6}" != '') { +if ("%{3gpp_pseudonym_encrypt:&control:User-Name &control:Tmp-String-0 6}" != '') { test_fail } else { test_pass