changeset 25621:860d8ed4f7a6

Check for session id (value for key 11) in the received IMs and Notifications against our session id. Disconnect in case of a mismatch.
author Sulabh Mahajan <sulabh@soc.pidgin.im>
date Wed, 02 Jul 2008 11:16:35 +0000
parents 6da23dc3000d
children 2fb8c39d0494
files libpurple/protocols/yahoo/yahoo.c libpurple/protocols/yahoo/yahoo.h libpurple/protocols/yahoo/yahoo_friend.h
diffstat 3 files changed, 53 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/yahoo/yahoo.c	Wed Jul 02 07:22:58 2008 +0000
+++ b/libpurple/protocols/yahoo/yahoo.c	Wed Jul 02 11:16:35 2008 +0000
@@ -230,6 +230,8 @@
 				message = pair->value;
 			break;
 		case 11: /* this is the buddy's session id */
+			if (f)
+				f->session_id = strtol(pair->value, NULL, 10);
 			break;
 		case 17: /* in chat? */
 			break;
@@ -694,7 +696,8 @@
 	yahoo_fetch_aliases(gc);
 }
 
-static void yahoo_process_notify(PurpleConnection *gc, struct yahoo_packet *pkt)
+/*pkt_type is PKT_YAHOOSERVER if pkt arrives from yahoo server, PKT_P2P if pkt arrives through p2p*/ 
+static void yahoo_process_notify(PurpleConnection *gc, struct yahoo_packet *pkt, int pkt_type)
 {
 	PurpleAccount *account;
 	char *msg = NULL;
@@ -703,6 +706,8 @@
 	char *game = NULL;
 	YahooFriend *f = NULL;
 	GSList *l = pkt->hash;
+	gint val_11 = 0;
+	struct yahoo_data *yd = gc->proto_data;
 
 	account = purple_connection_get_account(gc);
 
@@ -716,12 +721,22 @@
 			stat = pair->value;
 		if (pair->key == 14)
 			game = pair->value;
+		if (pair->key == 11)
+			val_11 = strtol(pair->value, NULL, 10);
 		l = l->next;
 	}
 
 	if (!from || !msg)
 		return;
 
+	/*disconnect the peer if connected through p2p and sends wrong value for session id*/
+	if( (pkt_type == PKT_P2P) && (val_11 != yd->session_id) ) {
+		purple_debug_warning("yahoo","p2p: %s sent us notify with wrong session id. Disconnecting p2p connection to peer\n", from);
+		/*remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data*/
+		g_hash_table_remove(yd->peers, from);
+		return;
+	}
+
 	if (!g_ascii_strncasecmp(msg, "TYPING", strlen("TYPING"))
 		&& (purple_privacy_check(account, from)))
 	{
@@ -758,7 +773,6 @@
 
 }
 
-
 struct _yahoo_im {
 	char *from;
 	int time;
@@ -767,7 +781,8 @@
 	char *msg;
 };
 
-static void yahoo_process_message(PurpleConnection *gc, struct yahoo_packet *pkt)
+/*pkt_type is PKT_YAHOOSERVER if pkt arrives from yahoo server, PKT_P2P if pkt arrives through p2p*/ 
+static void yahoo_process_message(PurpleConnection *gc, struct yahoo_packet *pkt, int pkt_type)
 {
 	PurpleAccount *account;
 	struct yahoo_data *yd = gc->proto_data;
@@ -775,6 +790,7 @@
 	GSList *list = NULL;
 	struct _yahoo_im *im = NULL;
 	const char *imv = NULL;
+	gint val_11 = 0;
 
 	account = purple_connection_get_account(gc);
 
@@ -802,6 +818,11 @@
 				if (im)
 					im->msg = pair->value;
 			}
+			/*peer session id*/
+			if (pair->key == 11) {
+				if (im)
+					val_11 = strtol(pair->value, NULL, 10);
+			}
 			/* IMV key */
 			if (pair->key == 63)
 			{
@@ -814,6 +835,14 @@
 		                  _("Your Yahoo! message did not get sent."), NULL);
 	}
 
+	/*disconnect the peer if connected through p2p and sends wrong value for session id*/
+	if( (pkt_type == PKT_P2P) && (val_11 != yd->session_id) ) {
+		purple_debug_warning("yahoo","p2p: %s sent us message with wrong session id. Disconnecting p2p connection to peer\n", im->from);
+		/*remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data*/
+		g_hash_table_remove(yd->peers, im->from);
+		return;
+	}
+
 	/** TODO: It seems that this check should be per IM, not global */
 	/* Check for the Doodle IMV */
 	if (im != NULL && imv!= NULL && im->from != NULL)
@@ -2233,7 +2262,9 @@
 	g_free(decoded_group);
 }
 
-/*destroy p2p_data associated with a peer and close p2p connection*/
+/*destroy p2p_data associated with a peer and close p2p connection.
+ *g_hash_table_remove() calls this function to destroy p2p_data associated with the peer,
+ *call g_hash_table_remove() instead of this fucntion if peer has an entry in the table */
 static void yahoo_p2p_disconnect_destroy_data(gpointer data)
 {
 	struct yahoo_p2p_data *p2p_data;
@@ -2401,10 +2432,10 @@
 			yahoo_p2p_process_p2pfilexfer(data, source, pkt);
 			break;
 		case YAHOO_SERVICE_MESSAGE:
-			yahoo_process_message(p2p_data->gc, pkt);
+			yahoo_process_message(p2p_data->gc, pkt, PKT_P2P);
 			break;
 		case YAHOO_SERVICE_NOTIFY:
-			yahoo_process_notify(p2p_data->gc, pkt);
+			yahoo_process_notify(p2p_data->gc, pkt, PKT_P2P);
 			break;
 		default:
 			purple_debug_warning("yahoo","p2p: p2p service %d Unhandled\n",pkt->service);
@@ -2439,8 +2470,7 @@
 	yd->yahoo_local_p2p_server_fd = -1;
 
 	if( (f = yahoo_friend_find(p2p_data->gc, p2p_data->host_username)) )	{
-		/*To-Do: we should disconnect if not a friend*/
-		p2p_data->val_11 = f->val_11;
+		p2p_data->session_id = f->session_id;
 		yahoo_friend_set_p2p_status(f, CONNECTED_AS_SERVER);
 	}
 
@@ -2506,7 +2536,7 @@
 		1, purple_normalize(account, purple_account_get_username(account)),
 		4, purple_normalize(account, purple_account_get_username(account)),
 		12, base64_ip,	/*base64 encode ip*/
-		61, 0,		/*To-do : whats 61 for??*/
+		61, 0,		/*To-do : figure out what is 61 for??*/
 		2, "",
 		5, who,
 		13, val_13,
@@ -2608,9 +2638,9 @@
 			val_13 = strtol(pair->value, NULL, 10);
 			break;
 		case 11:
-			val_11 = strtol(pair->value, NULL, 10);		/*p2p identity of peer*/
+			val_11 = strtol(pair->value, NULL, 10);		/*session id of peer*/
 			if( (f = yahoo_friend_find(gc, who)) )
-				f->val_11 = val_11;
+				f->session_id = val_11;
 			break;
 		/*
 			TODO: figure these out
@@ -2657,13 +2687,13 @@
 			if(!f)
 				return;
 			else
-				val_11 = f->val_11;
+				val_11 = f->session_id;
 		}
 
 		p2p_data->host_username = (char *)g_malloc(strlen(who));
 		strcpy(p2p_data->host_username, who);		
 		p2p_data->val_13 = val_13;
-		p2p_data->val_11 = val_11;
+		p2p_data->session_id = val_11;
 		p2p_data->host_ip = host_ip;
 		p2p_data->gc = gc;
 		p2p_data->connection_type = 0;		/*0:peer is server*/
@@ -2752,12 +2782,12 @@
 		yahoo_process_status(gc, pkt);
 		break;
 	case YAHOO_SERVICE_NOTIFY:
-		yahoo_process_notify(gc, pkt);
+		yahoo_process_notify(gc, pkt, PKT_YAHOOSERVER);
 		break;
 	case YAHOO_SERVICE_MESSAGE:
 	case YAHOO_SERVICE_GAMEMSG:
 	case YAHOO_SERVICE_CHATMSG:
-		yahoo_process_message(gc, pkt);
+		yahoo_process_message(gc, pkt, PKT_YAHOOSERVER);
 		break;
 	case YAHOO_SERVICE_SYSMESSAGE:
 		yahoo_process_sysmessage(gc, pkt);
@@ -3958,7 +3988,7 @@
 	else {
 		const char *yahoo_mail_url = (yd->jp ? YAHOOJP_MAIL_URL : YAHOO_MAIL_URL);
 		purple_debug_error("yahoo",
-				   "Unable to request mail login token; forwarding to login screen.");
+				   "Unable to request mail login token; forwarding to login screen.\n");
 		purple_notify_uri(gc, yahoo_mail_url);
 	}
 
@@ -4065,7 +4095,7 @@
 	if ((YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt)) <= 2000)	{
 		/*if p2p link exists, send through it. To-do: key 15, time value to be sent in case of p2p*/
 		if( (p2p_data = g_hash_table_lookup(yd->peers, who)) )	{
-			yahoo_packet_hash_int(pkt, 11, p2p_data->val_11);
+			yahoo_packet_hash_int(pkt, 11, p2p_data->session_id);
 			yahoo_p2p_write_pkt(p2p_data->source, pkt);
 		}
 		else	{
@@ -4095,7 +4125,7 @@
 	if( (p2p_data = g_hash_table_lookup(yd->peers, who)) )	{
 		yahoo_packet_hash(pkt, "sssssis", 49, "TYPING", 1, purple_connection_get_display_name(gc),
 	                  14, " ", 13, state == PURPLE_TYPING ? "1" : "0",
-	                  5, who, 11, p2p_data->val_11, 1002, "1");	/*To-do: key 15 to be sent in case of p2p*/	
+	                  5, who, 11, p2p_data->session_id, 1002, "1");	/*To-do: key 15 to be sent in case of p2p*/	
 		yahoo_p2p_write_pkt(p2p_data->source, pkt);
 		yahoo_packet_free(pkt);
 	}
--- a/libpurple/protocols/yahoo/yahoo.h	Wed Jul 02 07:22:58 2008 +0000
+++ b/libpurple/protocols/yahoo/yahoo.h	Wed Jul 02 11:16:35 2008 +0000
@@ -81,6 +81,9 @@
 #define YAHOOJP_CLIENT_VERSION_ID "524223"
 #define YAHOOJP_CLIENT_VERSION "7,0,1,1"
 
+/*Packet sources: yahoo server and p2p*/
+#define PKT_YAHOOSERVER 0
+#define PKT_P2P 1
 
 /* Index into attention types list. */
 #define YAHOO_BUZZ 0
@@ -121,7 +124,7 @@
 	int val_13;
 	guint input_event;
 	gint source;
-	int val_11;
+	int session_id;
 	gboolean connection_type;	/* 0: peer is server, 1: we are server*/
 };
 
--- a/libpurple/protocols/yahoo/yahoo_friend.h	Wed Jul 02 07:22:58 2008 +0000
+++ b/libpurple/protocols/yahoo/yahoo_friend.h	Wed Jul 02 11:16:35 2008 +0000
@@ -59,7 +59,7 @@
 	gchar *alias_id;
 	YahooP2PStatus p2p_status;
 	gboolean p2p_packet_sent;	/*0:not sent, 1=sent*/
-	gint val_11;	/*value for key 11, p2p identifier*/
+	gint session_id;	/*session id of friend*/
 } YahooFriend;
 
 YahooFriend *yahoo_friend_find(PurpleConnection *gc, const char *name);