[Asterisk-cvs] asterisk/channels chan_iax2.c, 1.318, 1.319 iax2-parser.c, 1.47, 1.48

markster at lists.digium.com markster at lists.digium.com
Tue Jul 12 10:38:12 CDT 2005


Update of /usr/cvsroot/asterisk/channels
In directory mongoose.digium.com:/tmp/cvs-serv16811/channels

Modified Files:
	chan_iax2.c iax2-parser.c 
Log Message:
Fix IAX2 encryption (really, bug #4500 for reference)


Index: chan_iax2.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_iax2.c,v
retrieving revision 1.318
retrieving revision 1.319
diff -u -d -r1.318 -r1.319
--- chan_iax2.c	12 Jul 2005 02:19:41 -0000	1.318
+++ chan_iax2.c	12 Jul 2005 14:46:20 -0000	1.319
@@ -3701,7 +3701,14 @@
 
 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
 {
-/*	memcpy(dst, src, len); */
+#if 0
+	/* Debug with "fake encryption" */
+	int x;
+	if (len % 16)
+		ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
+	for (x=0;x<len;x++)
+		dst[x] = src[x] ^ 0xff;
+#else	
 	unsigned char lastblock[16] = { 0 };
 	int x;
 	while(len > 0) {
@@ -3713,11 +3720,19 @@
 		src += 16;
 		len -= 16;
 	}
+#endif
 }
 
 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
 {
-/*	memcpy(dst, src, len); */
+#if 0
+	/* Debug with "fake encryption" */
+	int x;
+	if (len % 16)
+		ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
+	for (x=0;x<len;x++)
+		dst[x] = src[x] ^ 0xff;
+#else
 	unsigned char curblock[16] = { 0 };
 	int x;
 	while(len > 0) {
@@ -3729,6 +3744,7 @@
 		src += 16;
 		len -= 16;
 	}
+#endif
 }
 
 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
@@ -3740,15 +3756,17 @@
 		return -1;
 	if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
 		struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
-		if (option_debug)
-			ast_log(LOG_DEBUG, "Decoding full frame with length %d\n", *datalen);
 		if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
 			return -1;
-		padding = 16 + (efh->encdata[15] & 0xf);
+		/* Decrypt */
+		memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
+
+		padding = 16 + (workspace[15] & 0xf);
+		if (option_debug)
+			ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
 		if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
 			return -1;
-		/* Decrypt */
-		memcpy_decrypt(workspace, efh->encdata, *datalen, dcx);
+
 		*datalen -= padding;
 		memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
 		f->frametype = fh->type;
@@ -3763,11 +3781,11 @@
 			ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
 		if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
 			return -1;
-		padding = 16 + (efh->encdata[15] & 0x0f);
+		/* Decrypt */
+		memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
+		padding = 16 + (workspace[15] & 0x0f);
 		if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
 			return -1;
-		/* Decrypt */
-		memcpy_decrypt(workspace, efh->encdata, *datalen, dcx);
 		*datalen -= padding;
 		memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
 	}
@@ -3784,15 +3802,17 @@
 	if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
 		struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
 		if (option_debug)
-			ast_log(LOG_DEBUG, "Encoding full frame with length %d\n", *datalen);
+			ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
 		padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
 		padding = 16 + (padding & 0xf);
 		memcpy(workspace, poo, padding);
 		memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
-		*datalen += padding;
 		workspace[15] &= 0xf0;
 		workspace[15] |= (padding & 0xf);
-		memcpy_encrypt(efh->encdata, workspace, *datalen, ecx);
+		if (option_debug)
+			ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
+		*datalen += padding;
+		memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
 		if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
 			memcpy(poo, workspace + *datalen - 32, 32);
 	} else {
@@ -3801,12 +3821,12 @@
 			ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
 		padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
 		padding = 16 + (padding & 0xf);
-		memset(workspace, 0, padding);
+		memcpy(workspace, poo, padding);
 		memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
 		workspace[15] &= 0xf0;
 		workspace[15] |= (padding & 0x0f);
 		*datalen += padding;
-		memcpy_encrypt(efh->encdata, workspace, *datalen, ecx);
+		memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
 		if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
 			memcpy(poo, workspace + *datalen - 32, 32);
 	}
@@ -3955,6 +3975,12 @@
 			pvt->svideoformat = f->subclass & ~0x1;
 		if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
 			if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
+				if (iaxdebug) {
+					if (fr->transfer)
+						iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
+					else
+						iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
+				}
 				encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
 			} else
 				ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
@@ -6359,7 +6385,7 @@
 		}
 #ifdef DEBUG_SUPPORT
 		else if (iaxdebug)
-			iax_showframe(NULL, fh, 1, &sin, res - sizeof(struct ast_iax2_full_hdr));
+			iax_showframe(NULL, fh, 3, &sin, res - sizeof(struct ast_iax2_full_hdr));
 #endif
 	}
 

Index: iax2-parser.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/iax2-parser.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -d -r1.47 -r1.48
--- iax2-parser.c	13 Jun 2005 08:48:17 -0000	1.47
+++ iax2-parser.c	12 Jul 2005 14:46:20 -0000	1.48
@@ -440,8 +440,23 @@
 	char subclass2[20];
 	char *class;
 	char *subclass;
+	char *dir;
 	char tmp[256];
 	char iabuf[INET_ADDRSTRLEN];
+	switch(rx) {
+	case 0:
+		dir = "Tx";
+		break;
+	case 2:
+		dir = "TE";
+		break;
+	case 3:
+		dir = "RD";
+		break;
+	default:
+		dir = "Rx";
+		break;
+	}
 	if (f) {
 		fh = f->data;
 		snprintf(retries, (int)sizeof(retries), "%03d", f->retries);
@@ -485,7 +500,7 @@
 	}
 snprintf(tmp, (int)sizeof(tmp), 
 "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s Subclass: %s\n",
-	(rx ? "Rx" : "Tx"),
+	dir,
 	retries, fh->oseqno, fh->iseqno, class, subclass);
 	outputf(tmp);
 snprintf(tmp, (int)sizeof(tmp), 




More information about the svn-commits mailing list