changeset 30915:d9db23719cf9

merge of '148e99c7c4a60cc18826232bd8b3270cbdddc7b5' and '89847795e1c9cbdd51c942ae1e506e6060ac2235'
author Daniel Atallah <daniel.atallah@gmail.com>
date Mon, 08 Nov 2010 22:51:35 +0000
parents 4de2b3adc823 (current diff) a4f3d21f393c (diff)
children 4ba00731d066
files
diffstat 14 files changed, 196 insertions(+), 126 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Nov 04 19:20:38 2010 +0000
+++ b/ChangeLog	Mon Nov 08 22:51:35 2010 +0000
@@ -10,6 +10,9 @@
 	  (http://developer.pidgin.im/wiki/SlpArchitecture)
 	* Lots of little changes.
 
+	XMPP:
+	* Avoid a double-free in the Google Relay (V/V) code.
+
 version 2.7.5 (10/31/2010):
 	General:
 	* Added Verisign Class 3 Public CA - G2 root CA.
--- a/libpurple/protocols/jabber/google/google_session.c	Thu Nov 04 19:20:38 2010 +0000
+++ b/libpurple/protocols/jabber/google/google_session.c	Mon Nov 08 22:51:35 2010 +0000
@@ -372,7 +372,7 @@
 	params =
 		jabber_google_session_get_params(js, relay_ip, relay_udp, relay_tcp,
 			relay_ssltcp, relay_username, relay_password, &num_params);
-	
+
 	if (purple_media_add_stream(session_data->media, "google-voice",
 			session->remote_jid, PURPLE_MEDIA_AUDIO,
 			TRUE, "nice", num_params, params) == FALSE ||
@@ -382,12 +382,11 @@
 			TRUE, "nice", num_params, params) == FALSE)) {
 		purple_media_error(session_data->media, "Error adding stream.");
 		purple_media_end(session_data->media, NULL, NULL);
-		g_free(params);
 	} else {
 		session_data->added_streams = TRUE;
 	}
 
-	g_free(params);	
+	g_free(params);
 }
 
 
--- a/libpurple/protocols/msn/cmdproc.c	Thu Nov 04 19:20:38 2010 +0000
+++ b/libpurple/protocols/msn/cmdproc.c	Mon Nov 08 22:51:35 2010 +0000
@@ -211,37 +211,39 @@
 
 				MsnMessage *first = g_hash_table_lookup(cmdproc->multiparts, message_id);
 				chunk = strtol(chunk_text, NULL, 10);
-				if (first == NULL) {
+				if (first != NULL) {
+					if (first->received_chunks != chunk) {
+						/*
+						 * We received an out of order chunk number (i.e. not the
+						 * next one in the sequence).  Not sure if this can happen
+						 * legitimately, but we definitely don't handle it right
+						 * now.
+						 */
+						g_hash_table_remove(cmdproc->multiparts, message_id);
+						return;
+					}
+
+					/* Chunk is from 1 to total-1 (doesn't count first one) */
+					purple_debug_info("msn", "Received chunk %d of %d, message_id: '%s'\n",
+							chunk + 1, first->total_chunks, message_id);
+					first->body = g_realloc(first->body, first->body_len + msg->body_len);
+					memcpy(first->body + first->body_len, msg->body, msg->body_len);
+					first->body_len += msg->body_len;
+					first->received_chunks++;
+					if (first->received_chunks != first->total_chunks)
+						/* We're waiting for more chunks */
+						return;
+
+					/*
+					 * We have all the chunks for this message, great!  Send
+					 * it along... The caller takes care of freeing the old one.
+					 */
+					msg = first;
+				} else {
 					purple_debug_error("msn",
 					                   "Unable to find first chunk of message_id '%s' to correspond with chunk %d.\n",
 					                   message_id, chunk + 1);
-				} else if (first->received_chunks != chunk) {
-					/*
-					 * We received an out of order chunk number (i.e. not the
-					 * next one in the sequence).  Not sure if this can happen
-					 * legitimately, but we definitely don't handle it right
-					 * now.
-					 */
-					g_hash_table_remove(cmdproc->multiparts, message_id);
-					return;
 				}
-
-				/* Chunk is from 1 to total-1 (doesn't count first one) */
-				purple_debug_info("msn", "Received chunk %d of %d, message_id: '%s'\n",
-						chunk + 1, first->total_chunks, message_id);
-				first->body = g_realloc(first->body, first->body_len + msg->body_len);
-				memcpy(first->body + first->body_len, msg->body, msg->body_len);
-				first->body_len += msg->body_len;
-				first->received_chunks++;
-				if (first->received_chunks != first->total_chunks)
-					/* We're waiting for more chunks */
-					return;
-
-				/*
-				 * We have all the chunks for this message, great!  Send
-				 * it along... The caller takes care of freeing the old one.
-				 */
-				msg = first;
 			} else {
 				purple_debug_error("msn", "Received MessageId '%s' with no chunk number!\n", message_id);
 			}
--- a/libpurple/protocols/msn/msg.c	Thu Nov 04 19:20:38 2010 +0000
+++ b/libpurple/protocols/msn/msg.c	Mon Nov 08 22:51:35 2010 +0000
@@ -916,8 +916,6 @@
 {
 	MsnSession *session;
 	MsnSlpLink *slplink;
-	const char *data;
-	gsize len;
 
 	session = cmdproc->servconn->session;
 	slplink = msn_session_get_slplink(session, msg->remote_user);
@@ -940,8 +938,6 @@
 		}
 	}
 
-	data = msn_message_get_bin_data(msg, &len);
-
 	if (msg->part) {
 		msn_slplink_process_msg(slplink, msg->part);
 	}
--- a/libpurple/protocols/msn/notification.c	Thu Nov 04 19:20:38 2010 +0000
+++ b/libpurple/protocols/msn/notification.c	Mon Nov 08 22:51:35 2010 +0000
@@ -95,7 +95,6 @@
 	MsnCmdProc *cmdproc;
 	MsnSession *session;
 	MsnTransaction *trans;
-	PurpleAccount *account;
 	GString *vers;
 	const char *ver_str;
 	int i;
@@ -104,7 +103,6 @@
 
 	cmdproc = servconn->cmdproc;
 	session = servconn->session;
-	account = session->account;
 
 	vers = g_string_new("");
 
@@ -189,11 +187,7 @@
 static void
 usr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
 {
-	MsnSession *session;
-	PurpleAccount *account;
-
-	session = cmdproc->session;
-	account = session->account;
+	MsnSession *session = cmdproc->session;
 
 	if (!g_ascii_strcasecmp(cmd->params[1], "OK"))
 	{
@@ -732,11 +726,8 @@
 	for (domain_node = xmlnode_get_child(root, "d");
 	     domain_node;
 	     domain_node = xmlnode_get_next_twin(domain_node)) {
-		const gchar * domain = NULL;
 		xmlnode *contact_node = NULL;
 
-		domain = xmlnode_get_attrib(domain_node, "n");
-
 		for (contact_node = xmlnode_get_child(domain_node, "c");
 		     contact_node;
 		     contact_node = xmlnode_get_next_twin(contact_node)) {
@@ -1021,8 +1012,6 @@
 iln_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
 {
 	MsnSession *session;
-	PurpleAccount *account;
-	PurpleConnection *gc;
 	MsnUser *user;
 	MsnObject *msnobj = NULL;
 	unsigned long clientid, extcaps;
@@ -1032,8 +1021,6 @@
 	char *friendly;
 
 	session = cmdproc->session;
-	account = session->account;
-	gc = purple_account_get_connection(account);
 
 	state    = cmd->params[1];
 	passport = cmd->params[2];
@@ -1246,8 +1233,6 @@
 nln_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
 {
 	MsnSession *session;
-	PurpleAccount *account;
-	PurpleConnection *gc;
 	MsnUser *user;
 	MsnObject *msnobj;
 	unsigned long clientid, extcaps;
@@ -1256,8 +1241,6 @@
 	const char *state, *passport, *friendly;
 
 	session = cmdproc->session;
-	account = session->account;
-	gc = purple_account_get_connection(account);
 
 	state    = cmd->params[0];
 	passport = cmd->params[1];
@@ -1455,7 +1438,7 @@
 	swboard = msn_switchboard_new(session);
 
 	msn_switchboard_set_invited(swboard, TRUE);
-	msn_switchboard_set_session_id(swboard, cmd->params[0]);
+	msn_switchboard_set_session_id(swboard, session_id);
 	msn_switchboard_set_auth_key(swboard, cmd->params[3]);
 	swboard->im_user = g_strdup(cmd->params[4]);
 	/* msn_switchboard_add_user(swboard, cmd->params[4]); */
@@ -1696,14 +1679,12 @@
 			 size_t len)
 {
 	MsnSession *session;
-	PurpleAccount *account;
 	MsnUser *user;
 	const char *passport;
 	xmlnode *payloadNode;
 	char *psm_str, *str;
 
 	session = cmdproc->session;
-	account = session->account;
 
 	passport = cmd->params[0];
 	if (g_str_equal(passport, session->user->passport))
--- a/libpurple/protocols/msn/slp.c	Thu Nov 04 19:20:38 2010 +0000
+++ b/libpurple/protocols/msn/slp.c	Mon Nov 08 22:51:35 2010 +0000
@@ -118,7 +118,6 @@
 got_user_display(MsnSlpCall *slpcall,
 				 const guchar *data, gsize size)
 {
-	MsnUserList *userlist;
 	const char *info;
 	PurpleAccount *account;
 
@@ -128,7 +127,6 @@
 	if (purple_debug_is_verbose())
 		purple_debug_info("msn", "Got User Display: %s\n", slpcall->slplink->remote_user);
 
-	userlist = slpcall->slplink->session->userlist;
 	account = slpcall->slplink->session->account;
 
 	purple_buddy_icons_set_for_user(account, slpcall->slplink->remote_user,
@@ -198,7 +196,7 @@
 	MsnSession *session;
 	MsnObject *my_obj = NULL;
 	gconstpointer data = NULL;
-	const char *info;
+	const char *info = NULL;
 	size_t len = 0;
 
 	if (purple_debug_is_verbose())
--- a/libpurple/protocols/msn/slpcall.c	Thu Nov 04 19:20:38 2010 +0000
+++ b/libpurple/protocols/msn/slpcall.c	Mon Nov 08 22:51:35 2010 +0000
@@ -567,8 +567,7 @@
 
 	} else if (!strcmp(euf_guid, MSN_CAM_REQUEST_GUID)) {
 		purple_debug_info("msn", "Cam request.\n");
-		if (slpcall && slpcall->slplink &&
-				slpcall->slplink->session) {
+		if (slpcall->slplink && slpcall->slplink->session) {
 			PurpleConversation *conv;
 			gchar *from = slpcall->slplink->remote_user;
 			conv = purple_find_conversation_with_account(
@@ -590,8 +589,7 @@
 
 	} else if (!strcmp(euf_guid, MSN_CAM_GUID)) {
 		purple_debug_info("msn", "Cam invite.\n");
-		if (slpcall && slpcall->slplink &&
-				slpcall->slplink->session) {
+		if (slpcall->slplink && slpcall->slplink->session) {
 			PurpleConversation *conv;
 			gchar *from = slpcall->slplink->remote_user;
 			conv = purple_find_conversation_with_account(
--- a/libpurple/protocols/msn/switchboard.c	Thu Nov 04 19:20:38 2010 +0000
+++ b/libpurple/protocols/msn/switchboard.c	Mon Nov 08 22:51:35 2010 +0000
@@ -325,9 +325,8 @@
 			for (l = swboard->users; l != NULL; l = l->next)
 			{
 				const char *tmp_user;
-				user = l->data;
 
-				tmp_user = msnuser->passport;
+				tmp_user = ((MsnUser*)l->data)->passport;
 
 				purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv),
 										tmp_user, NULL, PURPLE_CBFLAGS_NONE, TRUE);
@@ -678,11 +677,9 @@
 iro_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
 {
 	PurpleAccount *account;
-	PurpleConnection *gc;
 	MsnSwitchBoard *swboard;
 
 	account = cmdproc->session->account;
-	gc = account->gc;
 	swboard = cmdproc->data;
 
 	swboard->total_users = atoi(cmd->params[2]);
@@ -695,7 +692,6 @@
 {
 	MsnSession *session;
 	PurpleAccount *account;
-	PurpleConnection *gc;
 	MsnSwitchBoard *swboard;
 	const char *passport;
 
@@ -703,7 +699,6 @@
 
 	session = cmdproc->session;
 	account = session->account;
-	gc = account->gc;
 	swboard = cmdproc->data;
 
 	msn_switchboard_add_user(swboard, passport);
--- a/libpurple/protocols/msn/userlist.c	Thu Nov 04 19:20:38 2010 +0000
+++ b/libpurple/protocols/msn/userlist.c	Mon Nov 08 22:51:35 2010 +0000
@@ -699,8 +699,6 @@
 
 	if (userlist->buddy_icon_window > 0) {
 		GQueue *queue;
-		PurpleAccount *account;
-		const char *username;
 
 		queue = userlist->buddy_icon_requests;
 
@@ -709,9 +707,6 @@
 
 		user = g_queue_pop_head(queue);
 
-		account  = userlist->session->account;
-		username = user->passport;
-
 		userlist->buddy_icon_window--;
 
 		msn_request_user_display(user);
--- a/libpurple/protocols/oscar/clientlogin.c	Thu Nov 04 19:20:38 2010 +0000
+++ b/libpurple/protocols/oscar/clientlogin.c	Mon Nov 08 22:51:35 2010 +0000
@@ -93,10 +93,22 @@
 static gchar *generate_error_message(xmlnode *resp, const char *url)
 {
 	xmlnode *text;
+	xmlnode *status_code_node;
+	gchar *status_code;
+	gboolean have_error_code = TRUE;
 	gchar *err = NULL;
 	gchar *details = NULL;
 
-	if (resp && (text = xmlnode_get_child(resp, "statusText"))) {
+	status_code_node = xmlnode_get_child(resp, "statusCode");
+	if (status_code_node) {
+		/* We can get 200 OK here if the server omitted something we think it shouldn't have (see #12783).
+		 * No point in showing the "Ok" string to the user.
+		 */
+		if ((status_code = xmlnode_get_data_unescaped(status_code_node)) && strcmp(status_code, "200") == 0) {
+			have_error_code = FALSE;
+		}
+	}
+	if (have_error_code && resp && (text = xmlnode_get_child(resp, "statusText"))) {
 		details = xmlnode_get_data(text);
 	}
 
@@ -156,11 +168,9 @@
 	OscarData *od = purple_connection_get_protocol_data(gc);
 	xmlnode *response_node, *tmp_node, *data_node;
 	xmlnode *host_node = NULL, *port_node = NULL, *cookie_node = NULL, *tls_node = NULL;
-	gboolean use_tls;
 	char *tmp;
 	guint code;
-
-	use_tls = purple_account_get_bool(purple_connection_get_account(gc), "use_ssl", OSCAR_DEFAULT_USE_SSL);
+	const gchar *encryption_type = purple_account_get_string(purple_connection_get_account(gc), "encryption", OSCAR_DEFAULT_ENCRYPTION);
 
 	/* Parse the response as XML */
 	response_node = xmlnode_from_str(response, response_len);
@@ -185,7 +195,6 @@
 		host_node = xmlnode_get_child(data_node, "host");
 		port_node = xmlnode_get_child(data_node, "port");
 		cookie_node = xmlnode_get_child(data_node, "cookie");
-		tls_node = xmlnode_get_child(data_node, "tlsCertName");
 	}
 
 	/* Make sure we have a status code */
@@ -259,19 +268,30 @@
 		return FALSE;
 	}
 
+	if (strcmp(encryption_type, OSCAR_NO_ENCRYPTION) != 0) {
+		tls_node = xmlnode_get_child(data_node, "tlsCertName");
+		if (tls_node != NULL) {
+			*tls_certname = xmlnode_get_data_unescaped(tls_node);
+		} else {
+			if (strcmp(encryption_type, OSCAR_OPPORTUNISTIC_ENCRYPTION) == 0) {
+				purple_debug_warning("oscar", "We haven't received a tlsCertName to use. We will not do SSL to BOS.\n");
+			} else {
+				purple_debug_error("oscar", "startOSCARSession was missing tlsCertName: %s\n", response);
+				purple_connection_error_reason(
+					gc,
+					PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
+					_("You required encryption in your account settings, but one of the servers doesn't support it."));
+				xmlnode_free(response_node);
+				return FALSE;
+			}
+		}
+	}
+
 	/* Extract data from the XML */
 	*host = xmlnode_get_data_unescaped(host_node);
 	tmp = xmlnode_get_data_unescaped(port_node);
 	*cookie = xmlnode_get_data_unescaped(cookie_node);
 
-	if (use_tls) {
-		if (tls_node != NULL) {
-			*tls_certname = xmlnode_get_data_unescaped(tls_node);
-		} else {
-			purple_debug_warning("oscar", "useTls was 1, but we haven't received a tlsCertName to use. We will not do SSL to BOS.\n");
-		}
-	}
-
 	if (*host == NULL || **host == '\0' || tmp == NULL || *tmp == '\0' || *cookie == NULL || **cookie == '\0')
 	{
 		char *msg;
@@ -337,11 +357,8 @@
 static void send_start_oscar_session(OscarData *od, const char *token, const char *session_key, time_t hosttime)
 {
 	char *query_string, *signature, *url;
-	PurpleAccount *account;
-	gboolean use_tls;
-
-	account = purple_connection_get_account(od->gc);
-	use_tls = purple_account_get_bool(account, "use_ssl", OSCAR_DEFAULT_USE_SSL);
+	PurpleAccount *account = purple_connection_get_account(od->gc);
+	const gchar *encryption_type = purple_account_get_string(account, "encryption", OSCAR_DEFAULT_ENCRYPTION);
 
 	/*
 	 * Construct the GET parameters.  0x00000611 is the distid given to
@@ -354,9 +371,10 @@
 			"&ts=%" PURPLE_TIME_T_MODIFIER
 			"&useTLS=%d",
 			purple_url_encode(token),
-			oscar_get_ui_info_int(od->icq ? "prpl-icq-distid"
-					: "prpl-aim-distid", 0x00000611),
-			get_client_key(od), hosttime, use_tls);
+			oscar_get_ui_info_int(od->icq ? "prpl-icq-distid" : "prpl-aim-distid", 0x00000611),
+			get_client_key(od),
+			hosttime,
+			strcmp(encryption_type, OSCAR_NO_ENCRYPTION) != 0 ? 1 : 0);
 	signature = generate_signature("GET", get_start_oscar_session_url(od),
 			query_string, session_key);
 	url = g_strdup_printf("%s?%s&sig_sha256=%s", get_start_oscar_session_url(od),
--- a/libpurple/protocols/oscar/oscar.c	Thu Nov 04 19:20:38 2010 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Mon Nov 08 22:51:35 2010 +0000
@@ -616,16 +616,37 @@
 	ICQ_DEFAULT_SSL_LOGIN_SERVER,
 };
 
-static const gchar *get_login_server(gboolean is_icq, gboolean use_ssl)
+static const gchar *
+get_login_server(gboolean is_icq, gboolean use_ssl)
 {
 	return login_servers[(is_icq ? 2 : 0) + (use_ssl ? 1 : 0)];
 }
 
+static gint
+compare_handlers(gconstpointer a, gconstpointer b)
+{
+	guint aa = GPOINTER_TO_UINT(a);
+	guint bb = GPOINTER_TO_UINT(b);
+	guint family1 = aa >> 16;
+	guint family2 = bb >> 16;
+	guint subtype1 = aa & 0xFFFF;
+	guint subtype2 = bb & 0xFFFF;
+	if (family1 != family2) {
+		return family1 - family2;
+	}
+	return subtype1 - subtype2;
+}
+
 void
 oscar_login(PurpleAccount *account)
 {
 	PurpleConnection *gc;
 	OscarData *od;
+	const gchar *encryption_type;
+	GList *handlers;
+	GList *sorted_handlers;
+	GList *cur;
+	GString *msg = g_string_new("");
 
 	gc = purple_account_get_connection(account);
 	od = oscar_data_new();
@@ -684,6 +705,18 @@
 	oscar_data_addhandler(od, SNAC_FAMILY_USERLOOKUP, SNAC_SUBTYPE_USERLOOKUP_ERROR, purple_parse_searcherror, 0);
 	oscar_data_addhandler(od, SNAC_FAMILY_USERLOOKUP, 0x0003, purple_parse_searchreply, 0);
 
+	g_string_append(msg, "Registered handlers: ");
+	handlers = g_hash_table_get_keys(od->handlerlist);
+	sorted_handlers = g_list_sort(g_list_copy(handlers), compare_handlers);
+	for (cur = sorted_handlers; cur; cur = cur->next) {
+		guint x = GPOINTER_TO_UINT(cur->data);
+		g_string_append_printf(msg, "%04x/%04x, ", x >> 16, x & 0xFFFF);
+	}
+	g_list_free(sorted_handlers);
+	g_list_free(handlers);
+	purple_debug_misc("oscar", "%s\n", msg->str);
+	g_string_free(msg, TRUE);
+
 	purple_debug_misc("oscar", "oscar_login: gc = %p\n", gc);
 
 	if (!oscar_util_valid_name(purple_account_get_username(account))) {
@@ -703,7 +736,16 @@
 	}
 
 	od->default_port = purple_account_get_int(account, "port", OSCAR_DEFAULT_LOGIN_PORT);
-	od->use_ssl = purple_account_get_bool(account, "use_ssl", OSCAR_DEFAULT_USE_SSL);
+
+	encryption_type = purple_account_get_string(account, "encryption", OSCAR_DEFAULT_ENCRYPTION);
+	if (!purple_ssl_is_supported() && strcmp(encryption_type, OSCAR_REQUIRE_ENCRYPTION) == 0) {
+		purple_connection_error_reason(
+			gc,
+			PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
+			_("You required encryption in your account settings, but encryption is not supported by your system."));
+		return;
+	}
+	od->use_ssl = purple_ssl_is_supported() && strcmp(encryption_type, OSCAR_NO_ENCRYPTION) != 0;
 
 	/* Connect to core Purple signals */
 	purple_prefs_connect_callback(gc, "/purple/away/idle_reporting", idle_reporting_pref_cb, gc);
@@ -728,12 +770,6 @@
 		newconn = flap_connection_new(od, SNAC_FAMILY_AUTH);
 
 		if (od->use_ssl) {
-			if (!purple_ssl_is_supported()) {
-				purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
-						_("SSL support unavailable"));
-				return;
-			}
-
 			server = purple_account_get_string(account, "server", get_login_server(od->icq, TRUE));
 
 			/*
@@ -977,7 +1013,7 @@
 	conn->cookie = g_memdup(cookie, cookielen);
 
 	/*
-	 * Use SSL only if the server provided us with a tls_certname. The server might not specify a tls_certname even if we requested to use TLS, 
+	 * Use TLS only if the server provided us with a tls_certname. The server might not specify a tls_certname even if we requested to use TLS, 
 	 * and that is something we should be prepared to.
 	 */
 	if (tls_certname)
@@ -1233,6 +1269,20 @@
 	else
 		host = g_strdup(redir->ip);
 
+	if (!redir->use_ssl) {
+		const gchar *encryption_type = purple_account_get_string(account, "encryption", OSCAR_DEFAULT_ENCRYPTION);
+		if (strcmp(encryption_type, OSCAR_OPPORTUNISTIC_ENCRYPTION) == 0) {
+			purple_debug_warning("oscar", "We won't use SSL for FLAP type 0x%04hx.\n", redir->group);
+		} else if (strcmp(encryption_type, OSCAR_REQUIRE_ENCRYPTION) == 0) {
+			purple_debug_error("oscar", "FLAP server %s:%d of type 0x%04hx doesn't support encryption.", host, port, redir->group);
+			purple_connection_error_reason(
+				gc,
+				PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
+				_("You required encryption in your account settings, but one of the servers doesn't support it."));
+			return 0;
+		} 
+	}
+
 	/*
 	 * These FLAP servers advertise SSL (type "0x02"), but SSL connections to these hosts
 	 * die a painful death. iChat and Miranda, when using SSL, still do these in plaintext.
@@ -1240,14 +1290,11 @@
 	if (redir->use_ssl && (redir->group == SNAC_FAMILY_ADMIN ||
 	                       redir->group == SNAC_FAMILY_BART))
 	{
-		purple_debug_info("oscar", "Ignoring broken SSL for FLAP type 0x%04hx.\n",
-						redir->group);
+		purple_debug_info("oscar", "Ignoring broken SSL for FLAP type 0x%04hx.\n", redir->group);
 		redir->use_ssl = 0;
 	}
 
-	purple_debug_info("oscar", "Connecting to FLAP server %s:%d of type 0x%04hx%s\n",
-					host, port, redir->group,
-					od->use_ssl && !redir->use_ssl ? " without SSL, despite main stream encryption" : "");
+	purple_debug_info("oscar", "Connecting to FLAP server %s:%d of type 0x%04hx\n", host, port, redir->group);
 
 	newconn = flap_connection_new(od, redir->group);
 	newconn->cookielen = redir->cookielen;
@@ -2372,6 +2419,7 @@
 
 	switch(type) {
 		case 0x0002: {
+			GString *msg = g_string_new("");
 			guint8 maxrooms;
 			struct aim_chat_exchangeinfo *exchanges;
 			int exchangecount, i;
@@ -2380,15 +2428,17 @@
 			exchangecount = va_arg(ap, int);
 			exchanges = va_arg(ap, struct aim_chat_exchangeinfo *);
 
-			purple_debug_misc("oscar", "chat info: Chat Rights:\n");
-			purple_debug_misc("oscar",
-					   "chat info: \tMax Concurrent Rooms: %hhd\n", maxrooms);
-			purple_debug_misc("oscar",
-					   "chat info: \tExchange List: (%d total)\n", exchangecount);
-			for (i = 0; i < exchangecount; i++)
-				purple_debug_misc("oscar",
-						   "chat info: \t\t%hu    %s\n",
-						   exchanges[i].number, exchanges[i].name ? exchanges[i].name : "");
+			g_string_append_printf(msg, "chat info: Max Concurrent Rooms: %hhd, Exchange List (%d total): ", maxrooms, exchangecount);
+			for (i = 0; i < exchangecount; i++) {
+				g_string_append_printf(msg, "%hu", exchanges[i].number);
+				if (exchanges[i].name) {
+					g_string_append_printf(msg, " %s", exchanges[i].name);
+				}
+				g_string_append(msg, ", ");
+			}
+			purple_debug_misc("oscar", "%s\n", msg->str);
+			g_string_free(msg, TRUE);
+
 			while (od->create_rooms) {
 				struct create_room *cr = od->create_rooms->data;
 				purple_debug_info("oscar",
@@ -5649,15 +5699,34 @@
 	PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin);
 	PurpleAccountOption *option;
 	static gboolean init = FALSE;
-
-	option = purple_account_option_string_new(_("Server"), "server", get_login_server(is_icq, OSCAR_DEFAULT_USE_SSL));
+	static const gchar *encryption_keys[] = {
+		N_("Use encryption if available"),
+		N_("Require encryption"),
+		N_("Don't use encryption"),
+		NULL
+	};
+	static const gchar *encryption_values[] = {
+		OSCAR_OPPORTUNISTIC_ENCRYPTION,
+		OSCAR_REQUIRE_ENCRYPTION,
+		OSCAR_NO_ENCRYPTION,
+		NULL
+	};
+	GList *encryption_options = NULL;
+	int i;
+
+	option = purple_account_option_string_new(_("Server"), "server", get_login_server(is_icq, TRUE));
 	prpl_info->protocol_options = g_list_append(prpl_info->protocol_options, option);
 
 	option = purple_account_option_int_new(_("Port"), "port", OSCAR_DEFAULT_LOGIN_PORT);
 	prpl_info->protocol_options = g_list_append(prpl_info->protocol_options, option);
 
-	option = purple_account_option_bool_new(_("Use SSL"), "use_ssl",
-			OSCAR_DEFAULT_USE_SSL);
+	for (i = 0; encryption_keys[i]; i++) {
+		PurpleKeyValuePair *kvp = g_new0(PurpleKeyValuePair, 1);
+		kvp->key = g_strdup(encryption_keys[i]);
+		kvp->value = g_strdup(encryption_values[i]);
+		encryption_options = g_list_append(encryption_options, kvp);
+	}
+	option = purple_account_option_list_new(_("Connection security"), "encryption", encryption_options);
 	prpl_info->protocol_options = g_list_append(prpl_info->protocol_options, option);
 
 	option = purple_account_option_bool_new(_("Use clientLogin"), "use_clientlogin",
--- a/libpurple/protocols/oscar/oscar_data.c	Thu Nov 04 19:20:38 2010 +0000
+++ b/libpurple/protocols/oscar/oscar_data.c	Mon Nov 08 22:51:35 2010 +0000
@@ -37,6 +37,8 @@
 oscar_data_new(void)
 {
 	OscarData *od;
+	aim_module_t *cur;
+	GString *msg;
 
 	od = g_new0(OscarData, 1);
 
@@ -70,6 +72,20 @@
 	aim__registermodule(od, auth_modfirst);
 	aim__registermodule(od, email_modfirst);
 
+	msg = g_string_new("Registered modules: ");
+	for (cur = od->modlistv; cur; cur = cur->next) {
+		g_string_append_printf(
+			msg,
+			"%s (family=0x%04x, version=0x%04x, toolid=0x%04x, toolversion=0x%04x), ",
+			cur->name,
+			cur->family,
+			cur->version,
+			cur->toolid,
+			cur->toolversion);
+	}
+	purple_debug_misc("oscar", "%s\n", msg->str);
+	g_string_free(msg, TRUE);
+
 	return od;
 }
 
@@ -118,8 +134,6 @@
 {
 	SnacHandler *snac_handler;
 
-	purple_debug_misc("oscar", "Adding handler for %04x/%04x\n", family, subtype);
-
 	snac_handler = g_new0(SnacHandler, 1);
 
 	snac_handler->family = family;
--- a/libpurple/protocols/oscar/oscarcommon.h	Thu Nov 04 19:20:38 2010 +0000
+++ b/libpurple/protocols/oscar/oscarcommon.h	Mon Nov 08 22:51:35 2010 +0000
@@ -39,6 +39,10 @@
 
 #define OSCAR_DEFAULT_LOGIN_PORT 5190
 
+#define OSCAR_OPPORTUNISTIC_ENCRYPTION "opportunistic_encryption"
+#define OSCAR_REQUIRE_ENCRYPTION "require_encryption"
+#define OSCAR_NO_ENCRYPTION "no_encryption"
+
 #ifndef _WIN32
 #define OSCAR_DEFAULT_CUSTOM_ENCODING "ISO-8859-1"
 #else
@@ -49,8 +53,8 @@
 #define OSCAR_DEFAULT_WEB_AWARE FALSE
 #define OSCAR_DEFAULT_ALWAYS_USE_RV_PROXY FALSE
 #define OSCAR_DEFAULT_ALLOW_MULTIPLE_LOGINS TRUE
-#define OSCAR_DEFAULT_USE_SSL TRUE
 #define OSCAR_DEFAULT_USE_CLIENTLOGIN TRUE
+#define OSCAR_DEFAULT_ENCRYPTION OSCAR_OPPORTUNISTIC_ENCRYPTION
 
 #ifdef _WIN32
 const char *oscar_get_locale_charset(void);
--- a/libpurple/protocols/oscar/rxhandlers.c	Thu Nov 04 19:20:38 2010 +0000
+++ b/libpurple/protocols/oscar/rxhandlers.c	Mon Nov 08 22:51:35 2010 +0000
@@ -69,8 +69,6 @@
 	mod->next = (aim_module_t *)od->modlistv;
 	od->modlistv = mod;
 
-	purple_debug_misc("oscar", "registered module %s (family 0x%04x, version = 0x%04x, tool 0x%04x, tool version 0x%04x)\n", mod->name, mod->family, mod->version, mod->toolid, mod->toolversion);
-
 	return 0;
 }