| 48 if(purple_ssl_is_supported()) { |
48 if(purple_ssl_is_supported()) { |
| 49 jabber_send_raw(js, |
49 jabber_send_raw(js, |
| 50 "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>", -1); |
50 "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>", -1); |
| 51 return TRUE; |
51 return TRUE; |
| 52 } else if(xmlnode_get_child(starttls, "required")) { |
52 } else if(xmlnode_get_child(starttls, "required")) { |
| 53 purple_connection_error(js->gc, _("Server requires TLS/SSL for login. No TLS/SSL support found.")); |
53 purple_connection_error_reason (js->gc, PURPLE_REASON_ENCRYPTION_ERROR, |
| |
54 _("Server requires TLS/SSL for login. No TLS/SSL support found.")); |
| 54 return TRUE; |
55 return TRUE; |
| 55 } |
56 } |
| 56 } |
57 } |
| 57 |
58 |
| 58 return FALSE; |
59 return FALSE; |
| 111 finish_plaintext_authentication(account->gc->proto_data); |
112 finish_plaintext_authentication(account->gc->proto_data); |
| 112 } |
113 } |
| 113 |
114 |
| 114 static void disallow_plaintext_auth(PurpleAccount *account) |
115 static void disallow_plaintext_auth(PurpleAccount *account) |
| 115 { |
116 { |
| 116 purple_connection_error(account->gc, _("Server requires plaintext authentication over an unencrypted stream")); |
117 purple_connection_error_reason (account->gc, PURPLE_REASON_ENCRYPTION_ERROR, |
| |
118 _("Server requires plaintext authentication over an unencrypted stream")); |
| 117 } |
119 } |
| 118 |
120 |
| 119 #ifdef HAVE_CYRUS_SASL |
121 #ifdef HAVE_CYRUS_SASL |
| 120 |
122 |
| 121 static void jabber_auth_start_cyrus(JabberStream *); |
123 static void jabber_auth_start_cyrus(JabberStream *); |
| 329 /* Everything else has failed, so fail the |
331 /* Everything else has failed, so fail the |
| 330 * connection. Should probably have a better |
332 * connection. Should probably have a better |
| 331 * error here. |
333 * error here. |
| 332 */ |
334 */ |
| 333 } else { |
335 } else { |
| 334 purple_connection_error(js->gc, _("Server does not use any supported authentication method")); |
336 purple_connection_error_reason (js->gc, |
| |
337 PURPLE_REASON_AUTHENTICATION_IMPOSSIBLE, |
| |
338 _("Server does not use any supported authentication method")); |
| 335 return; |
339 return; |
| 336 } |
340 } |
| 337 /* not reached */ |
341 /* not reached */ |
| 338 break; |
342 break; |
| 339 |
343 |
| 384 } |
388 } |
| 385 } |
389 } |
| 386 jabber_send(js, auth); |
390 jabber_send(js, auth); |
| 387 xmlnode_free(auth); |
391 xmlnode_free(auth); |
| 388 } else { |
392 } else { |
| 389 purple_connection_error(js->gc, "SASL authentication failed\n"); |
393 purple_connection_error_reason (js->gc, |
| |
394 PURPLE_REASON_AUTHENTICATION_IMPOSSIBLE, |
| |
395 "SASL authentication failed\n"); |
| 390 } |
396 } |
| 391 } |
397 } |
| 392 |
398 |
| 393 static int |
399 static int |
| 394 jabber_sasl_cb_log(void *context, int level, const char *message) |
400 jabber_sasl_cb_log(void *context, int level, const char *message) |
| 457 } |
463 } |
| 458 |
464 |
| 459 mechs = xmlnode_get_child(packet, "mechanisms"); |
465 mechs = xmlnode_get_child(packet, "mechanisms"); |
| 460 |
466 |
| 461 if(!mechs) { |
467 if(!mechs) { |
| 462 purple_connection_error(js->gc, _("Invalid response from server.")); |
468 purple_connection_error_reason (js->gc, PURPLE_REASON_NETWORK_ERROR, |
| |
469 _("Invalid response from server.")); |
| 463 return; |
470 return; |
| 464 } |
471 } |
| 465 |
472 |
| 466 #ifdef HAVE_CYRUS_SASL |
473 #ifdef HAVE_CYRUS_SASL |
| 467 js->sasl_mechs = g_string_new(""); |
474 js->sasl_mechs = g_string_new(""); |
| 543 /* Clear the pasword if it isn't being saved */ |
550 /* Clear the pasword if it isn't being saved */ |
| 544 if (!purple_account_get_remember_password(js->gc->account)) |
551 if (!purple_account_get_remember_password(js->gc->account)) |
| 545 purple_account_set_password(js->gc->account, NULL); |
552 purple_account_set_password(js->gc->account, NULL); |
| 546 } |
553 } |
| 547 |
554 |
| 548 purple_connection_error(js->gc, msg); |
555 purple_connection_error_reason (js->gc, PURPLE_REASON_OTHER_ERROR, msg); |
| 549 g_free(msg); |
556 g_free(msg); |
| 550 } |
557 } |
| 551 } |
558 } |
| 552 |
559 |
| 553 static void auth_old_cb(JabberStream *js, xmlnode *packet, gpointer data) |
560 static void auth_old_cb(JabberStream *js, xmlnode *packet, gpointer data) |
| 556 xmlnode *query, *x; |
563 xmlnode *query, *x; |
| 557 const char *type = xmlnode_get_attrib(packet, "type"); |
564 const char *type = xmlnode_get_attrib(packet, "type"); |
| 558 const char *pw = purple_connection_get_password(js->gc); |
565 const char *pw = purple_connection_get_password(js->gc); |
| 559 |
566 |
| 560 if(!type) { |
567 if(!type) { |
| 561 purple_connection_error(js->gc, _("Invalid response from server.")); |
568 purple_connection_error_reason (js->gc, PURPLE_REASON_NETWORK_ERROR, |
| |
569 _("Invalid response from server.")); |
| 562 return; |
570 return; |
| 563 } else if(!strcmp(type, "error")) { |
571 } else if(!strcmp(type, "error")) { |
| 564 char *msg = jabber_parse_error(js, packet); |
572 char *msg = jabber_parse_error(js, packet); |
| 565 purple_connection_error(js->gc, msg); |
573 purple_connection_error_reason (js->gc, PURPLE_REASON_AUTHENTICATION_FAILED, |
| |
574 msg); |
| 566 g_free(msg); |
575 g_free(msg); |
| 567 } else if(!strcmp(type, "result")) { |
576 } else if(!strcmp(type, "result")) { |
| 568 query = xmlnode_get_child(packet, "query"); |
577 query = xmlnode_get_child(packet, "query"); |
| 569 if(js->stream_id && xmlnode_get_child(query, "digest")) { |
578 if(js->stream_id && xmlnode_get_child(query, "digest")) { |
| 570 unsigned char hashval[20]; |
579 unsigned char hashval[20]; |
| 604 disallow_plaintext_auth); |
613 disallow_plaintext_auth); |
| 605 return; |
614 return; |
| 606 } |
615 } |
| 607 finish_plaintext_authentication(js); |
616 finish_plaintext_authentication(js); |
| 608 } else { |
617 } else { |
| 609 purple_connection_error(js->gc, |
618 purple_connection_error_reason (js->gc, |
| 610 _("Server does not use any supported authentication method")); |
619 PURPLE_REASON_AUTHENTICATION_IMPOSSIBLE, |
| |
620 _("Server does not use any supported authentication method")); |
| 611 return; |
621 return; |
| 612 } |
622 } |
| 613 } |
623 } |
| 614 } |
624 } |
| 615 |
625 |
| 771 char *dec_in; |
781 char *dec_in; |
| 772 char *enc_out; |
782 char *enc_out; |
| 773 GHashTable *parts; |
783 GHashTable *parts; |
| 774 |
784 |
| 775 if(!enc_in) { |
785 if(!enc_in) { |
| 776 purple_connection_error(js->gc, _("Invalid response from server.")); |
786 purple_connection_error_reason (js->gc, PURPLE_REASON_NETWORK_ERROR, |
| |
787 _("Invalid response from server.")); |
| 777 return; |
788 return; |
| 778 } |
789 } |
| 779 |
790 |
| 780 dec_in = (char *)purple_base64_decode(enc_in, NULL); |
791 dec_in = (char *)purple_base64_decode(enc_in, NULL); |
| 781 purple_debug(PURPLE_DEBUG_MISC, "jabber", "decoded challenge (%d): %s\n", |
792 purple_debug(PURPLE_DEBUG_MISC, "jabber", "decoded challenge (%d): %s\n", |
| 792 !strcmp(rspauth, js->expected_rspauth)) { |
803 !strcmp(rspauth, js->expected_rspauth)) { |
| 793 jabber_send_raw(js, |
804 jabber_send_raw(js, |
| 794 "<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl' />", |
805 "<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl' />", |
| 795 -1); |
806 -1); |
| 796 } else { |
807 } else { |
| 797 purple_connection_error(js->gc, _("Invalid challenge from server")); |
808 purple_connection_error_reason (js->gc, PURPLE_REASON_NETWORK_ERROR, |
| |
809 _("Invalid challenge from server")); |
| 798 } |
810 } |
| 799 g_free(js->expected_rspauth); |
811 g_free(js->expected_rspauth); |
| 800 } else { |
812 } else { |
| 801 /* assemble a response, and send it */ |
813 /* assemble a response, and send it */ |
| 802 /* see RFC 2831 */ |
814 /* see RFC 2831 */ |
| 815 realm = g_hash_table_lookup(parts, "realm"); |
827 realm = g_hash_table_lookup(parts, "realm"); |
| 816 if(!realm) |
828 if(!realm) |
| 817 realm = js->user->domain; |
829 realm = js->user->domain; |
| 818 |
830 |
| 819 if (nonce == NULL || realm == NULL) |
831 if (nonce == NULL || realm == NULL) |
| 820 purple_connection_error(js->gc, _("Invalid challenge from server")); |
832 purple_connection_error_reason (js->gc, PURPLE_REASON_NETWORK_ERROR, |
| |
833 _("Invalid challenge from server")); |
| 821 else { |
834 else { |
| 822 GString *response = g_string_new(""); |
835 GString *response = g_string_new(""); |
| 823 char *a2; |
836 char *a2; |
| 824 char *auth_resp; |
837 char *auth_resp; |
| 825 char *buf; |
838 char *buf; |
| 887 NULL, &c_out, &clen); |
900 NULL, &c_out, &clen); |
| 888 g_free(enc_in); |
901 g_free(enc_in); |
| 889 g_free(dec_in); |
902 g_free(dec_in); |
| 890 if (js->sasl_state != SASL_CONTINUE && js->sasl_state != SASL_OK) { |
903 if (js->sasl_state != SASL_CONTINUE && js->sasl_state != SASL_OK) { |
| 891 purple_debug_error("jabber", "Error is %d : %s\n",js->sasl_state,sasl_errdetail(js->sasl)); |
904 purple_debug_error("jabber", "Error is %d : %s\n",js->sasl_state,sasl_errdetail(js->sasl)); |
| 892 purple_connection_error(js->gc, _("SASL error")); |
905 purple_connection_error_reason (js->gc, PURPLE_REASON_NETWORK_ERROR, |
| |
906 _("SASL error")); |
| 893 return; |
907 return; |
| 894 } else { |
908 } else { |
| 895 response = xmlnode_new("response"); |
909 response = xmlnode_new("response"); |
| 896 xmlnode_set_namespace(response, "urn:ietf:params:xml:ns:xmpp-sasl"); |
910 xmlnode_set_namespace(response, "urn:ietf:params:xml:ns:xmpp-sasl"); |
| 897 if (clen > 0) { |
911 if (clen > 0) { |
| 912 #ifdef HAVE_CYRUS_SASL |
926 #ifdef HAVE_CYRUS_SASL |
| 913 const void *x; |
927 const void *x; |
| 914 #endif |
928 #endif |
| 915 |
929 |
| 916 if(!ns || strcmp(ns, "urn:ietf:params:xml:ns:xmpp-sasl")) { |
930 if(!ns || strcmp(ns, "urn:ietf:params:xml:ns:xmpp-sasl")) { |
| 917 purple_connection_error(js->gc, _("Invalid response from server.")); |
931 purple_connection_error_reason (js->gc, PURPLE_REASON_NETWORK_ERROR, |
| |
932 _("Invalid response from server.")); |
| 918 return; |
933 return; |
| 919 } |
934 } |
| 920 |
935 |
| 921 #ifdef HAVE_CYRUS_SASL |
936 #ifdef HAVE_CYRUS_SASL |
| 922 /* The SASL docs say that if the client hasn't returned OK yet, we |
937 /* The SASL docs say that if the client hasn't returned OK yet, we |
| 937 g_free(enc_in); |
952 g_free(enc_in); |
| 938 g_free(dec_in); |
953 g_free(dec_in); |
| 939 |
954 |
| 940 if (js->sasl_state != SASL_OK) { |
955 if (js->sasl_state != SASL_OK) { |
| 941 /* This should never happen! */ |
956 /* This should never happen! */ |
| 942 purple_connection_error(js->gc, _("Invalid response from server.")); |
957 purple_connection_error_reason (js->gc, PURPLE_REASON_NETWORK_ERROR, |
| |
958 _("Invalid response from server.")); |
| 943 } |
959 } |
| 944 } |
960 } |
| 945 /* If we've negotiated a security layer, we need to enable it */ |
961 /* If we've negotiated a security layer, we need to enable it */ |
| 946 sasl_getprop(js->sasl, SASL_SSF, &x); |
962 sasl_getprop(js->sasl, SASL_SSF, &x); |
| 947 if (*(int *)x > 0) { |
963 if (*(int *)x > 0) { |
| 956 void jabber_auth_handle_failure(JabberStream *js, xmlnode *packet) |
972 void jabber_auth_handle_failure(JabberStream *js, xmlnode *packet) |
| 957 { |
973 { |
| 958 char *msg = jabber_parse_error(js, packet); |
974 char *msg = jabber_parse_error(js, packet); |
| 959 |
975 |
| 960 if(!msg) { |
976 if(!msg) { |
| 961 purple_connection_error(js->gc, _("Invalid response from server.")); |
977 purple_connection_error_reason (js->gc, PURPLE_REASON_NETWORK_ERROR, |
| |
978 _("Invalid response from server.")); |
| 962 } else { |
979 } else { |
| 963 purple_connection_error(js->gc, msg); |
980 purple_connection_error_reason (js->gc, PURPLE_REASON_AUTHENTICATION_FAILED, |
| |
981 msg); |
| 964 g_free(msg); |
982 g_free(msg); |
| 965 } |
983 } |
| 966 } |
984 } |