]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Fix parsing of mwi => lines in sip.conf
authorBrad Watkins <Marquis42@gmail.com>
Fri, 17 Dec 2010 17:26:31 +0000 (17:26 +0000)
committerBrad Watkins <Marquis42@gmail.com>
Fri, 17 Dec 2010 17:26:31 +0000 (17:26 +0000)
Reworking parsing of mwi => lines to resolve a segfault.  Also add a set of unit tests for the function that does the parsing.

(closes issue #18350)
Reported by: gbour
Tested by: Marquis, gbour

Review: https://reviewboard.asterisk.org/r/1053/

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@298773 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_sip.c
configs/sip.conf.sample

index c9b0592586897e65d3fa3280f762bc7e79934fd8..6043e468be14ab427d7f95cfd75cd624a09a555a 100644 (file)
@@ -7571,36 +7571,39 @@ static int sip_subscribe_mwi(const char *value, int lineno)
        int portnum = 0;
        enum sip_transport transport = SIP_TRANSPORT_UDP;
        char buf[256] = "";
-       char *username = NULL, *hostname = NULL, *secret = NULL, *authuser = NULL, *porta = NULL, *mailbox = NULL;
-       
+       char *username = NULL, *hostname = NULL, *secret = NULL, *authuser = NULL, *porta = NULL, *mailbox = NULL, *at = NULL;
+
        if (!value) {
                return -1;
        }
-       
+
        ast_copy_string(buf, value, sizeof(buf));
 
-       sip_parse_host(buf, lineno, &username, &portnum, &transport);
-       
-       if ((hostname = strrchr(username, '@'))) {
+       if (!(at = strstr(buf, "@"))) {
+               return -1;
+       }
+
+       if ((hostname = strrchr(buf, '@'))) {
                *hostname++ = '\0';
+               username = buf;
        }
-       
+
        if ((secret = strchr(username, ':'))) {
                *secret++ = '\0';
                if ((authuser = strchr(secret, ':'))) {
                        *authuser++ = '\0';
                }
        }
-       
+
        if ((mailbox = strchr(hostname, '/'))) {
                *mailbox++ = '\0';
        }
 
        if (ast_strlen_zero(username) || ast_strlen_zero(hostname) || ast_strlen_zero(mailbox)) {
-               ast_log(LOG_WARNING, "Format for MWI subscription is user[:secret[:authuser]]@host[:port][/mailbox] at line %d\n", lineno);
+               ast_log(LOG_WARNING, "Format for MWI subscription is user[:secret[:authuser]]@host[:port]/mailbox at line %d\n", lineno);
                return -1;
        }
-       
+
        if ((porta = strchr(hostname, ':'))) {
                *porta++ = '\0';
                if (!(portnum = atoi(porta))) {
@@ -7608,11 +7611,11 @@ static int sip_subscribe_mwi(const char *value, int lineno)
                        return -1;
                }
        }
-       
+
        if (!(mwi = ast_calloc_with_stringfields(1, struct sip_subscription_mwi, 256))) {
                return -1;
        }
-       
+
        ASTOBJ_INIT(mwi);
        ast_string_field_set(mwi, username, username);
        if (secret) {
@@ -7626,10 +7629,10 @@ static int sip_subscribe_mwi(const char *value, int lineno)
        mwi->resub = -1;
        mwi->portno = portnum;
        mwi->transport = transport;
-       
+
        ASTOBJ_CONTAINER_LINK(&submwil, mwi);
        ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy);
-       
+
        return 0;
 }
 
@@ -28291,6 +28294,157 @@ static void sip_unregister_tests(void)
 }
 
 #ifdef TEST_FRAMEWORK
+AST_TEST_DEFINE(test_sip_mwi_subscribe_parse)
+{
+       int found = 0;
+       enum ast_test_result_state res = AST_TEST_PASS;
+       const char *mwi1 = "1234@mysipprovider.com/1234";
+       const char *mwi2 = "1234:password@mysipprovider.com/1234";
+       const char *mwi3 = "1234:password@mysipprovider.com:5061/1234";
+       const char *mwi4 = "1234:password:authuser@mysipprovider.com/1234";
+       const char *mwi5 = "1234:password:authuser@mysipprovider.com:5061/1234";
+       const char *mwi6 = "1234:password";
+
+       switch (cmd) {
+       case TEST_INIT:
+               info->name = "sip_mwi_subscribe_parse_test";
+               info->category = "/channels/chan_sip/";
+               info->summary = "SIP MWI subscribe line parse unit test";
+               info->description =
+                       "Tests the parsing of mwi subscription lines (e.g., mwi => from sip.conf)";
+               return AST_TEST_NOT_RUN;
+       case TEST_EXECUTE:
+               break;
+       }
+
+       if (sip_subscribe_mwi(mwi1, 1)) {
+               res = AST_TEST_FAIL;
+       } else {
+               found = 0;
+               res = AST_TEST_FAIL;
+               ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {
+                       ASTOBJ_WRLOCK(iterator);
+                       if (
+                               !strcmp(iterator->hostname, "mysipprovider.com") &&
+                               !strcmp(iterator->username, "1234") &&
+                               !strcmp(iterator->secret, "") &&
+                               !strcmp(iterator->authuser, "") &&
+                               !strcmp(iterator->mailbox, "1234") &&
+                               iterator->portno == 0) {
+                               found = 1;
+                               res = AST_TEST_PASS;
+                       }
+                       ASTOBJ_UNLOCK(iterator);
+               } while(0));
+               if (!found) {
+                       ast_test_status_update(test, "sip_subscribe_mwi test 1 failed\n");
+               }
+       }
+
+       if (sip_subscribe_mwi(mwi2, 1)) {
+               res = AST_TEST_FAIL;
+       } else {
+               found = 0;
+               res = AST_TEST_FAIL;
+               ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {
+                       ASTOBJ_WRLOCK(iterator);
+                       if (
+                               !strcmp(iterator->hostname, "mysipprovider.com") &&
+                               !strcmp(iterator->username, "1234") &&
+                               !strcmp(iterator->secret, "password") &&
+                               !strcmp(iterator->authuser, "") &&
+                               !strcmp(iterator->mailbox, "1234") &&
+                               iterator->portno == 0) {
+                               found = 1;
+                               res = AST_TEST_PASS;
+                       }
+                       ASTOBJ_UNLOCK(iterator);
+               } while(0));
+               if (!found) {
+                       ast_test_status_update(test, "sip_subscribe_mwi test 2 failed\n");
+               }
+       }
+
+       if (sip_subscribe_mwi(mwi3, 1)) {
+               res = AST_TEST_FAIL;
+       } else {
+               found = 0;
+               res = AST_TEST_FAIL;
+               ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {
+                       ASTOBJ_WRLOCK(iterator);
+                       if (
+                               !strcmp(iterator->hostname, "mysipprovider.com") &&
+                               !strcmp(iterator->username, "1234") &&
+                               !strcmp(iterator->secret, "password") &&
+                               !strcmp(iterator->authuser, "") &&
+                               !strcmp(iterator->mailbox, "1234") &&
+                               iterator->portno == 5061) {
+                               found = 1;
+                               res = AST_TEST_PASS;
+                       }
+                       ASTOBJ_UNLOCK(iterator);
+               } while(0));
+               if (!found) {
+                       ast_test_status_update(test, "sip_subscribe_mwi test 3 failed\n");
+               }
+       }
+
+       if (sip_subscribe_mwi(mwi4, 1)) {
+               res = AST_TEST_FAIL;
+       } else {
+               found = 0;
+               res = AST_TEST_FAIL;
+               ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {
+                       ASTOBJ_WRLOCK(iterator);
+                       if (
+                               !strcmp(iterator->hostname, "mysipprovider.com") &&
+                               !strcmp(iterator->username, "1234") &&
+                               !strcmp(iterator->secret, "password") &&
+                               !strcmp(iterator->authuser, "authuser") &&
+                               !strcmp(iterator->mailbox, "1234") &&
+                               iterator->portno == 0) {
+                               found = 1;
+                               res = AST_TEST_PASS;
+                       }
+                       ASTOBJ_UNLOCK(iterator);
+               } while(0));
+               if (!found) {
+                       ast_test_status_update(test, "sip_subscribe_mwi test 4 failed\n");
+               }
+       }
+
+       if (sip_subscribe_mwi(mwi5, 1)) {
+               res = AST_TEST_FAIL;
+       } else {
+               found = 0;
+               res = AST_TEST_FAIL;
+               ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {
+                       ASTOBJ_WRLOCK(iterator);
+                       if (
+                               !strcmp(iterator->hostname, "mysipprovider.com") &&
+                               !strcmp(iterator->username, "1234") &&
+                               !strcmp(iterator->secret, "password") &&
+                               !strcmp(iterator->authuser, "authuser") &&
+                               !strcmp(iterator->mailbox, "1234") &&
+                               iterator->portno == 5061) {
+                               found = 1;
+                               res = AST_TEST_PASS;
+                       }
+                       ASTOBJ_UNLOCK(iterator);
+               } while(0));
+               if (!found) {
+                       ast_test_status_update(test, "sip_subscribe_mwi test 5 failed\n");
+               }
+       }
+       
+       if (sip_subscribe_mwi(mwi6, 1)) {
+               res = AST_TEST_PASS;
+       } else {
+               res = AST_TEST_FAIL;
+       }
+       return res;
+}
+
 AST_TEST_DEFINE(test_sip_peers_get)
 {
        struct sip_peer *peer;
@@ -28567,6 +28721,7 @@ static int load_module(void)
 
 #ifdef TEST_FRAMEWORK
        AST_TEST_REGISTER(test_sip_peers_get);
+       AST_TEST_REGISTER(test_sip_mwi_subscribe_parse);
 #endif
 
        /* Register AstData providers */
@@ -28677,6 +28832,7 @@ static int unload_module(void)
 
 #ifdef TEST_FRAMEWORK
        AST_TEST_UNREGISTER(test_sip_peers_get);
+       AST_TEST_UNREGISTER(test_sip_mwi_subscribe_parse);
 #endif
        /* Unregister all the AstData providers */
        ast_data_unregister(NULL);
index 320895669677c38e1df8d81a362ff9a16259876e..03008b146a85b9b90778c6ceeeda0cf9b10711dd 100644 (file)
@@ -680,12 +680,15 @@ srvlookup=yes                   ; Enable DNS SRV lookups on outbound calls
 
 ;----------------------------------------- OUTBOUND MWI SUBSCRIPTIONS -------------------------
 ; Asterisk can subscribe to receive the MWI from another SIP server and store it locally for retrieval
-; by other phones.
+; by other phones. At this time, you can only subscribe using UDP as the transport.
 ; Format for the mwi register statement is:
-;       mwi => user[:secret[:authuser]]@host[:port][/mailbox]
+;       mwi => user[:secret[:authuser]]@host[:port]/mailbox
 ;
 ; Examples:
 ;mwi => 1234:password@mysipprovider.com/1234
+;mwi => 1234:password@myportprovider.com:6969/1234
+;mwi => 1234:password:authuser@myauthprovider.com/1234
+;mwi => 1234:password:authuser@myauthportprovider.com:6969/1234
 ;
 ; MWI received will be stored in the 1234 mailbox of the SIP_Remote context. It can be used by other phones by following the below:
 ; mailbox=1234@SIP_Remote