]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 98946 via svnmerge from
authorRussell Bryant <russell@russellbryant.com>
Tue, 15 Jan 2008 23:53:28 +0000 (23:53 +0000)
committerRussell Bryant <russell@russellbryant.com>
Tue, 15 Jan 2008 23:53:28 +0000 (23:53 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r98946 | russell | 2008-01-15 17:50:10 -0600 (Tue, 15 Jan 2008) | 11 lines

Change a buffer in check_auth() to be a thread local dynamically allocated
buffer, instead of a massive buffer on the stack.  This fixes a crash reported
by Qwell due to running out of stack space when building with LOW_MEMORY defined.

On a very related note, the usage of BUFSIZ in various places in chan_sip is
arbitrary and careless.  BUFSIZ is a system specific define.  On my machine,
it is 8192, but by definition (according to google) could be as small as 256.
So, this buffer in check_auth was 16 kB.  We don't even support SIP messages
larger than 4 kB!  Further usage of this define should be avoided, unless it
is used in the proper context.

........

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

channels/chan_sip.c

index 4018045f8402078dabb56bd72ead993ff89c9d0b..f9b64a02cfc0fb760ca71d9b77b724ff53444a88 100644 (file)
@@ -9167,6 +9167,8 @@ static void build_route(struct sip_pvt *p, struct sip_request *req, int backward
                list_route(p->route);
 }
 
+AST_THREADSTORAGE(check_auth_buf);
+#define CHECK_AUTH_BUF_INITLEN   256
 
 /*! \brief  Check user authorization from peer definition 
        Some actions, like REGISTER and INVITEs from peers require
@@ -9182,11 +9184,12 @@ static enum check_auth_result check_auth(struct sip_pvt *p, struct sip_request *
        const char *authtoken;
        char a1_hash[256];
        char resp_hash[256]="";
-       char tmp[BUFSIZ * 2];                /* Make a large enough buffer */
        char *c;
        int  wrongnonce = FALSE;
        int  good_response;
        const char *usednonce = p->randdata;
+       struct ast_str *buf;
+       int res;
 
        /* table of recognised keywords, and their value in the digest */
        enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST };
@@ -9241,10 +9244,16 @@ static enum check_auth_result check_auth(struct sip_pvt *p, struct sip_request *
        /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting
           an example in the spec of just what it is you're doing a hash on. */
 
+       if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN)))
+               return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
 
        /* Make a copy of the response and parse it */
-       ast_copy_string(tmp, authtoken, sizeof(tmp));
-       c = tmp;
+       res = ast_str_set(&buf, 0, "%s", authtoken);
+
+       if (res == AST_DYNSTR_BUILD_FAILED)
+               return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
+
+       c = buf->str;
 
        while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */
                for (i = keys; i->key != NULL; i++) {