]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
use nonce count with registration
authorAnthony Minessale <anthony.minessale@gmail.com>
Wed, 28 Oct 2009 16:55:29 +0000 (16:55 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Wed, 28 Oct 2009 16:55:29 +0000 (16:55 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@15260 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/mod/endpoints/mod_sofia/mod_sofia.h
src/mod/endpoints/mod_sofia/sofia_glue.c
src/mod/endpoints/mod_sofia/sofia_reg.c

index 69f0fb072fa501c628a719de49abdb37f4563433..9bb68bee3d4472042423764acb001863b036d284 100644 (file)
@@ -37,7 +37,7 @@
 /*Defines etc..*/
 /*************************************************************************************************************************************************************/
 #define MANUAL_BYE
-
+#define DEFAULT_NONCE_TTL 60
 #define IREG_SECONDS 30
 #define GATEWAY_SECONDS 1
 #define SOFIA_QUEUE_SIZE 50000
index 97d34e9e2a9b4061d76f8e11f35e713b82d76742..926ee9cd9f060a8cadcb9e04cd973207b7cfb5b5 100644 (file)
@@ -3685,7 +3685,8 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
                "   nonce           VARCHAR(255),\n" 
                "   expires         INTEGER," 
                "   profile_name    VARCHAR(255),\n"
-               "   hostname        VARCHAR(255)\n"
+               "   hostname        VARCHAR(255),\n"
+               "   last_nc         INTEGER\n"
                ");\n";
 
        /* should we move this glue to sofia_sla or keep it here where all db init happens? XXX MTK */
@@ -3799,7 +3800,7 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
                }
 
                free(test_sql);
-               test_sql = switch_mprintf("delete from sip_authentication where hostname='%q'", mod_sofia_globals.hostname);
+               test_sql = switch_mprintf("delete from sip_authentication where hostname='%q' and last_nc >= 0", mod_sofia_globals.hostname);
 
                if (switch_odbc_handle_exec(profile->master_odbc, test_sql, NULL) != SWITCH_ODBC_SUCCESS) {
                        switch_odbc_handle_exec(profile->master_odbc, "DROP TABLE sip_authentication", NULL);
@@ -3857,7 +3858,7 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
                switch_core_db_test_reactive(profile->master_db, test_sql, "DROP TABLE sip_presence", pres_sql);
                free(test_sql);
 
-               test_sql = switch_mprintf("delete from sip_authentication where hostname='%q'", mod_sofia_globals.hostname);
+               test_sql = switch_mprintf("delete from sip_authentication where hostname='%q' and last_nc >= 0", mod_sofia_globals.hostname);
                switch_core_db_test_reactive(profile->master_db, test_sql, "DROP TABLE sip_authentication", auth_sql);
                free(test_sql);
 
index 33c81fbe3bea323fda98d24115bcd3c9c2a9e4da..4935ef7361ff34b5ffb96f6968bebebd97cba7a0 100644 (file)
@@ -681,8 +681,10 @@ void sofia_reg_auth_challenge(nua_t *nua, sofia_profile_t *profile, nua_handle_t
        switch_uuid_get(&uuid);
        switch_uuid_format(uuid_str, &uuid);
 
-       sql = switch_mprintf("insert into sip_authentication (nonce,expires,profile_name,hostname) "
-                                                "values('%q', %ld, '%q', '%q')", uuid_str, switch_epoch_time_now(NULL) + profile->nonce_ttl, profile->name, mod_sofia_globals.hostname);
+       sql = switch_mprintf("insert into sip_authentication (nonce,expires,profile_name,hostname, last_nc) "
+                                                "values('%q', %ld, '%q', '%q', 0)", uuid_str, 
+                                                switch_epoch_time_now(NULL) + (profile->nonce_ttl ? profile->nonce_ttl : DEFAULT_NONCE_TTL), 
+                                                profile->name, mod_sofia_globals.hostname);
        switch_assert(sql != NULL);
        sofia_glue_actually_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
        switch_safe_free(sql);
@@ -1567,6 +1569,25 @@ void sofia_reg_handle_sip_r_challenge(int status,
 
 }
 
+static unsigned long get_nc(const char *nc, sip_t const *sip)
+{
+       unsigned long x;
+       const char *ua = NULL;
+
+       if (sip->sip_user_agent) {
+               ua = sip->sip_user_agent->g_string;
+       }
+
+       /* sigh, polycom sends nc in base-10 rather than spec which says base-16*/
+       if (ua && switch_stristr("polycom", ua)) {
+               x = strtoul(nc, 0, 10);
+       } else {
+               x = strtoul(nc, 0, 16);
+       }
+
+       return x;
+}
+
 auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, 
                                                                sip_authorization_t const *authorization, 
                                                                sip_t const *sip, 
@@ -1658,7 +1679,15 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
 
        if (zstr(np)) {
                first = 1;
-               sql = switch_mprintf("select nonce from sip_authentication where nonce='%q'", nonce);
+               if (nc) {
+                       unsigned long x;
+
+                       x = get_nc(nc, sip);
+                       sql = switch_mprintf("select nonce from sip_authentication where nonce='%q' and last_nc + 1 >= %lu", nonce, x);
+               } else {
+                       sql = switch_mprintf("select nonce from sip_authentication where nonce='%q'", nonce);
+               }
+
                switch_assert(sql != NULL);
                if (!sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, np, nplen)) {
                        free(sql);
@@ -1885,15 +1914,15 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
                input2 = switch_mprintf("%s:%s:%s", a1_hash, nonce, uridigest);
        }
 
-       switch_assert(input2);
-
-       memset(&ctx, 0, sizeof(ctx));
-       su_md5_init(&ctx);
-       su_md5_strupdate(&ctx, input2);
-       su_md5_hexdigest(&ctx, bigdigest);
-       su_md5_deinit(&ctx);
+       if (input2) {
+               memset(&ctx, 0, sizeof(ctx));
+               su_md5_init(&ctx);
+               su_md5_strupdate(&ctx, input2);
+               su_md5_hexdigest(&ctx, bigdigest);
+               su_md5_deinit(&ctx);
+       }
 
-       if (!strcasecmp(bigdigest, response)) {
+       if (input2 && !strcasecmp(bigdigest, response)) {
                ret = AUTH_OK;
        } else {
                if ((profile->ndlb & PFLAG_NDLB_BROKEN_AUTH_HASH) && strcasecmp(regstr, "REGISTER") && strcasecmp(regstr, "INVITE")) {
@@ -2047,6 +2076,22 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
        }
   end:
 
+
+       if (nc && cnonce && qop) {
+               unsigned long x;
+               char *sql;
+
+               x = get_nc(nc, sip);
+               input2 = switch_mprintf("%s:%s:%s:%s:%s:%s", a1_hash, nonce, nc, cnonce, qop, uridigest);
+
+               sql = switch_mprintf("update sip_authentication set expires='%ld',last_nc=%lu where nonce='%s'", 
+                                                        switch_epoch_time_now(NULL) + (profile->nonce_ttl ? profile->nonce_ttl : exptime + 10), x, nonce);
+
+               switch_assert(sql != NULL);
+               sofia_glue_actually_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
+               switch_safe_free(sql);
+       }
+
        switch_event_destroy(&params);
 
        if (xml) {