[Asterisk-code-review] chan_iax2.c: Require secret and auth method if encryption is enabled (asterisk[master])

George Joseph asteriskteam at digium.com
Tue Feb 9 09:16:10 CST 2021


George Joseph has submitted this change. ( https://gerrit.asterisk.org/c/asterisk/+/15403 )

Change subject: chan_iax2.c: Require secret and auth method if encryption is enabled
......................................................................

chan_iax2.c: Require secret and auth method if encryption is enabled

If there's no secret specified for an iax2 peer and there's no secret
specified in the dial string, Asterisk will crash if the auth method
requested by the peer is MD5 or plaintext.  You also couldn't specify
a default auth method in the [general] section of iax.conf so if you
don't have static peers defined and just use the dial string, Asterisk
will still crash even if you have a secret specified in the dial string.

* Added logic to iax2_call() and authenticate_reply() to print
  a warning and hanhup the call if encryption is requested and
  there's no secret or auth method.  This prevents the crash.

* Added the ability to specify a default "auth" in the [general]
  section of iax.conf.

ASTERISK-29624
Reported by: N A

Change-Id: I5928e16137581f7d383fcc7fa04ad96c919e6254
---
M channels/chan_iax2.c
M configs/samples/iax.conf.sample
A doc/CHANGES-staging/chan_iax2.txt
3 files changed, 44 insertions(+), 8 deletions(-)

Approvals:
  Kevin Harwell: Looks good to me, but someone else must approve
  George Joseph: Looks good to me, approved; Approved for Submit



diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 5a3ed80..2ecd689 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -433,6 +433,7 @@
 static int adsi = 0;
 static int delayreject = 0;
 static int iax2_encryption = 0;
+static int iax2_authmethods = 0;
 
 static struct ast_flags64 globalflags = { 0 };
 
@@ -4589,6 +4590,7 @@
 	struct iax2_codec_pref prefs;
 	int maxtime;
 	int encmethods;
+	int authmethods;
 	int found;
 	int sockfd;
 	int adsi;
@@ -4664,6 +4666,7 @@
 	cai->maxtime = peer->maxms;
 	cai->capability = peer->capability;
 	cai->encmethods = peer->encmethods;
+	cai->authmethods = peer->authmethods;
 	cai->sockfd = peer->sockfd;
 	cai->adsi = peer->adsi;
 	cai->prefs = peer->prefs;
@@ -5097,6 +5100,7 @@
 
 	memset(&cai, 0, sizeof(cai));
 	cai.encmethods = iax2_encryption;
+	cai.authmethods = iax2_authmethods;
 
 	memset(&pds, 0, sizeof(pds));
 	tmpstr = ast_strdupa(dest);
@@ -5113,15 +5117,21 @@
 		ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
 		return -1;
 	}
-	if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) && !cai.encmethods) {
-		ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n");
-		ast_channel_hangupcause_set(c, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
-		return -1;
+
+	if (ast_test_flag64(&cai, IAX_FORCE_ENCRYPT) ||
+		ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
+		if (!cai.encmethods) {
+			ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n");
+			ast_channel_hangupcause_set(c, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
+			return -1;
+		}
+		if (((cai.authmethods & IAX_AUTH_MD5) || (cai.authmethods & IAX_AUTH_PLAINTEXT)) &&
+			ast_strlen_zero(cai.secret) && ast_strlen_zero(pds.password)) {
+		        ast_log(LOG_WARNING, "Call terminated. Encryption forced but no secret provided\n");
+		        return -1;
+		}
 	}
-	if (ast_strlen_zero(cai.secret) && ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
-		ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n");
-		return -1;
-	}
+
 	if (!pds.username && !ast_strlen_zero(cai.username))
 		pds.username = cai.username;
 	if (!pds.password && !ast_strlen_zero(cai.secret))
@@ -8475,6 +8485,11 @@
 	}
 
 	if (ies->encmethods) {
+		if (ast_strlen_zero(p->secret) &&
+			((ies->authmethods & IAX_AUTH_MD5) || (ies->authmethods & IAX_AUTH_PLAINTEXT))) {
+			ast_log(LOG_WARNING, "Call terminated. Encryption requested by peer but no secret available locally\n");
+			return -1;
+		}
 		ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
 	} else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
 		ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set\n");
@@ -12813,6 +12828,7 @@
 		if (firstpass) {
 			ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
 			peer->encmethods = iax2_encryption;
+			peer->authmethods = iax2_authmethods;
 			peer->adsi = adsi;
 			ast_string_field_set(peer, secret, "");
 			if (!found) {
@@ -13146,6 +13162,7 @@
 			user->prefs = prefs_global;
 			user->capability = iax2_capability;
 			user->encmethods = iax2_encryption;
+			user->authmethods = iax2_authmethods;
 			user->adsi = adsi;
 			user->calltoken_required = CALLTOKEN_DEFAULT;
 			ast_string_field_set(user, name, name);
@@ -13538,6 +13555,7 @@
 	maxauthreq = 3;
 
 	srvlookup = 0;
+	iax2_authmethods = 0;
 
 	v = ast_variable_browse(cfg, "general");
 
@@ -13646,6 +13664,11 @@
 					ast_log(LOG_WARNING, "Invalid address '%s' specified, at line %d\n", v->value, v->lineno);
 				}
 			}
+		} else if (!strcasecmp(v->name, "auth")) {
+			iax2_authmethods = get_auth_methods(v->value);
+			if (iax2_authmethods & IAX_AUTH_PLAINTEXT) {
+				ast_log(LOG_WARNING, "Default auth method is set to deprecated 'plaintext' at line %d of iax.conf\n", v->lineno);
+			}
 		} else if (!strcasecmp(v->name, "authdebug")) {
 			authdebug = ast_true(v->value);
 		} else if (!strcasecmp(v->name, "encryption")) {
diff --git a/configs/samples/iax.conf.sample b/configs/samples/iax.conf.sample
index c6da461..1ee96ff 100644
--- a/configs/samples/iax.conf.sample
+++ b/configs/samples/iax.conf.sample
@@ -201,6 +201,15 @@
 ;resyncthreshold=1000
 ;jittertargetextra=40
 
+; There are three authentication methods that are supported:  md5, plaintext,
+; and rsa.  The least secure is "plaintext", which sends passwords cleartext
+; across the net.  "md5" uses a challenge/response md5 sum arrangement, but
+; still requires both ends have plain text access to the secret.  "rsa" allows
+; unidirectional secret knowledge through public/private keys.  There is no
+; default unless set here in the [general] section.
+;
+;auth=md5
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; IAX2 Encryption
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/doc/CHANGES-staging/chan_iax2.txt b/doc/CHANGES-staging/chan_iax2.txt
new file mode 100644
index 0000000..4e1d844
--- /dev/null
+++ b/doc/CHANGES-staging/chan_iax2.txt
@@ -0,0 +1,4 @@
+Subject: chan_iax2
+
+You can now specify a default "auth" method in the
+[general] section of iax.conf

-- 
To view, visit https://gerrit.asterisk.org/c/asterisk/+/15403
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Change-Id: I5928e16137581f7d383fcc7fa04ad96c919e6254
Gerrit-Change-Number: 15403
Gerrit-PatchSet: 6
Gerrit-Owner: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Benjamin Keith Ford <bford at digium.com>
Gerrit-Reviewer: Friendly Automation
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Joshua Colp <jcolp at sangoma.com>
Gerrit-Reviewer: Kevin Harwell <kharwell at digium.com>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20210209/3d8353db/attachment-0001.html>


More information about the asterisk-code-review mailing list