# HG changeset patch # User ivan.komarov@soc.pidgin.im # Date 1288913900 0 # Node ID f8f853ab3aba97afdbb274751c4f32536b86d1ac # Parent 4f0d6ee5ffee6f902d283c0599a8a9f6a18f17bf A followup commit to d849dc2a852a4ffdd345a150f0b88ab37de36e36. Daniel voiced discontent with how I silently fall back to insecure connection, so I changed the old 'Use SSL' checkbox to a XMPP-style dropdown (Require encryption/Use encryption if available/ Don't use encryption), as was discussed on devel@. diff -r 4f0d6ee5ffee -r f8f853ab3aba libpurple/protocols/oscar/clientlogin.c --- a/libpurple/protocols/oscar/clientlogin.c Thu Nov 04 18:28:48 2010 +0000 +++ b/libpurple/protocols/oscar/clientlogin.c Thu Nov 04 23:38:20 2010 +0000 @@ -168,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); @@ -197,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 */ @@ -271,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; @@ -349,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 @@ -366,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), diff -r 4f0d6ee5ffee -r f8f853ab3aba libpurple/protocols/oscar/oscar.c --- a/libpurple/protocols/oscar/oscar.c Thu Nov 04 18:28:48 2010 +0000 +++ b/libpurple/protocols/oscar/oscar.c Thu Nov 04 23:38:20 2010 +0000 @@ -626,6 +626,7 @@ { PurpleConnection *gc; OscarData *od; + const gchar *encryption_type; gc = purple_account_get_connection(account); od = oscar_data_new(); @@ -703,7 +704,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 +738,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 +981,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 +1237,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 +1258,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; @@ -5649,15 +5664,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", diff -r 4f0d6ee5ffee -r f8f853ab3aba libpurple/protocols/oscar/oscarcommon.h --- a/libpurple/protocols/oscar/oscarcommon.h Thu Nov 04 18:28:48 2010 +0000 +++ b/libpurple/protocols/oscar/oscarcommon.h Thu Nov 04 23:38:20 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);