aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b>2009-09-10 22:20:57 +0000
committerdvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b>2009-09-10 22:20:57 +0000
commita2693562cb764a298f6478fbae64f78d67d6ad43 (patch)
tree4bf96496d4cebe1cb89f2bf073f67877b257a0f1
parentccb83659535ee7853f5fd1a0672affce630eeef6 (diff)
IAX2 encryption regression
The IAX2 Call Token security patch inadvertently broke the use of encryption due to the reorganization of code in the socket_process() function. When encryption is used, an incoming full frame must first be decrypted before the information elements can be parsed. The security release mistakenly moved IE parsing before decryption in order to process the new Call Token IE. To resolve this, decryption of full frames is once again done before looking into the frame. This involves searching for an existing callno, checking the pvt to see if encryption is turned on, and decrypting the packet before the internal fields of the full frame are accessed. associated with AST-2009-006 (closes issue #15834) Reported by: karesmakro Patches: iax2_encryption_fix_1.4.diff uploaded by dvossel (license 671) Tested by: dvossel, karesmakro Review: https://reviewboard.asterisk.org/r/355/ git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@217887 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--channels/chan_iax2.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index f47ca8202..8ef382af7 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -7634,6 +7634,7 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
void *ptr;
socklen_t len = sizeof(sin);
int dcallno = 0;
+ char decrypted = 0;
struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)buf;
struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)buf;
struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)buf;
@@ -7833,6 +7834,25 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
/* Get the destination call number */
dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
+
+
+ /* check to make sure this full frame isn't encrypted before we attempt
+ * to look inside of it. If it is encrypted, decrypt it first. Its ok if the
+ * callno is not found here, that just means one hasn't been allocated for
+ * this connection yet. */
+ if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, 1, fd, 1))) {
+ ast_mutex_lock(&iaxsl[fr->callno]);
+ if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
+ if (decrypt_frame(fr->callno, fh, &f, &res)) {
+ ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
+ ast_mutex_unlock(&iaxsl[fr->callno]);
+ return 1;
+ }
+ decrypted = 1;
+ }
+ ast_mutex_unlock(&iaxsl[fr->callno]);
+ }
+
/* Retrieve the type and subclass */
f.frametype = fh->type;
if (f.frametype == AST_FRAME_VIDEO) {
@@ -7942,17 +7962,19 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
ast_mutex_unlock(&iaxsl[fr->callno]);
return 1;
}
- if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
+ if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
if (decrypt_frame(fr->callno, fh, &f, &res)) {
ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
ast_mutex_unlock(&iaxsl[fr->callno]);
return 1;
}
+ decrypted = 1;
+ }
#ifdef DEBUG_SUPPORT
- else if (iaxdebug)
- iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
-#endif
+ if (decrypted && iaxdebug) {
+ iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
}
+#endif
/* count this frame */
iaxs[fr->callno]->frames_received++;