comparison libpurple/protocols/oscar/clientlogin.c @ 28509:17617d892bc4

oscar: Properly support TLS when using clientLogin.
author Paul Aurich <paul@darkrain42.org>
date Fri, 06 Nov 2009 03:58:26 +0000
parents 79c14adf9669
children 7963477c2019
comparison
equal deleted inserted replaced
28508:281bd8a973d8 28509:17617d892bc4
38 38
39 #include "cipher.h" 39 #include "cipher.h"
40 #include "core.h" 40 #include "core.h"
41 41
42 #include "oscar.h" 42 #include "oscar.h"
43 #include "oscarcommon.h"
43 44
44 #define URL_CLIENT_LOGIN "https://api.screenname.aol.com/auth/clientLogin" 45 #define URL_CLIENT_LOGIN "https://api.screenname.aol.com/auth/clientLogin"
45 #define URL_START_OSCAR_SESSION "http://api.oscar.aol.com/aim/startOSCARSession" 46 #define URL_START_OSCAR_SESSION "http://api.oscar.aol.com/aim/startOSCARSession"
46 47
47 /* 48 /*
100 g_free(signature_base_string); 101 g_free(signature_base_string);
101 102
102 return signature; 103 return signature;
103 } 104 }
104 105
105 static gboolean parse_start_oscar_session_response(PurpleConnection *gc, const gchar *response, gsize response_len, char **host, unsigned short *port, char **cookie) 106 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)
106 { 107 {
107 xmlnode *response_node, *tmp_node, *data_node; 108 xmlnode *response_node, *tmp_node, *data_node;
108 xmlnode *host_node = NULL, *port_node = NULL, *cookie_node = NULL; 109 xmlnode *host_node = NULL, *port_node = NULL, *cookie_node = NULL, *tls_node = NULL;
110 gboolean use_tls;
109 char *tmp; 111 char *tmp;
112
113 use_tls = purple_account_get_bool(purple_connection_get_account(gc), "use_ssl", OSCAR_DEFAULT_USE_SSL);
110 114
111 /* Parse the response as XML */ 115 /* Parse the response as XML */
112 response_node = xmlnode_from_str(response, response_len); 116 response_node = xmlnode_from_str(response, response_len);
113 if (response_node == NULL) 117 if (response_node == NULL)
114 { 118 {
129 data_node = xmlnode_get_child(response_node, "data"); 133 data_node = xmlnode_get_child(response_node, "data");
130 if (data_node != NULL) { 134 if (data_node != NULL) {
131 host_node = xmlnode_get_child(data_node, "host"); 135 host_node = xmlnode_get_child(data_node, "host");
132 port_node = xmlnode_get_child(data_node, "port"); 136 port_node = xmlnode_get_child(data_node, "port");
133 cookie_node = xmlnode_get_child(data_node, "cookie"); 137 cookie_node = xmlnode_get_child(data_node, "cookie");
138 tls_node = xmlnode_get_child(data_node, "tlsCertName");
134 } 139 }
135 140
136 /* Make sure we have a status code */ 141 /* Make sure we have a status code */
137 if (tmp_node == NULL || (tmp = xmlnode_get_data_unescaped(tmp_node)) == NULL) { 142 if (tmp_node == NULL || (tmp = xmlnode_get_data_unescaped(tmp_node)) == NULL) {
138 char *msg; 143 char *msg;
175 } 180 }
176 g_free(tmp); 181 g_free(tmp);
177 182
178 /* Make sure we have everything else */ 183 /* Make sure we have everything else */
179 if (data_node == NULL || host_node == NULL || 184 if (data_node == NULL || host_node == NULL ||
180 port_node == NULL || cookie_node == NULL) 185 port_node == NULL || cookie_node == NULL ||
186 (use_tls && tls_node == NULL))
181 { 187 {
182 char *msg; 188 char *msg;
183 purple_debug_error("oscar", "startOSCARSession response was missing " 189 purple_debug_error("oscar", "startOSCARSession response was missing "
184 "something: %s\n", response); 190 "something: %s\n", response);
185 msg = g_strdup_printf(_("Received unexpected response from %s"), 191 msg = g_strdup_printf(_("Received unexpected response from %s"),
193 199
194 /* Extract data from the XML */ 200 /* Extract data from the XML */
195 *host = xmlnode_get_data_unescaped(host_node); 201 *host = xmlnode_get_data_unescaped(host_node);
196 tmp = xmlnode_get_data_unescaped(port_node); 202 tmp = xmlnode_get_data_unescaped(port_node);
197 *cookie = xmlnode_get_data_unescaped(cookie_node); 203 *cookie = xmlnode_get_data_unescaped(cookie_node);
198 if (*host == NULL || **host == '\0' || tmp == NULL || *tmp == '\0' || cookie == NULL || *cookie == '\0') 204
205 if (use_tls)
206 *tls_certname = xmlnode_get_data_unescaped(tls_node);
207
208 if (*host == NULL || **host == '\0' || tmp == NULL || *tmp == '\0' || cookie == NULL || *cookie == '\0' ||
209 (use_tls && (*tls_certname == NULL || **tls_certname == '\0')))
199 { 210 {
200 char *msg; 211 char *msg;
201 purple_debug_error("oscar", "startOSCARSession response was missing " 212 purple_debug_error("oscar", "startOSCARSession response was missing "
202 "something: %s\n", response); 213 "something: %s\n", response);
203 msg = g_strdup_printf(_("Received unexpected response from %s"), 214 msg = g_strdup_printf(_("Received unexpected response from %s"),
221 static void start_oscar_session_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message) 232 static void start_oscar_session_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message)
222 { 233 {
223 OscarData *od; 234 OscarData *od;
224 PurpleConnection *gc; 235 PurpleConnection *gc;
225 char *host, *cookie; 236 char *host, *cookie;
237 char *tls_certname = NULL;
226 unsigned short port; 238 unsigned short port;
227 guint8 *cookiedata; 239 guint8 *cookiedata;
228 gsize cookiedata_len; 240 gsize cookiedata_len;
229 241
230 od = user_data; 242 od = user_data;
242 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); 254 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
243 g_free(tmp); 255 g_free(tmp);
244 return; 256 return;
245 } 257 }
246 258
247 if (!parse_start_oscar_session_response(gc, url_text, len, &host, &port, &cookie)) 259 if (!parse_start_oscar_session_response(gc, url_text, len, &host, &port, &cookie, &tls_certname))
248 return; 260 return;
249 261
250 cookiedata = purple_base64_decode(cookie, &cookiedata_len); 262 cookiedata = purple_base64_decode(cookie, &cookiedata_len);
251 oscar_connect_to_bos(gc, od, host, port, cookiedata, cookiedata_len); 263 oscar_connect_to_bos(gc, od, host, port, cookiedata, cookiedata_len, tls_certname);
252 g_free(cookiedata); 264 g_free(cookiedata);
253 265
254 g_free(host); 266 g_free(host);
255 g_free(cookie); 267 g_free(cookie);
268 g_free(tls_certname);
256 } 269 }
257 270
258 static void send_start_oscar_session(OscarData *od, const char *token, const char *session_key, time_t hosttime) 271 static void send_start_oscar_session(OscarData *od, const char *token, const char *session_key, time_t hosttime)
259 { 272 {
260 char *query_string, *signature, *url; 273 char *query_string, *signature, *url;
274 gboolean use_tls = purple_account_get_bool(purple_connection_get_account(od->gc), "use_ssl", OSCAR_DEFAULT_USE_SSL);
261 275
262 /* Construct the GET parameters */ 276 /* Construct the GET parameters */
263 query_string = g_strdup_printf("a=%s" 277 query_string = g_strdup_printf("a=%s"
264 "&f=xml" 278 "&f=xml"
265 "&k=%s" 279 "&k=%s"
266 "&ts=%" PURPLE_TIME_T_MODIFIER 280 "&ts=%" PURPLE_TIME_T_MODIFIER
267 "&useTLS=0", 281 "&useTLS=%d",
268 purple_url_encode(token), get_client_key(od), hosttime); 282 purple_url_encode(token), get_client_key(od), hosttime, use_tls);
269 signature = generate_signature("GET", URL_START_OSCAR_SESSION, 283 signature = generate_signature("GET", URL_START_OSCAR_SESSION,
270 query_string, session_key); 284 query_string, session_key);
271 url = g_strdup_printf(URL_START_OSCAR_SESSION "?%s&sig_sha256=%s", 285 url = g_strdup_printf(URL_START_OSCAR_SESSION "?%s&sig_sha256=%s",
272 query_string, signature); 286 query_string, signature);
273 g_free(query_string); 287 g_free(query_string);