src/protocols/msn/notification.c

changeset 8171
c3c43a25caec
parent 8029
058ae2ae7b1f
child 8175
4e79974d452c
equal deleted inserted replaced
8170:f034b2951a24 8171:c3c43a25caec
126 (char *)msn_user_get_name(user)); 126 (char *)msn_user_get_name(user));
127 127
128 return TRUE; 128 return TRUE;
129 } 129 }
130 130
131 static size_t
132 msn_ssl_read(GaimSslConnection *gsc, char **dest_buffer)
133 {
134 size_t size = 0, s;
135 char *buffer = NULL;
136 char temp_buf[4096];
137
138 while ((s = gaim_ssl_read(gsc, temp_buf, sizeof(temp_buf))) > 0)
139 {
140 char *new_buffer = g_new(char, size + s + 1);
141
142 if (buffer != NULL)
143 {
144 strncpy(new_buffer, buffer, size);
145
146 g_free(buffer);
147 }
148
149 buffer = new_buffer;
150
151 strncpy(buffer + size, temp_buf, s);
152
153 buffer[size + s] = '\0';
154
155 size += s;
156 }
157
158 *dest_buffer = buffer;
159
160 return size;
161 }
162
163 /************************************************************************** 131 /**************************************************************************
164 * Callbacks 132 * Callbacks
165 **************************************************************************/ 133 **************************************************************************/
166 static void 134 static void
167 msn_accept_add_cb(MsnPermitAdd *pa) 135 msn_accept_add_cb(MsnPermitAdd *pa)
310 5, MSN_CONNECT_STEPS); 278 5, MSN_CONNECT_STEPS);
311 279
312 return TRUE; 280 return TRUE;
313 } 281 }
314 282
315 static void
316 login_error_cb(GaimSslConnection *gsc, GaimSslErrorType error, void *data)
317 {
318 MsnServConn *servconn = (MsnServConn *)data;
319 GaimAccount *account = servconn->session->account;
320 GaimConnection *gc = gaim_account_get_connection(account);
321
322 gaim_connection_error(gc, _("Unable to connect to server"));
323 }
324
325 static void
326 login_connect_cb(gpointer data, GaimSslConnection *gsc,
327 GaimInputCondition cond)
328 {
329 MsnServConn *servconn = (MsnServConn *)data;
330 MsnSession *session = servconn->session;
331 GaimConnection *gc = gaim_account_get_connection(session->account);
332 char *username, *password;
333 char *request_str;
334 char *buffer = NULL;
335 char *tpf;
336 size_t s;
337
338 username =
339 g_strdup(gaim_url_encode(gaim_account_get_username(session->account)));
340 password =
341 g_strdup(gaim_url_encode(gaim_account_get_password(session->account)));
342
343 tpf = (char *)g_hash_table_lookup(session->ssl_challenge_data, "tpf");
344
345 request_str = g_strdup_printf(
346 "GET %s HTTP/1.1\r\n"
347 "Authorization: Passport1.4 OrgVerb=GET,OrgURL=%s,sign-in=%s,pwd=%s,"
348 "lc=%s,id=%s,tw=%s,fs=%s,ru=%s,ct=%s,kpp=%s,kv=%s,ver=%s,tpf=%s\r\n"
349 "User-Agent: MSMSGS\r\n"
350 "Host: %s\r\n"
351 "Connection: Keep-Alive\r\n"
352 "Cache-Control: no-cache\r\n"
353 "\r\n",
354 session->ssl_login_path,
355 (char *)g_hash_table_lookup(session->ssl_challenge_data, "ru"),
356 username, password,
357 (char *)g_hash_table_lookup(session->ssl_challenge_data, "lc"),
358 (char *)g_hash_table_lookup(session->ssl_challenge_data, "id"),
359 (char *)g_hash_table_lookup(session->ssl_challenge_data, "tw"),
360 (char *)g_hash_table_lookup(session->ssl_challenge_data, "fs"),
361 (char *)g_hash_table_lookup(session->ssl_challenge_data, "ru"),
362 (char *)g_hash_table_lookup(session->ssl_challenge_data, "ct"),
363 (char *)g_hash_table_lookup(session->ssl_challenge_data, "kpp"),
364 (char *)g_hash_table_lookup(session->ssl_challenge_data, "kv"),
365 (char *)g_hash_table_lookup(session->ssl_challenge_data, "ver"),
366 (tpf == NULL ? "" : tpf),
367 session->ssl_login_host);
368
369 gaim_debug(GAIM_DEBUG_MISC, "msn", "Sending: {%s}\n", request_str);
370
371 g_free(username);
372 g_free(password);
373
374 if ((s = gaim_ssl_write(gsc, request_str, strlen(request_str))) <= 0)
375 {
376 g_free(request_str);
377 gaim_connection_error(gc, _("Unable to write to MSN Nexus server."));
378
379 return;
380 }
381
382 g_free(request_str);
383
384 if ((s = msn_ssl_read(gsc, &buffer)) <= 0)
385 {
386 gaim_connection_error(gc, _("Unable to read from MSN Nexus server."));
387
388 if (buffer != NULL)
389 g_free(buffer);
390
391 return;
392 }
393
394 gaim_ssl_close(gsc);
395
396 gaim_debug(GAIM_DEBUG_MISC, "msn", "ssl buffer: {%s}", buffer);
397
398 if (strstr(buffer, "HTTP/1.1 302") != NULL)
399 {
400 /* Redirect. */
401 char *location, *c;
402
403 if ((location = strstr(buffer, "Location: ")) == NULL)
404 {
405 gaim_connection_error(gc,
406 _("MSN Nexus server returned invalid redirect information."));
407
408 g_free(buffer);
409
410 return;
411 }
412
413 location = strchr(location, ' ') + 1;
414
415 if ((c = strchr(location, '\r')) != NULL)
416 *c = '\0';
417
418 /* Skip the http:// */
419 if ((c = strchr(location, '/')) != NULL)
420 location = c + 2;
421
422 if ((c = strchr(location, '/')) != NULL)
423 {
424 session->ssl_login_path = g_strdup(c);
425
426 *c = '\0';
427 }
428
429 session->ssl_login_host = g_strdup(location);
430
431 session->ssl_conn = gaim_ssl_connect(session->account,
432 session->ssl_login_host,
433 GAIM_SSL_DEFAULT_PORT,
434 login_connect_cb, login_error_cb,
435 servconn);
436 }
437 else if (strstr(buffer, "HTTP/1.1 401 Unauthorized") != NULL)
438 {
439 const char *error, *c;
440 char *temp;
441
442 if ((error = strstr(buffer, "WWW-Authenticate")) != NULL)
443 {
444 if ((error = strstr(error, "cbtxt=")) != NULL)
445 {
446 error += strlen("cbtxt=");
447
448 if ((c = strchr(error, '\n')) == NULL)
449 c = error + strlen(error);
450
451 temp = g_strndup(error, c - error);
452 error = gaim_url_decode(temp);
453 g_free(temp);
454 }
455 }
456
457 if (error == NULL)
458 {
459 gaim_connection_error(gc,
460 _("Unknown error when attempting to authorize with "
461 "MSN login server."));
462 }
463 else
464 gaim_connection_error(gc, error);
465 }
466 else
467 {
468 char *base, *c;
469 char outparams[MSN_BUF_LEN];
470
471 g_free(session->ssl_login_host);
472 g_free(session->ssl_login_path);
473 g_hash_table_destroy(session->ssl_challenge_data);
474
475 session->ssl_login_host = NULL;
476 session->ssl_login_path = NULL;
477 session->ssl_challenge_data = NULL;
478
479 #if 0
480 /* All your base are belong to us. */
481 base = buffer;
482
483 /* For great cookie! */
484 while ((base = strstr(base, "Set-Cookie: ")) != NULL)
485 {
486 base += strlen("Set-Cookie: ");
487
488 c = strchr(base, ';');
489
490 session->login_cookies =
491 g_list_append(session->login_cookies,
492 g_strndup(base, c - base));
493 }
494 #endif
495
496 if ((base = strstr(buffer, "Authentication-Info: ")) == NULL)
497 {
498 gaim_debug(GAIM_DEBUG_ERROR, "msn",
499 "Authentication information was not found. This did "
500 "not just happen, but if it did, you're screwed. "
501 "Report this.\n");
502
503 return;
504 }
505
506 base = strstr(base, "from-PP='");
507 base += strlen("from-PP='");
508 c = strchr(base, '\'');
509
510 session->ssl_login_params = g_strndup(base, c - base);
511
512 g_snprintf(outparams, sizeof(outparams),
513 "TWN S %s", session->ssl_login_params);
514
515 g_free(session->ssl_login_params);
516 session->ssl_login_params = NULL;
517
518 if (!msn_servconn_send_command(session->notification_conn, "USR",
519 outparams))
520 {
521 gaim_connection_error(gc, _("Unable to request USR\n"));
522 }
523 }
524
525 g_free(buffer);
526 }
527
528 static void
529 nexus_connect_cb(gpointer data, GaimSslConnection *gsc,
530 GaimInputCondition cond)
531 {
532 MsnServConn *servconn = (MsnServConn *)data;
533 MsnSession *session = servconn->session;
534 GaimConnection *gc = gaim_account_get_connection(session->account);
535 char *request_str;
536 char *da_login;
537 char *base, *c;
538 char *buffer = NULL;
539 size_t s;
540
541 request_str = g_strdup_printf("GET /rdr/pprdr.asp\r\n\r\n");
542
543 if ((s = gaim_ssl_write(gsc, request_str, strlen(request_str))) <= 0)
544 {
545 g_free(request_str);
546 gaim_connection_error(gc, _("Unable to write to MSN Nexus server."));
547 return;
548 }
549
550 g_free(request_str);
551
552 if (session->ssl_url != NULL)
553 {
554 g_free(session->ssl_url);
555 session->ssl_url = NULL;
556 }
557
558 /* Get the PassportURLs line. */
559 if ((s = msn_ssl_read(gsc, &buffer)) <= 0)
560 {
561 gaim_connection_error(gc, _("Unable to read from MSN Nexus server."));
562
563 if (buffer != NULL)
564 g_free(buffer);
565
566 return;
567 }
568
569 if ((base = strstr(buffer, "PassportURLs")) == NULL)
570 {
571 gaim_connection_error(gc,
572 _("MSN Nexus server returned invalid information."));
573
574 g_free(buffer);
575
576 return;
577 }
578
579 if ((da_login = strstr(base, "DALogin=")) != NULL)
580 {
581 if ((da_login = strchr(da_login, '=')) != NULL)
582 da_login++;
583
584 if ((c = strchr(da_login, ',')) != NULL)
585 *c = '\0';
586
587 if ((c = strchr(da_login, '/')) != NULL)
588 {
589 session->ssl_login_path = g_strdup(c);
590
591 *c = '\0';
592 }
593
594 session->ssl_login_host = g_strdup(da_login);
595 }
596
597 g_free(buffer);
598
599 gaim_ssl_close(gsc);
600
601 /* Now begin the connection to the login server. */
602 session->ssl_conn = gaim_ssl_connect(session->account,
603 session->ssl_login_host,
604 GAIM_SSL_DEFAULT_PORT,
605 login_connect_cb, login_error_cb,
606 servconn);
607 }
608
609 static gboolean 283 static gboolean
610 usr_cmd(MsnServConn *servconn, const char *command, const char **params, 284 usr_cmd(MsnServConn *servconn, const char *command, const char **params,
611 size_t param_count) 285 size_t param_count)
612 { 286 {
613 MsnSession *session = servconn->session; 287 MsnSession *session = servconn->session;
641 gaim_connection_update_progress(gc, _("Retrieving buddy list"), 315 gaim_connection_update_progress(gc, _("Retrieving buddy list"),
642 7, MSN_CONNECT_STEPS); 316 7, MSN_CONNECT_STEPS);
643 } 317 }
644 else if (!g_ascii_strcasecmp(params[1], "TWN")) 318 else if (!g_ascii_strcasecmp(params[1], "TWN"))
645 { 319 {
320 char **elems, **cur, **tokens;
321
646 /* Passport authentication */ 322 /* Passport authentication */
647 char *challenge_data; 323 session->nexus = msn_nexus_new(session);
648 char *key, *value = NULL;
649 char *c;
650
651 if (session->ssl_challenge_data != NULL)
652 g_hash_table_destroy(session->ssl_challenge_data);
653
654 session->ssl_challenge_data =
655 g_hash_table_new_full(g_str_hash, g_str_equal,
656 g_free, g_free);
657 324
658 /* Parse the challenge data. */ 325 /* Parse the challenge data. */
659 326 elems = g_strsplit(params[3], ",", 0);
660 challenge_data = g_strdup(params[3]); 327
661 328 for (cur = elems; *cur != NULL; cur++)
662 for (c = challenge_data, key = challenge_data; *c != '\0'; c++) 329 {
663 { 330 tokens = g_strsplit(*cur, "=", 2);
664 if (*c == '=') 331 g_hash_table_insert(session->nexus->challenge_data, tokens[0], tokens[1]);
665 { 332 /* Don't free each of the tokens, only the array. */
666 *c = '\0'; 333 g_free(tokens);
667 334 }
668 value = c + 1; 335
669 } 336 g_strfreev(elems);
670 else if (*c == ',') 337
671 { 338 msn_nexus_connect(session->nexus);
672 *c = '\0';
673
674 g_hash_table_insert(session->ssl_challenge_data,
675 g_strdup(key), g_strdup(value));
676
677 key = c + 1;
678 }
679 }
680
681 if (key < value)
682 {
683 /* Let's not forget the last one, it doesn't end with a ',' */
684 g_hash_table_insert(session->ssl_challenge_data,
685 g_strdup(key), g_strdup(value));
686 }
687
688 g_free(challenge_data);
689
690 #if 0
691 passport_str = g_strdup(gaim_url_decode(params[3]));
692
693 for (c = passport_str; *c != '\0'; c++)
694 {
695 if (*c == ',')
696 *c = '&';
697 }
698
699 session->ssl_url = passport_str;
700 #endif
701
702 session->ssl_conn = gaim_ssl_connect(session->account,
703 "nexus.passport.com",
704 GAIM_SSL_DEFAULT_PORT,
705 nexus_connect_cb, login_error_cb,
706 servconn);
707
708 if (session->ssl_conn == NULL)
709 {
710 gaim_connection_error(gc,
711 _("Unable to connect to passport server"));
712
713 return FALSE;
714 }
715 339
716 gaim_connection_update_progress(gc, _("Password sent"), 340 gaim_connection_update_progress(gc, _("Password sent"),
717 6, MSN_CONNECT_STEPS); 341 6, MSN_CONNECT_STEPS);
718 } 342 }
719 else if (!g_ascii_strcasecmp(params[1], "MD5")) 343 else if (!g_ascii_strcasecmp(params[1], "MD5"))

mercurial