]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
chan_iax2: Allow both secret and outkey at dial time
authorNaveen Albert <asterisk@phreaknet.org>
Tue, 26 Oct 2021 00:47:02 +0000 (00:47 +0000)
committerGeorge Joseph <gjoseph@digium.com>
Mon, 8 Nov 2021 17:27:00 +0000 (11:27 -0600)
Historically, the dial syntax for IAX2 has held that
an outkey (used only for RSA authenticated calls)
and a secret (used only for plain text and MD5 authenticated
calls, historically) were mutually exclusive, and thus
the same position in the dial string was used for both
values.

Now that encryption is possible with RSA authentication,
this poses a limitation, since encryption requires a
secret and RSA authentication requires an outkey. Thus,
the dial syntax is extended so that both a secret and
an outkey can be specified.

The new extended syntax is backwards compatible with the
old syntax. However, a secret can now be specified after
the outkey, or the outkey can be specified after the secret.
This makes it possible to spawn an encrypted RSA authenticated
call without a corresponding peer being predefined in iax.conf.

ASTERISK-29707 #close

Change-Id: I1f8149313ed760169d604afbb07720a8b07dd00e

channels/chan_iax2.c
doc/CHANGES-staging/chan_iax2_dial.txt [new file with mode: 0644]

index a5996cbdd4b51b09241d218b53dbc6693872e9d2..09c00963c3bc9ad38addbea947422768c5317979 100644 (file)
@@ -5035,6 +5035,8 @@ reject:
  */
 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
 {
+       char *outkey = NULL;
+
        if (ast_strlen_zero(data))
                return;
 
@@ -5057,7 +5059,8 @@ static void parse_dial_string(char *data, struct parsed_dial_string *pds)
        if (pds->username) {
                data = pds->username;
                pds->username = strsep(&data, ":");
-               pds->password = data;
+               pds->password = strsep(&data, ":");
+               outkey = data;
        }
 
        data = pds->peer;
@@ -5067,10 +5070,26 @@ static void parse_dial_string(char *data, struct parsed_dial_string *pds)
        /*
         * Check for a key name wrapped in [] in the password position.
         * If found, move it to the key field instead.
+        * Also allow for both key and secret to be specified, now that
+        * encryption is possible with RSA authentication.
         */
-       if (pds->password && (pds->password[0] == '[')) {
+       
+       if (pds->password && (pds->password[0] == '[')) { /* key (then maybe secret) */
                pds->key = ast_strip_quoted(pds->password, "[", "]");
-               pds->password = NULL;
+               if (ast_strlen_zero(outkey)) {
+                       pds->password = NULL;
+                       ast_debug(1, "Outkey (%s), no secret\n", pds->key);
+               } else {
+                       pds->password = outkey;
+                       ast_debug(1, "Outkey (%s) and secret (%s)\n", pds->key, pds->password);
+               }
+       } else if (outkey && (outkey[0] == '[')) { /* secret, then key */
+               pds->key = ast_strip_quoted(outkey, "[", "]");
+               if (ast_strlen_zero(pds->password)) {
+                       ast_debug(1, "Outkey (%s), no secret\n", pds->key);
+               } else {
+                       ast_debug(1, "Outkey (%s) and secret (%s)\n", pds->key, pds->password);
+               }
        }
 }
 
@@ -6468,7 +6487,7 @@ static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh,
        } else {
                struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
                if (iaxdebug)
-                       ast_debug(1, "Decoding mini with length %d\n", *datalen);
+                       ast_debug(5, "Decoding mini with length %d\n", *datalen);
                if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
                        return -1;
                /* Decrypt */
@@ -6506,7 +6525,7 @@ static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh,
        } else {
                struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
                if (iaxdebug)
-                       ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
+                       ast_debug(5, "Encoding mini frame with length %d\n", *datalen);
                padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
                padding = 16 + (padding & 0xf);
                memcpy(workspace, poo, padding);
@@ -11993,7 +12012,7 @@ immediatedial:
                iaxs[fr->callno]->last = fr->ts;
 #if 1
                if (iaxdebug)
-                       ast_debug(1, "For call=%d, set last=%u\n", fr->callno, fr->ts);
+                       ast_debug(3, "For call=%d, set last=%u\n", fr->callno, fr->ts);
 #endif
        }
 
diff --git a/doc/CHANGES-staging/chan_iax2_dial.txt b/doc/CHANGES-staging/chan_iax2_dial.txt
new file mode 100644 (file)
index 0000000..a95832b
--- /dev/null
@@ -0,0 +1,4 @@
+Subject: chan_iax2
+
+Both a secret and an outkey may be specified at dial time,
+since encryption is possible with RSA authentication.