summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Aurich <darkrain42@pidgin.im>2009-11-06 03:58:26 +0000
committerPaul Aurich <darkrain42@pidgin.im>2009-11-06 03:58:26 +0000
commit1231b5ac9fbbd3724dfe8248a3d2eba2cab9e7e1 (patch)
tree926298e47c7f536fa2733594da53c7b7a8454899
parent9a8df267b081ef59fffa9b6ee7145ea66aa2eb17 (diff)
downloadpidgin-1231b5ac9fbbd3724dfe8248a3d2eba2cab9e7e1.tar.gz
oscar: Properly support TLS when using clientLogin.
-rw-r--r--ChangeLog4
-rw-r--r--libpurple/protocols/oscar/clientlogin.c30
-rw-r--r--libpurple/protocols/oscar/oscar.c28
-rw-r--r--libpurple/protocols/oscar/oscar.h2
4 files changed, 48 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index 0968dd754d..e0c64e0659 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -11,14 +11,14 @@ version 2.6.4 (??/??/20??):
* Fix building the GnuTLS plugin with older versions of GnuTLS.
* Fix DNS TXT query resolution.
* Always rejoin open chats after an account reconnects.
+
AIM and ICQ:
* Better rate limit calculations and other improvements. (Aman Gupta)
* More detailed error messages when messages fail to send. (Aman Gupta)
* The simultaneous login account option is respected when using
the clientLogin authentication method.
-
- AIM and ICQ:
* Fix offline message retrieval (broken in 2.6.3)
+ * Fix SSL when clientLogin is enabled.
MSN:
* Don't forget display names for buddies.
diff --git a/libpurple/protocols/oscar/clientlogin.c b/libpurple/protocols/oscar/clientlogin.c
index 6b131600cc..35462348f6 100644
--- a/libpurple/protocols/oscar/clientlogin.c
+++ b/libpurple/protocols/oscar/clientlogin.c
@@ -40,6 +40,7 @@
#include "core.h"
#include "oscar.h"
+#include "oscarcommon.h"
#define URL_CLIENT_LOGIN "https://api.screenname.aol.com/auth/clientLogin"
#define URL_START_OSCAR_SESSION "http://api.oscar.aol.com/aim/startOSCARSession"
@@ -102,12 +103,15 @@ static gchar *generate_signature(const char *method, const char *url, const char
return signature;
}
-static gboolean parse_start_oscar_session_response(PurpleConnection *gc, const gchar *response, gsize response_len, char **host, unsigned short *port, char **cookie)
+static gboolean parse_start_oscar_session_response(PurpleConnection *gc, const gchar *response, gsize response_len, char **host, unsigned short *port, char **cookie, char **tls_certname)
{
xmlnode *response_node, *tmp_node, *data_node;
- xmlnode *host_node = NULL, *port_node = NULL, *cookie_node = NULL;
+ xmlnode *host_node = NULL, *port_node = NULL, *cookie_node = NULL, *tls_node = NULL;
+ gboolean use_tls;
char *tmp;
+ use_tls = purple_account_get_bool(purple_connection_get_account(gc), "use_ssl", OSCAR_DEFAULT_USE_SSL);
+
/* Parse the response as XML */
response_node = xmlnode_from_str(response, response_len);
if (response_node == NULL)
@@ -131,6 +135,7 @@ static gboolean parse_start_oscar_session_response(PurpleConnection *gc, const g
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 */
@@ -177,7 +182,8 @@ static gboolean parse_start_oscar_session_response(PurpleConnection *gc, const g
/* Make sure we have everything else */
if (data_node == NULL || host_node == NULL ||
- port_node == NULL || cookie_node == NULL)
+ port_node == NULL || cookie_node == NULL ||
+ (use_tls && tls_node == NULL))
{
char *msg;
purple_debug_error("oscar", "startOSCARSession response was missing "
@@ -195,7 +201,12 @@ static gboolean parse_start_oscar_session_response(PurpleConnection *gc, const g
*host = xmlnode_get_data_unescaped(host_node);
tmp = xmlnode_get_data_unescaped(port_node);
*cookie = xmlnode_get_data_unescaped(cookie_node);
- if (*host == NULL || **host == '\0' || tmp == NULL || *tmp == '\0' || cookie == NULL || *cookie == '\0')
+
+ if (use_tls)
+ *tls_certname = xmlnode_get_data_unescaped(tls_node);
+
+ if (*host == NULL || **host == '\0' || tmp == NULL || *tmp == '\0' || cookie == NULL || *cookie == '\0' ||
+ (use_tls && (*tls_certname == NULL || **tls_certname == '\0')))
{
char *msg;
purple_debug_error("oscar", "startOSCARSession response was missing "
@@ -223,6 +234,7 @@ static void start_oscar_session_cb(PurpleUtilFetchUrlData *url_data, gpointer us
OscarData *od;
PurpleConnection *gc;
char *host, *cookie;
+ char *tls_certname = NULL;
unsigned short port;
guint8 *cookiedata;
gsize cookiedata_len;
@@ -244,28 +256,30 @@ static void start_oscar_session_cb(PurpleUtilFetchUrlData *url_data, gpointer us
return;
}
- if (!parse_start_oscar_session_response(gc, url_text, len, &host, &port, &cookie))
+ if (!parse_start_oscar_session_response(gc, url_text, len, &host, &port, &cookie, &tls_certname))
return;
cookiedata = purple_base64_decode(cookie, &cookiedata_len);
- oscar_connect_to_bos(gc, od, host, port, cookiedata, cookiedata_len);
+ oscar_connect_to_bos(gc, od, host, port, cookiedata, cookiedata_len, tls_certname);
g_free(cookiedata);
g_free(host);
g_free(cookie);
+ g_free(tls_certname);
}
static void send_start_oscar_session(OscarData *od, const char *token, const char *session_key, time_t hosttime)
{
char *query_string, *signature, *url;
+ gboolean use_tls = purple_account_get_bool(purple_connection_get_account(od->gc), "use_ssl", OSCAR_DEFAULT_USE_SSL);
/* Construct the GET parameters */
query_string = g_strdup_printf("a=%s"
"&f=xml"
"&k=%s"
"&ts=%" PURPLE_TIME_T_MODIFIER
- "&useTLS=0",
- purple_url_encode(token), get_client_key(od), hosttime);
+ "&useTLS=%d",
+ purple_url_encode(token), get_client_key(od), hosttime, use_tls);
signature = generate_signature("GET", URL_START_OSCAR_SESSION,
query_string, session_key);
url = g_strdup_printf(URL_START_OSCAR_SESSION "?%s&sig_sha256=%s",
diff --git a/libpurple/protocols/oscar/oscar.c b/libpurple/protocols/oscar/oscar.c
index 2533997681..0326f0ef70 100644
--- a/libpurple/protocols/oscar/oscar.c
+++ b/libpurple/protocols/oscar/oscar.c
@@ -1827,17 +1827,35 @@ static int purple_memrequest(OscarData *od, FlapConnection *conn, FlapFrame *fr,
return 1;
}
-int oscar_connect_to_bos(PurpleConnection *gc, OscarData *od, const char *host, guint16 port, guint8 *cookie, guint16 cookielen)
+int oscar_connect_to_bos(PurpleConnection *gc, OscarData *od, const char *host, guint16 port, guint8 *cookie, guint16 cookielen, const char *tls_certname)
{
+ PurpleAccount *account;
FlapConnection *conn;
+ account = purple_connection_get_account(gc);
+
conn = flap_connection_new(od, SNAC_FAMILY_LOCATE);
conn->cookielen = cookielen;
conn->cookie = g_memdup(cookie, cookielen);
- conn->connect_data = purple_proxy_connect(NULL,
- purple_connection_get_account(gc), host, port,
- connection_established_cb, conn);
- if (conn->connect_data == NULL)
+
+ /*
+ * tls_certname is only set (and must be set if we get this far) if
+ * SSL is enabled.
+ */
+ if (tls_certname)
+ {
+ conn->gsc = purple_ssl_connect_with_ssl_cn(account, host, port,
+ ssl_connection_established_cb, ssl_connection_error_cb,
+ tls_certname, conn);
+ }
+ else
+ {
+ conn->connect_data = purple_proxy_connect(NULL,
+ account, host, port,
+ connection_established_cb, conn);
+ }
+
+ if (conn->gsc == NULL && conn->connect_data == NULL)
{
purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect"));
return 0;
diff --git a/libpurple/protocols/oscar/oscar.h b/libpurple/protocols/oscar/oscar.h
index fe994993b0..6ea143600b 100644
--- a/libpurple/protocols/oscar/oscar.h
+++ b/libpurple/protocols/oscar/oscar.h
@@ -623,7 +623,7 @@ struct aim_redirect_data
} chat;
};
-int oscar_connect_to_bos(PurpleConnection *gc, OscarData *od, const char *host, guint16 port, guint8 *cookie, guint16 cookielen);
+int oscar_connect_to_bos(PurpleConnection *gc, OscarData *od, const char *host, guint16 port, guint8 *cookie, guint16 cookielen, const char *tls_certname);
/* family_auth.c */