pidgin: 56ce815e: Support old-style Nonce, which should le...

qulogic at pidgin.im qulogic at pidgin.im
Fri May 21 18:03:18 EDT 2010


-----------------------------------------------------------------
Revision: 56ce815eeb3b4a0939cbe3c2b48194e34c5b63e2
Ancestor: d26e0fdc3d34d61f50a0f04c1bfc3098eeebbf62
Author: qulogic at pidgin.im
Date: 2010-04-24T06:41:52
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/56ce815eeb3b4a0939cbe3c2b48194e34c5b63e2

Modified files:
        libpurple/protocols/msn/directconn.c
        libpurple/protocols/msn/directconn.h
        libpurple/protocols/msn/slp.c

ChangeLog: 

Support old-style Nonce, which should let us use direct connections to
aMSN (or msn-pecan?)

Refs #247.

-------------- next part --------------
============================================================
--- libpurple/protocols/msn/directconn.c	82bbc5b3eab9a009c6cd87d434deb1b5a8d676c7
+++ libpurple/protocols/msn/directconn.c	a004ef0ee4f8109efd61908794f29a66797b1471
@@ -49,23 +49,23 @@ msn_dc_generate_nonce(MsnDirectConn *dc)
 static void
 msn_dc_generate_nonce(MsnDirectConn *dc)
 {
-	PurpleCipher        *cipher = NULL;
-	PurpleCipherContext *context = NULL;
 	guint32 *nonce;
 	int i;
 	guchar digest[20];
 
-	cipher = purple_ciphers_find_cipher("sha1");
-	g_return_if_fail(cipher != NULL);
-
 	nonce = (guint32 *)&dc->nonce;
 	for (i = 0; i < 4; i++)
 		nonce[i] = rand();
 
-	context = purple_cipher_context_new(cipher, NULL);
-	purple_cipher_context_append(context, dc->nonce, sizeof(dc->nonce));
-	purple_cipher_context_digest(context, sizeof(digest), digest, NULL);
-	purple_cipher_context_destroy(context);
+	if (dc->nonce_type == DC_NONCE_SHA1) {
+		PurpleCipher *cipher = purple_ciphers_find_cipher("sha1");
+		PurpleCipherContext *context = purple_cipher_context_new(cipher, NULL);
+		purple_cipher_context_append(context, dc->nonce, sizeof(dc->nonce));
+		purple_cipher_context_digest(context, sizeof(digest), digest, NULL);
+		purple_cipher_context_destroy(context);
+	} else if (dc->nonce_type == DC_NONCE_PLAIN) {
+		memcpy(digest, nonce, 16);
+	}
 
 	g_sprintf(dc->nonce_hash,
 	          "%08X-%04X-%04X-%04X-%08X%04X",
@@ -145,6 +145,8 @@ msn_dc_new(MsnSlpCall *slpcall)
 	dc->progress = FALSE;
 	//dc->num_calls = 1;
 
+	/* TODO: Probably should set this based on buddy caps */
+	dc->nonce_type = DC_NONCE_PLAIN;
 	msn_dc_generate_nonce(dc);
 
 	return dc;
@@ -699,11 +701,15 @@ msn_dc_verify_handshake(MsnDirectConn *d
 
 	memcpy(nonce, dc->in_buffer + 4 + offsetof(MsnDcContext, ack_id), 16);
 
-	cipher = purple_ciphers_find_cipher("sha1");
-	context = purple_cipher_context_new(cipher, NULL);
-	purple_cipher_context_append(context, nonce, sizeof(nonce));
-	purple_cipher_context_digest(context, sizeof(digest), digest, NULL);
-	purple_cipher_context_destroy(context);
+	if (dc->nonce_type == DC_NONCE_SHA1) {
+		cipher = purple_ciphers_find_cipher("sha1");
+		context = purple_cipher_context_new(cipher, NULL);
+		purple_cipher_context_append(context, nonce, sizeof(nonce));
+		purple_cipher_context_digest(context, sizeof(digest), digest, NULL);
+		purple_cipher_context_destroy(context);
+	} else if (dc->nonce_type == DC_NONCE_PLAIN) {
+		memcpy(digest, nonce, 16);
+	}
 
 	g_sprintf(nonce_hash,
 	          "%08X-%04X-%04X-%04X-%08X%04X",
@@ -1354,13 +1360,14 @@ msn_dc_listen_socket_created_cb(int list
 			dc->msg_body = g_strdup_printf(
 				"Bridge: TCPv1\r\n"
 				"Listening: true\r\n"
-				"Hashed-Nonce: {%s}\r\n"
+				"%sNonce: {%s}\r\n"
 				"IPv4External-Addrs: %s\r\n"
 				"IPv4External-Port: %d\r\n"
 				"IPv4Internal-Addrs: %s\r\n"
 				"IPv4Internal-Port: %d\r\n"
 				"\r\n",
 
+				dc->nonce_type != DC_NONCE_PLAIN ? "Hashed-" : "",
 				dc->nonce_hash,
 				ext_ip,
 				port,
@@ -1372,11 +1379,12 @@ msn_dc_listen_socket_created_cb(int list
 			dc->msg_body = g_strdup_printf(
 				"Bridge: TCPv1\r\n"
 				"Listening: true\r\n"
-				"Hashed-Nonce: {%s}\r\n"
+				"%sNonce: {%s}\r\n"
 				"IPv4External-Addrs: %s\r\n"
 				"IPv4External-Port: %d\r\n"
 				"\r\n",
 
+				dc->nonce_type != DC_NONCE_PLAIN ? "Hashed-" : "",
 				dc->nonce_hash,
 				ext_ip,
 				port
============================================================
--- libpurple/protocols/msn/directconn.h	e4fe02d33e840c7e699019d582c66b5624022556
+++ libpurple/protocols/msn/directconn.h	d648293b0215b8c55de9f7e63040aa9d4758b6f4
@@ -53,6 +53,13 @@ typedef enum
 
 } MsnDirectConnProcessResult;
 
+typedef enum
+{
+	DC_NONCE_PLAIN,     /**< No hashing */
+	DC_NONCE_SHA1       /**< First 16 bytes of SHA1 of nonce */
+
+} MsnDirectConnNonceType;
+
 typedef struct _MsnDirectConnPacket MsnDirectConnPacket;
 
 struct _MsnDirectConnPacket {
@@ -71,9 +78,10 @@ struct _MsnDirectConn
 	char                *msg_body;  /**< The body of message sent by send_connection_info_msg_cb */
 	MsnSlpMessage       *prev_ack;  /**< The saved SLP ACK message */
 
-	guchar  nonce[16];          /**< The nonce used for direct connection handshake */
-	gchar   nonce_hash[37];     /**< The hash of nonce */
-	gchar   remote_nonce[37];   /**< The remote side's nonce */
+	MsnDirectConnNonceType nonce_type;         /**< The type of nonce hashing */
+	guchar                 nonce[16];          /**< The nonce used for handshake */
+	gchar                  nonce_hash[37];     /**< The hash of nonce */
+	gchar                  remote_nonce[37];   /**< The remote side's nonce */
 
 	PurpleNetworkListenData *listen_data;           /**< The pending socket creation request */
 	PurpleProxyConnectData  *connect_data;          /**< The pending connection attempt */
============================================================
--- libpurple/protocols/msn/slp.c	ec788a4998b43739d5897b7b06df54b42c0c261d
+++ libpurple/protocols/msn/slp.c	960d418ff8d1930104e98693d1d1fe12c41d86c3
@@ -631,6 +631,7 @@ got_invite(MsnSlpCall *slpcall,
 		/* A direct connection negotiation request */
 		char *bridges;
 		char *nonce;
+		MsnDirectConnNonceType ntype;
 
 		purple_debug_info("msn", "got_invite: transreqbody received\n");
 
@@ -640,6 +641,12 @@ got_invite(MsnSlpCall *slpcall,
 
 		bridges = get_token(content, "Bridges: ", "\r\n");
 		nonce = get_token(content, "Hashed-Nonce: {", "}\r\n");
+		if (nonce) {
+			ntype = DC_NONCE_SHA1;
+		} else {
+			nonce = get_token(content, "Nonce: {", "}\r\n");
+			ntype = DC_NONCE_PLAIN;
+		}
 		if (nonce && bridges && strstr(bridges, "TCPv1") != NULL) {
 			/*
 			 * Ok, the client supports direct TCP connection
@@ -648,6 +655,7 @@ got_invite(MsnSlpCall *slpcall,
 			MsnDirectConn *dc;
 
 			dc = msn_dc_new(slpcall);
+			dc->nonce_type = ntype;
 			strncpy(dc->remote_nonce, nonce, 36);
 			dc->remote_nonce[36] = '\0';
 
@@ -663,12 +671,20 @@ got_invite(MsnSlpCall *slpcall,
 
 				purple_debug_info("msn", "got_invite: listening failed\n");
 
-				msn_slp_send_ok(slpcall, branch,
-					"application/x-msnmsgr-transrespbody",
-					"Bridge: TCPv1\r\n"
-					"Listening: false\r\n"
-					"Hashed-Nonce: {00000000-0000-0000-0000-000000000000}\r\n"
-					"\r\n");
+				if (dc->nonce_type != DC_NONCE_PLAIN)
+					msn_slp_send_ok(slpcall, branch,
+						"application/x-msnmsgr-transrespbody",
+						"Bridge: TCPv1\r\n"
+						"Listening: false\r\n"
+						"Hashed-Nonce: {00000000-0000-0000-0000-000000000000}\r\n"
+						"\r\n");
+				else
+					msn_slp_send_ok(slpcall, branch,
+						"application/x-msnmsgr-transrespbody",
+						"Bridge: TCPv1\r\n"
+						"Listening: false\r\n"
+						"Nonce: {00000000-0000-0000-0000-000000000000}\r\n"
+						"\r\n");
 
 			} else {
 				/*
@@ -750,10 +766,11 @@ got_ok(MsnSlpCall *slpcall,
 				"Conn-Type: IP-Restrict-NAT\r\n"
 				"UPnPNat: false\r\n"
 				"ICF: false\r\n"
-				"Hashed-Nonce: {%s}\r\n"
+				"%sNonce: {%s}\r\n"
 				"\r\n",
 
 				rand() % G_MAXUINT32,
+				dc->nonce_type != DC_NONCE_PLAIN ? "Hashed-" : "",
 				dc->nonce_hash
 			);
 
@@ -768,9 +785,10 @@ got_ok(MsnSlpCall *slpcall,
 				"Conn-Type: Direct-Connect\r\n"
 				"UPnPNat: false\r\n"
 				"ICF: false\r\n"
-				"Hashed-Nonce: {%s}\r\n"
+				"%sNonce: {%s}\r\n"
 				"\r\n",
 
+				dc->nonce_type != DC_NONCE_PLAIN ? "Hashed-" : "",
 				dc->nonce_hash
 			);
 		}


More information about the Commits mailing list