From c86e3827f94f4dff1e0910922aeb3ba96a1d1154 Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Wed, 14 Apr 2021 10:15:04 +0000 Subject: [PATCH] [mod_sofia] rfc8760: use different nonce per auth algorithm. [mod_sofia] keep unconsumed nonce in the db for 32 seconds (timer_t1x64) + nonce_ttl. [mod_sofia] add #ifdef condition on using sha512: OPENSSL_VERSION_NUMBER >= 0x10101000L --- src/mod/endpoints/mod_sofia/sofia_glue.c | 5 ++- src/mod/endpoints/mod_sofia/sofia_reg.c | 55 ++++++++++++++++-------- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 9a6a7acbd9..644848a010 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -2533,7 +2533,8 @@ int sofia_glue_init_sql(sofia_profile_t *profile) " expires BIGINT," " profile_name VARCHAR(255),\n" " hostname VARCHAR(255),\n" - " last_nc INTEGER\n" + " last_nc INTEGER,\n" + " algorithm INTEGER DEFAULT 1 NOT NULL\n" ");\n"; /* should we move this glue to sofia_sla or keep it here where all db init happens? XXX MTK */ @@ -2700,7 +2701,7 @@ int sofia_glue_init_sql(sofia_profile_t *profile) switch_cache_db_test_reactive(dbh, test_sql, "DROP TABLE sip_presence", pres_sql); free(test_sql); - test_sql = switch_mprintf("delete from sip_authentication where hostname='%q' or last_nc >= 0", mod_sofia_globals.hostname); + test_sql = switch_mprintf("delete from sip_authentication where hostname='%q' or last_nc >= 0 or algorithm >= 0", mod_sofia_globals.hostname); switch_cache_db_test_reactive(dbh, test_sql, "DROP TABLE sip_authentication", auth_sql); diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 49dc8feeda..ae301e9e50 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -1129,8 +1129,10 @@ static char * sofia_alg_to_str(sofia_auth_algs_t alg) { if (alg == ALG_SHA256) return "SHA-256"; +#if OPENSSL_VERSION_NUMBER >= 0x10101000L if (alg == ALG_SHA512) return "SHA-512-256"; +#endif return "MD5"; } @@ -1148,25 +1150,37 @@ void sofia_reg_auth_challenge(sofia_profile_t *profile, nua_handle_t *nh, sofia_ msg = de->data->e_msg; } - switch_uuid_get(&uuid); - switch_uuid_format(uuid_str, &uuid); - - sql = switch_mprintf("insert into sip_authentication (nonce,expires,profile_name,hostname, last_nc) " - "values('%q', %ld, '%q', '%q', 0)", uuid_str, - (long) switch_epoch_time_now(NULL) + (profile->nonce_ttl ? profile->nonce_ttl : DEFAULT_NONCE_TTL) + exptime, - profile->name, mod_sofia_globals.hostname); - switch_assert(sql != NULL); - sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); - if (!profile->rfc8760_algs_count) { + switch_uuid_get(&uuid); + switch_uuid_format(uuid_str, &uuid); + + sql = switch_mprintf("insert into sip_authentication (nonce,expires,profile_name,hostname, last_nc) " + "values('%q', %ld, '%q', '%q', 0)", uuid_str, + (long) switch_epoch_time_now(NULL) + (profile->nonce_ttl ? profile->nonce_ttl : DEFAULT_NONCE_TTL) + profile->timer_t1x64 / 1000, + profile->name, mod_sofia_globals.hostname); + switch_assert(sql != NULL); + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + auth_str = switch_mprintf("Digest realm=\"%q\", nonce=\"%q\",%s algorithm=MD5, qop=\"auth\"", realm, uuid_str, stale ? " stale=true," : ""); } else { int i; - for (i = 0 ; i < profile->rfc8760_algs_count; i++) { - if (profile->auth_algs[i] != ALG_NONE) { - auth_str_rfc8760[i] = switch_mprintf("Digest realm=\"%q\", nonce=\"%q\",%s algorithm=%s, qop=\"auth\"", realm, uuid_str, stale ? " stale=true," : "", sofia_alg_to_str(profile->auth_algs[i])); - } + char *sql_build; + switch_stream_handle_t stream = { 0 }; + + SWITCH_STANDARD_STREAM(stream); + for (i = 0; i < profile->rfc8760_algs_count; i++) { + switch_uuid_get(&uuid); + switch_uuid_format(uuid_str, &uuid); + sql_build = switch_mprintf("insert into sip_authentication (nonce,expires,profile_name,hostname, last_nc, algorithm) " + "values('%s', %ld, '%q', '%q', 0, %d)", uuid_str, + (long) switch_epoch_time_now(NULL) + (profile->nonce_ttl ? profile->nonce_ttl : DEFAULT_NONCE_TTL) + profile->timer_t1x64 / 1000, + profile->name, mod_sofia_globals.hostname, profile->auth_algs[i]); + + auth_str_rfc8760[i] = switch_mprintf("Digest realm=\"%q\", nonce=\"%q\",%s algorithm=%s, qop=\"auth\"", realm, uuid_str, stale ? " stale=true," : "", sofia_alg_to_str(profile->auth_algs[i])); + stream.write_function(&stream, "%s%s", i ? ";" : "", sql_build); + switch_safe_free(sql_build); } + sofia_glue_execute_sql_now(profile, (char **)&stream.data, SWITCH_TRUE); } if (regtype == REG_REGISTER) { @@ -2931,11 +2945,12 @@ sofia_auth_algs_t sofia_alg_str2id(char *algorithm, switch_bool_t permissive) if (!strcasecmp(algorithm, "SHA-256") || (permissive && !strcasecmp(algorithm, "SHA256"))) { return ALG_SHA256; } +#if OPENSSL_VERSION_NUMBER >= 0x10101000L if (!strcasecmp(algorithm, "SHA-512-256") || (permissive && !strcasecmp(algorithm, "SHA512")) || (permissive && !strcasecmp(algorithm, "SHA512-256")) || (permissive && !strcasecmp(algorithm, "SHA-512"))) { return ALG_SHA512; } - +#endif return ALG_NONE; } @@ -2949,9 +2964,11 @@ switch_status_t sofia_make_digest(sofia_auth_algs_t use_alg, char **digest, cons case ALG_SHA256: switch_digest_string("sha256", digest, input, strlen((char *)input), outputlen); break; +#if OPENSSL_VERSION_NUMBER >= 0x10101000L case ALG_SHA512: switch_digest_string("sha512-256", digest, input, strlen((char *)input), outputlen); break; +#endif default: return SWITCH_STATUS_FALSE; } @@ -3536,7 +3553,11 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, end: - if (nc && cnonce && qop) { + if (nc && cnonce && qop && ret == AUTH_OK) { + ret = AUTH_RENEWED; + } + + if (((ret == AUTH_OK) || (ret == AUTH_RENEWED)) && nc) { ncl = strtoul(nc, 0, 16); sql = switch_mprintf("update sip_authentication set expires='%ld',last_nc=%lu where nonce='%q'", @@ -3545,8 +3566,6 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, switch_assert(sql != NULL); sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); - if (ret == AUTH_OK) - ret = AUTH_RENEWED; } switch_event_destroy(¶ms);