Mercurial > pidgin.yaz
comparison libpurple/protocols/oscar/clientlogin.c @ 31085:4297feb30ad1
Merged everything related to ICQ server changes.
applied changes from b6d7712e90b68610df3bd2d8cbaf46d94c8b3794
through d849dc2a852a4ffdd345a150f0b88ab37de36e36
applied changes from 7aedaac3ed815cab16d758474a829d5ec5a59e4b
through d849dc2a852a4ffdd345a150f0b88ab37de36e36
author | ivan.komarov@soc.pidgin.im |
---|---|
date | Sat, 30 Oct 2010 21:36:34 +0000 |
parents | 943fce8ef142 |
children | d9e21370fca0 |
comparison
equal
deleted
inserted
replaced
31084:a61147460879 | 31085:4297feb30ad1 |
---|---|
40 #include "oscarcommon.h" | 40 #include "oscarcommon.h" |
41 | 41 |
42 #include "cipher.h" | 42 #include "cipher.h" |
43 #include "core.h" | 43 #include "core.h" |
44 | 44 |
45 #define URL_CLIENT_LOGIN "https://api.screenname.aol.com/auth/clientLogin" | 45 #define AIM_LOGIN_HOST "api.screenname.aol.com" |
46 #define URL_START_OSCAR_SESSION "https://api.oscar.aol.com/aim/startOSCARSession" | 46 #define ICQ_LOGIN_HOST "api.login.icq.net" |
47 | |
48 #define AIM_API_HOST "api.oscar.aol.com" | |
49 #define ICQ_API_HOST "api.icq.net" | |
50 | |
51 #define CLIENT_LOGIN_PAGE "/auth/clientLogin" | |
52 #define START_OSCAR_SESSION_PAGE "/aim/startOSCARSession" | |
53 | |
54 #define HTTPS_FORMAT_URL(host, page) "https://" host page | |
55 | |
56 static const gchar *client_login_urls[] = { | |
57 HTTPS_FORMAT_URL(AIM_LOGIN_HOST, CLIENT_LOGIN_PAGE), | |
58 HTTPS_FORMAT_URL(ICQ_LOGIN_HOST, CLIENT_LOGIN_PAGE), | |
59 }; | |
60 | |
61 static const gchar *start_oscar_session_urls[] = { | |
62 HTTPS_FORMAT_URL(AIM_API_HOST, START_OSCAR_SESSION_PAGE), | |
63 HTTPS_FORMAT_URL(ICQ_API_HOST, START_OSCAR_SESSION_PAGE), | |
64 }; | |
65 | |
66 static const gchar *get_client_login_url(OscarData *od) | |
67 { | |
68 return client_login_urls[od->icq]; | |
69 } | |
70 | |
71 static const gchar *get_start_oscar_session_url(OscarData *od) | |
72 { | |
73 return start_oscar_session_urls[od->icq]; | |
74 } | |
47 | 75 |
48 /* | 76 /* |
49 * Using clientLogin requires a developer ID. This key is for libpurple. | 77 * Using clientLogin requires a developer ID. This key is for libpurple. |
50 * It is the default key for all libpurple-based clients. AOL encourages | 78 * It is the default key for all libpurple-based clients. AOL encourages |
51 * UIs (especially ones with lots of users) to override this with their | 79 * UIs (especially ones with lots of users) to override this with their |
123 return signature; | 151 return signature; |
124 } | 152 } |
125 | 153 |
126 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) | 154 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) |
127 { | 155 { |
156 OscarData *od = purple_connection_get_protocol_data(gc); | |
128 xmlnode *response_node, *tmp_node, *data_node; | 157 xmlnode *response_node, *tmp_node, *data_node; |
129 xmlnode *host_node = NULL, *port_node = NULL, *cookie_node = NULL, *tls_node = NULL; | 158 xmlnode *host_node = NULL, *port_node = NULL, *cookie_node = NULL, *tls_node = NULL; |
130 gboolean use_tls; | 159 gboolean use_tls; |
131 char *tmp; | 160 char *tmp; |
132 guint code; | 161 guint code; |
140 char *msg; | 169 char *msg; |
141 purple_debug_error("oscar", "startOSCARSession could not parse " | 170 purple_debug_error("oscar", "startOSCARSession could not parse " |
142 "response as XML: %s\n", response); | 171 "response as XML: %s\n", response); |
143 /* Note to translators: %s in this string is a URL */ | 172 /* Note to translators: %s in this string is a URL */ |
144 msg = generate_error_message(response_node, | 173 msg = generate_error_message(response_node, |
145 URL_START_OSCAR_SESSION); | 174 get_start_oscar_session_url(od)); |
146 purple_connection_error_reason(gc, | 175 purple_connection_error_reason(gc, |
147 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); | 176 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); |
148 g_free(msg); | 177 g_free(msg); |
149 return FALSE; | 178 return FALSE; |
150 } | 179 } |
163 if (tmp_node == NULL || (tmp = xmlnode_get_data_unescaped(tmp_node)) == NULL) { | 192 if (tmp_node == NULL || (tmp = xmlnode_get_data_unescaped(tmp_node)) == NULL) { |
164 char *msg; | 193 char *msg; |
165 purple_debug_error("oscar", "startOSCARSession response was " | 194 purple_debug_error("oscar", "startOSCARSession response was " |
166 "missing statusCode: %s\n", response); | 195 "missing statusCode: %s\n", response); |
167 msg = generate_error_message(response_node, | 196 msg = generate_error_message(response_node, |
168 URL_START_OSCAR_SESSION); | 197 get_start_oscar_session_url(od)); |
169 purple_connection_error_reason(gc, | 198 purple_connection_error_reason(gc, |
170 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); | 199 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); |
171 g_free(msg); | 200 g_free(msg); |
172 xmlnode_free(response_node); | 201 xmlnode_free(response_node); |
173 return FALSE; | 202 return FALSE; |
201 "you continue to try, you will need to wait even " | 230 "you continue to try, you will need to wait even " |
202 "longer.")); | 231 "longer.")); |
203 else { | 232 else { |
204 char *msg; | 233 char *msg; |
205 msg = generate_error_message(response_node, | 234 msg = generate_error_message(response_node, |
206 URL_START_OSCAR_SESSION); | 235 get_start_oscar_session_url(od)); |
207 purple_connection_error_reason(gc, | 236 purple_connection_error_reason(gc, |
208 PURPLE_CONNECTION_ERROR_OTHER_ERROR, msg); | 237 PURPLE_CONNECTION_ERROR_OTHER_ERROR, msg); |
209 g_free(msg); | 238 g_free(msg); |
210 } | 239 } |
211 | 240 |
214 return FALSE; | 243 return FALSE; |
215 } | 244 } |
216 g_free(tmp); | 245 g_free(tmp); |
217 | 246 |
218 /* Make sure we have everything else */ | 247 /* Make sure we have everything else */ |
219 if (data_node == NULL || host_node == NULL || | 248 if (data_node == NULL || host_node == NULL || port_node == NULL || cookie_node == NULL) |
220 port_node == NULL || cookie_node == NULL || | |
221 (use_tls && tls_node == NULL)) | |
222 { | 249 { |
223 char *msg; | 250 char *msg; |
224 purple_debug_error("oscar", "startOSCARSession response was missing " | 251 purple_debug_error("oscar", "startOSCARSession response was missing " |
225 "something: %s\n", response); | 252 "something: %s\n", response); |
226 msg = generate_error_message(response_node, | 253 msg = generate_error_message(response_node, |
227 URL_START_OSCAR_SESSION); | 254 get_start_oscar_session_url(od)); |
228 purple_connection_error_reason(gc, | 255 purple_connection_error_reason(gc, |
229 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); | 256 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); |
230 g_free(msg); | 257 g_free(msg); |
231 xmlnode_free(response_node); | 258 xmlnode_free(response_node); |
232 return FALSE; | 259 return FALSE; |
235 /* Extract data from the XML */ | 262 /* Extract data from the XML */ |
236 *host = xmlnode_get_data_unescaped(host_node); | 263 *host = xmlnode_get_data_unescaped(host_node); |
237 tmp = xmlnode_get_data_unescaped(port_node); | 264 tmp = xmlnode_get_data_unescaped(port_node); |
238 *cookie = xmlnode_get_data_unescaped(cookie_node); | 265 *cookie = xmlnode_get_data_unescaped(cookie_node); |
239 | 266 |
240 if (use_tls) | 267 if (use_tls) { |
241 *tls_certname = xmlnode_get_data_unescaped(tls_node); | 268 if (tls_node != NULL) { |
242 | 269 *tls_certname = xmlnode_get_data_unescaped(tls_node); |
243 if (*host == NULL || **host == '\0' || tmp == NULL || *tmp == '\0' || *cookie == NULL || **cookie == '\0' || | 270 } else { |
244 (use_tls && (*tls_certname == NULL || **tls_certname == '\0'))) | 271 purple_debug_warning("oscar", "useTls was 1, but we haven't received a tlsCertName to use. We will not do SSL to BOS.\n"); |
272 } | |
273 } | |
274 | |
275 if (*host == NULL || **host == '\0' || tmp == NULL || *tmp == '\0' || *cookie == NULL || **cookie == '\0') | |
245 { | 276 { |
246 char *msg; | 277 char *msg; |
247 purple_debug_error("oscar", "startOSCARSession response was missing " | 278 purple_debug_error("oscar", "startOSCARSession response was missing " |
248 "something: %s\n", response); | 279 "something: %s\n", response); |
249 msg = generate_error_message(response_node, | 280 msg = generate_error_message(response_node, |
250 URL_START_OSCAR_SESSION); | 281 get_start_oscar_session_url(od)); |
251 purple_connection_error_reason(gc, | 282 purple_connection_error_reason(gc, |
252 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); | 283 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); |
253 g_free(msg); | 284 g_free(msg); |
254 g_free(*host); | 285 g_free(*host); |
255 g_free(tmp); | 286 g_free(tmp); |
282 if (error_message != NULL || len == 0) { | 313 if (error_message != NULL || len == 0) { |
283 gchar *tmp; | 314 gchar *tmp; |
284 /* Note to translators: The first %s is a URL, the second is an | 315 /* Note to translators: The first %s is a URL, the second is an |
285 error message. */ | 316 error message. */ |
286 tmp = g_strdup_printf(_("Error requesting %s: %s"), | 317 tmp = g_strdup_printf(_("Error requesting %s: %s"), |
287 URL_START_OSCAR_SESSION, error_message); | 318 get_start_oscar_session_url(od), error_message); |
288 purple_connection_error_reason(gc, | 319 purple_connection_error_reason(gc, |
289 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); | 320 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); |
290 g_free(tmp); | 321 g_free(tmp); |
291 return; | 322 return; |
292 } | 323 } |
324 "&useTLS=%d", | 355 "&useTLS=%d", |
325 purple_url_encode(token), | 356 purple_url_encode(token), |
326 oscar_get_ui_info_int(od->icq ? "prpl-icq-distid" | 357 oscar_get_ui_info_int(od->icq ? "prpl-icq-distid" |
327 : "prpl-aim-distid", 0x00000611), | 358 : "prpl-aim-distid", 0x00000611), |
328 get_client_key(od), hosttime, use_tls); | 359 get_client_key(od), hosttime, use_tls); |
329 signature = generate_signature("GET", URL_START_OSCAR_SESSION, | 360 signature = generate_signature("GET", get_start_oscar_session_url(od), |
330 query_string, session_key); | 361 query_string, session_key); |
331 url = g_strdup_printf(URL_START_OSCAR_SESSION "?%s&sig_sha256=%s", | 362 url = g_strdup_printf("%s?%s&sig_sha256=%s", get_start_oscar_session_url(od), |
332 query_string, signature); | 363 query_string, signature); |
333 g_free(query_string); | 364 g_free(query_string); |
334 g_free(signature); | 365 g_free(signature); |
335 | 366 |
336 /* Make the request */ | 367 /* Make the request */ |
365 * @return TRUE if the request was successful and we were able to | 396 * @return TRUE if the request was successful and we were able to |
366 * extract all info we need. Otherwise FALSE. | 397 * extract all info we need. Otherwise FALSE. |
367 */ | 398 */ |
368 static gboolean parse_client_login_response(PurpleConnection *gc, const gchar *response, gsize response_len, char **token, char **secret, time_t *hosttime) | 399 static gboolean parse_client_login_response(PurpleConnection *gc, const gchar *response, gsize response_len, char **token, char **secret, time_t *hosttime) |
369 { | 400 { |
401 OscarData *od = purple_connection_get_protocol_data(gc); | |
370 xmlnode *response_node, *tmp_node, *data_node; | 402 xmlnode *response_node, *tmp_node, *data_node; |
371 xmlnode *secret_node = NULL, *hosttime_node = NULL, *token_node = NULL, *tokena_node = NULL; | 403 xmlnode *secret_node = NULL, *hosttime_node = NULL, *token_node = NULL, *tokena_node = NULL; |
372 char *tmp; | 404 char *tmp; |
373 | 405 |
374 /* Parse the response as XML */ | 406 /* Parse the response as XML */ |
377 { | 409 { |
378 char *msg; | 410 char *msg; |
379 purple_debug_error("oscar", "clientLogin could not parse " | 411 purple_debug_error("oscar", "clientLogin could not parse " |
380 "response as XML: %s\n", response); | 412 "response as XML: %s\n", response); |
381 msg = generate_error_message(response_node, | 413 msg = generate_error_message(response_node, |
382 URL_CLIENT_LOGIN); | 414 get_client_login_url(od)); |
383 purple_connection_error_reason(gc, | 415 purple_connection_error_reason(gc, |
384 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); | 416 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); |
385 g_free(msg); | 417 g_free(msg); |
386 return FALSE; | 418 return FALSE; |
387 } | 419 } |
401 if (tmp_node == NULL || (tmp = xmlnode_get_data_unescaped(tmp_node)) == NULL) { | 433 if (tmp_node == NULL || (tmp = xmlnode_get_data_unescaped(tmp_node)) == NULL) { |
402 char *msg; | 434 char *msg; |
403 purple_debug_error("oscar", "clientLogin response was " | 435 purple_debug_error("oscar", "clientLogin response was " |
404 "missing statusCode: %s\n", response); | 436 "missing statusCode: %s\n", response); |
405 msg = generate_error_message(response_node, | 437 msg = generate_error_message(response_node, |
406 URL_CLIENT_LOGIN); | 438 get_client_login_url(od)); |
407 purple_connection_error_reason(gc, | 439 purple_connection_error_reason(gc, |
408 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); | 440 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); |
409 g_free(msg); | 441 g_free(msg); |
410 xmlnode_free(response_node); | 442 xmlnode_free(response_node); |
411 return FALSE; | 443 return FALSE; |
444 PURPLE_CONNECTION_ERROR_OTHER_ERROR, | 476 PURPLE_CONNECTION_ERROR_OTHER_ERROR, |
445 _("AOL does not allow your screen name to authenticate here")); | 477 _("AOL does not allow your screen name to authenticate here")); |
446 } else { | 478 } else { |
447 char *msg; | 479 char *msg; |
448 msg = generate_error_message(response_node, | 480 msg = generate_error_message(response_node, |
449 URL_CLIENT_LOGIN); | 481 get_client_login_url(od)); |
450 purple_connection_error_reason(gc, | 482 purple_connection_error_reason(gc, |
451 PURPLE_CONNECTION_ERROR_OTHER_ERROR, msg); | 483 PURPLE_CONNECTION_ERROR_OTHER_ERROR, msg); |
452 g_free(msg); | 484 g_free(msg); |
453 } | 485 } |
454 | 486 |
463 { | 495 { |
464 char *msg; | 496 char *msg; |
465 purple_debug_error("oscar", "clientLogin response was missing " | 497 purple_debug_error("oscar", "clientLogin response was missing " |
466 "something: %s\n", response); | 498 "something: %s\n", response); |
467 msg = generate_error_message(response_node, | 499 msg = generate_error_message(response_node, |
468 URL_CLIENT_LOGIN); | 500 get_client_login_url(od)); |
469 purple_connection_error_reason(gc, | 501 purple_connection_error_reason(gc, |
470 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); | 502 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); |
471 g_free(msg); | 503 g_free(msg); |
472 xmlnode_free(response_node); | 504 xmlnode_free(response_node); |
473 return FALSE; | 505 return FALSE; |
481 { | 513 { |
482 char *msg; | 514 char *msg; |
483 purple_debug_error("oscar", "clientLogin response was missing " | 515 purple_debug_error("oscar", "clientLogin response was missing " |
484 "something: %s\n", response); | 516 "something: %s\n", response); |
485 msg = generate_error_message(response_node, | 517 msg = generate_error_message(response_node, |
486 URL_CLIENT_LOGIN); | 518 get_client_login_url(od)); |
487 purple_connection_error_reason(gc, | 519 purple_connection_error_reason(gc, |
488 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); | 520 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); |
489 g_free(msg); | 521 g_free(msg); |
490 g_free(*token); | 522 g_free(*token); |
491 g_free(*secret); | 523 g_free(*secret); |
518 | 550 |
519 if (error_message != NULL || len == 0) { | 551 if (error_message != NULL || len == 0) { |
520 gchar *tmp; | 552 gchar *tmp; |
521 if (error_message != NULL) | 553 if (error_message != NULL) |
522 tmp = g_strdup_printf(_("Error requesting %s: %s"), | 554 tmp = g_strdup_printf(_("Error requesting %s: %s"), |
523 URL_CLIENT_LOGIN, error_message); | 555 get_client_login_url(od), error_message); |
524 else | 556 else |
525 tmp = g_strdup_printf(_("Error requesting %s"), | 557 tmp = g_strdup_printf(_("Error requesting %s"), |
526 URL_CLIENT_LOGIN); | 558 get_client_login_url(od)); |
527 purple_connection_error_reason(gc, | 559 purple_connection_error_reason(gc, |
528 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); | 560 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); |
529 g_free(tmp); | 561 g_free(tmp); |
530 return; | 562 return; |
531 } | 563 } |
597 g_string_append_len(request, body->str, body->len); | 629 g_string_append_len(request, body->str, body->len); |
598 g_string_free(body, TRUE); | 630 g_string_free(body, TRUE); |
599 | 631 |
600 /* Send the POST request */ | 632 /* Send the POST request */ |
601 od->url_data = purple_util_fetch_url_request_len_with_account( | 633 od->url_data = purple_util_fetch_url_request_len_with_account( |
602 purple_connection_get_account(gc), URL_CLIENT_LOGIN, | 634 purple_connection_get_account(gc), get_client_login_url(od), |
603 TRUE, NULL, FALSE, request->str, FALSE, -1, | 635 TRUE, NULL, FALSE, request->str, FALSE, -1, |
604 client_login_cb, od); | 636 client_login_cb, od); |
605 g_string_free(request, TRUE); | 637 g_string_free(request, TRUE); |
606 } | 638 } |