Remove Character Limit On "inkeys" For IAX2
authorMichael L. Young <elgueromexicano@gmail.com>
Fri, 17 May 2013 20:24:56 +0000 (20:24 +0000)
committerMichael L. Young <elgueromexicano@gmail.com>
Fri, 17 May 2013 20:24:56 +0000 (20:24 +0000)
Currently, the buffer for processing "inkeys" is limited to 256 characters.  If
the user has many keys and the names of those key files are long, the 256
character limit is not enough.

* Change inkeys buffer to be dynamic

(closes issue ASTERISK-21398)
Reported by: Pavel Kopchyk
Tested by: Pavel Kopchyk, Michael L. Young
Patches:
    asterisk-21398-iax2-inkeys-dynamic-buffer_v3.diff
by Michael L. Young (license 5026)

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

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

channels/chan_iax2.c

index 9cf7465..eeffb66 100644 (file)
@@ -6262,7 +6262,7 @@ static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_fr
                struct MD5Context md5;
                unsigned char digest[16];
                char *tmppw, *stringp;
-               
+
                tmppw = ast_strdupa(iaxs[callno]->secret);
                stringp = tmppw;
                while ((tmppw = strsep(&stringp, ";"))) {
@@ -7824,10 +7824,13 @@ static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
        if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
                struct ast_key *key;
                char *keyn;
-               char tmpkey[256];
+               char *tmpkey;
                char *stringp=NULL;
-               ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
-               stringp=tmpkey;
+               if (!(tmpkey = ast_strdup(p->inkeys))) {
+                       ast_log(LOG_ERROR, "Unable to create a temporary string for parsing stored 'inkeys'\n");
+                       return res;
+               }
+               stringp = tmpkey;
                keyn = strsep(&stringp, ":");
                while(keyn) {
                        key = ast_key_get(keyn, AST_KEY_PUBLIC);
@@ -7838,11 +7841,12 @@ static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
                                ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
                        keyn = strsep(&stringp, ":");
                }
+               ast_free(tmpkey);
        } else if (p->authmethods & IAX_AUTH_MD5) {
                struct MD5Context md5;
                unsigned char digest[16];
                char *tmppw, *stringp;
-               
+
                tmppw = ast_strdupa(p->secret);
                stringp = tmppw;
                while((tmppw = strsep(&stringp, ";"))) {
@@ -7945,10 +7949,13 @@ static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *
        /* Check secret against what we have on file */
        if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
                if (!ast_strlen_zero(p->inkeys)) {
-                       char tmpkeys[256];
+                       char *tmpkey;
                        char *stringp=NULL;
-                       ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
-                       stringp=tmpkeys;
+                       if (!(tmpkey = ast_strdup(p->inkeys))) {
+                               ast_log(LOG_ERROR, "Unable to create a temporary string for parsing stored 'inkeys'\n");
+                               goto return_unref;
+                       }
+                       stringp = tmpkey;
                        keyn = strsep(&stringp, ":");
                        while(keyn) {
                                key = ast_key_get(keyn, AST_KEY_PUBLIC);
@@ -7959,6 +7966,7 @@ static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *
                                        ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
                                keyn = strsep(&stringp, ":");
                        }
+                       ast_free(tmpkey);
                        if (!keyn) {
                                if (authdebug)
                                        ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
@@ -14579,9 +14587,14 @@ static int users_data_provider_get(const struct ast_data_search *search,
        struct ast_data *data_user, *data_authmethods, *data_enum_node;
        struct iax2_user *user;
        struct ao2_iterator i;
-       char auth[90];
+       struct ast_str *auth;
        char *pstr = "";
 
+       if (!(auth = ast_str_create(90))) {
+               ast_log(LOG_ERROR, "Unable to create temporary string for storing 'secret'\n");
+               return 0;
+       }
+
        i = ao2_iterator_init(users, 0);
        for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
                data_user = ast_data_add_node(data_root, "user");
@@ -14594,13 +14607,13 @@ static int users_data_provider_get(const struct ast_data_search *search,
                iax2_data_add_codecs(data_user, "codecs", user->capability);
 
                if (!ast_strlen_zero(user->secret)) {
-                       ast_copy_string(auth, user->secret, sizeof(auth));
+                       ast_str_set(&auth, 0, "%s", user->secret);
                } else if (!ast_strlen_zero(user->inkeys)) {
-                       snprintf(auth, sizeof(auth), "Key: %s", user->inkeys);
+                       ast_str_set(&auth, 0, "Key: %s", user->inkeys);
                } else {
-                       ast_copy_string(auth, "no secret", sizeof(auth));
+                       ast_str_set(&auth, 0, "no secret");
                }
-               ast_data_add_password(data_user, "secret", auth);
+               ast_data_add_password(data_user, "secret", ast_str_buffer(auth));
 
                ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT);
 
@@ -14640,6 +14653,7 @@ static int users_data_provider_get(const struct ast_data_search *search,
        }
        ao2_iterator_destroy(&i);
 
+       ast_free(auth);
        return 0;
 }