summaryrefslogtreecommitdiff
path: root/libpurple/protocols
diff options
context:
space:
mode:
authorGary Kramlich <grim@reaperworld.com>2023-02-28 03:20:33 -0600
committerGary Kramlich <grim@reaperworld.com>2023-02-28 03:20:33 -0600
commit349731e9a959acedcd01ca0c03374436610071b6 (patch)
tree7e4fe6736ceb2dd7faf92ef65a875184e0d0a9cb /libpurple/protocols
parenta36beced54501cced2f7403655800d55aa1df0c9 (diff)
downloadpidgin-349731e9a959acedcd01ca0c03374436610071b6.tar.gz
Remove Cyrus SASL from XMPP
This will eventually be replaced by Hasl, but XMPP has it's own built-in SASL mechanisms as well as Cyrus, so removing Cyrus first is just the first step. Testing Done: Connected an XMPP account, sent direct messages from both sides, and joined a muc and sent messages from both sides as well. Also ran the unit tests. Reviewed at https://reviews.imfreedom.org/r/2295/
Diffstat (limited to 'libpurple/protocols')
-rw-r--r--libpurple/protocols/jabber/auth.c7
-rw-r--r--libpurple/protocols/jabber/auth.h1
-rw-r--r--libpurple/protocols/jabber/auth_cyrus.c672
-rw-r--r--libpurple/protocols/jabber/jabber.c99
-rw-r--r--libpurple/protocols/jabber/jabber.h14
-rw-r--r--libpurple/protocols/jabber/meson.build6
6 files changed, 1 insertions, 798 deletions
diff --git a/libpurple/protocols/jabber/auth.c b/libpurple/protocols/jabber/auth.c
index 2ad5ecb7e7..d22e282862 100644
--- a/libpurple/protocols/jabber/auth.c
+++ b/libpurple/protocols/jabber/auth.c
@@ -197,12 +197,6 @@ jabber_auth_start(JabberStream *js, PurpleXmlNode *packet)
for (l = auth_mechs; l; l = l->next) {
JabberSaslMech *possible = l->data;
- /* Is this the Cyrus SASL mechanism? */
- if (purple_strequal(possible->name, "*")) {
- js->auth_mech = possible;
- break;
- }
-
/* Can we find this mechanism in the server's list? */
if (g_slist_find_custom(mechanisms, possible->name, (GCompareFunc)strcmp)) {
js->auth_mech = possible;
@@ -551,7 +545,6 @@ void jabber_auth_init(void)
jabber_auth_add_mech(jabber_auth_get_plain_mech());
jabber_auth_add_mech(jabber_auth_get_digest_md5_mech());
- jabber_auth_add_mech(jabber_auth_get_cyrus_mech());
#ifdef HAVE_WEBEX_TOKEN
jabber_auth_add_mech(jabber_auth_get_webex_token_mech());
#endif
diff --git a/libpurple/protocols/jabber/auth.h b/libpurple/protocols/jabber/auth.h
index 34886fb32e..764afa4fe3 100644
--- a/libpurple/protocols/jabber/auth.h
+++ b/libpurple/protocols/jabber/auth.h
@@ -56,7 +56,6 @@ void jabber_auth_handle_failure(JabberStream *js, PurpleXmlNode *packet);
JabberSaslMech *jabber_auth_get_plain_mech(void);
JabberSaslMech *jabber_auth_get_digest_md5_mech(void);
JabberSaslMech **jabber_auth_get_scram_mechs(gint *count);
-JabberSaslMech *jabber_auth_get_cyrus_mech(void);
JabberSaslMech *jabber_auth_get_webex_token_mech(void);
void jabber_auth_init(void);
diff --git a/libpurple/protocols/jabber/auth_cyrus.c b/libpurple/protocols/jabber/auth_cyrus.c
deleted file mode 100644
index bc68a6eb66..0000000000
--- a/libpurple/protocols/jabber/auth_cyrus.c
+++ /dev/null
@@ -1,672 +0,0 @@
-/*
- * purple - Jabber Protocol Plugin
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- *
- */
-
-#include <config.h>
-
-#include <glib/gi18n-lib.h>
-
-#include <purple.h>
-
-#include "auth.h"
-#include "jabber.h"
-
-static JabberSaslState jabber_auth_start_cyrus(JabberStream *js, PurpleXmlNode **reply,
- char **error);
-static void jabber_sasl_build_callbacks(JabberStream *);
-
-static void disallow_plaintext_auth(PurpleAccount *account)
-{
- purple_connection_error(purple_account_get_connection(account),
- PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
- _("Server may require plaintext authentication over an unencrypted stream"));
-}
-
-static void start_cyrus_wrapper(JabberStream *js)
-{
- char *error = NULL;
- PurpleXmlNode *response = NULL;
- JabberSaslState state = jabber_auth_start_cyrus(js, &response, &error);
-
- if (state == JABBER_SASL_STATE_FAIL) {
- purple_connection_error(js->gc,
- PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
- error);
- g_free(error);
- } else if (response) {
- jabber_send(js, response);
- purple_xmlnode_free(response);
- }
-}
-
-
-/* Callbacks for Cyrus SASL */
-
-static int
-jabber_sasl_cb_realm(void *ctx, int id, G_GNUC_UNUSED const char **avail,
- const char **result)
-{
- JabberStream *js = ctx;
-
- if (id != SASL_CB_GETREALM || !result) return SASL_BADPARAM;
-
- *result = js->user->domain;
-
- return SASL_OK;
-}
-
-static int jabber_sasl_cb_simple(void *ctx, int id, const char **res, unsigned *len)
-{
- JabberStream *js = ctx;
-
- switch(id) {
- case SASL_CB_AUTHNAME:
- *res = js->user->node;
- break;
- case SASL_CB_USER:
- *res = "";
- break;
- default:
- return SASL_BADPARAM;
- }
- if (len) *len = strlen((char *)*res);
- return SASL_OK;
-}
-
-static int jabber_sasl_cb_secret(sasl_conn_t *conn, void *ctx, int id, sasl_secret_t **secret)
-{
- JabberStream *js = ctx;
- size_t len;
-
- if (!conn || !secret || id != SASL_CB_PASS)
- return SASL_BADPARAM;
-
- len = strlen(js->sasl_password);
- /* Not an off-by-one because sasl_secret_t defines char data[1] */
- /* TODO: This can probably be moved to glib's allocator */
- js->sasl_secret = malloc(sizeof(sasl_secret_t) + len);
- if (!js->sasl_secret)
- return SASL_NOMEM;
-
- js->sasl_secret->len = len;
- strcpy((char*)js->sasl_secret->data, js->sasl_password);
-
- *secret = js->sasl_secret;
- return SASL_OK;
-}
-
-static void allow_cyrus_plaintext_auth(PurpleAccount *account)
-{
- PurpleConnection *gc;
- JabberStream *js;
-
- gc = purple_account_get_connection(account);
- js = purple_connection_get_protocol_data(gc);
-
- purple_account_set_bool(account, "auth_plain_in_clear", TRUE);
-
- start_cyrus_wrapper(js);
-}
-
-static void auth_pass_cb(PurpleConnection *gc, PurpleRequestFields *fields)
-{
- PurpleAccount *account;
- JabberStream *js;
- const char *entry;
- gboolean remember;
-
- /* TODO: the password prompt dialog doesn't get disposed if the account disconnects */
- PURPLE_ASSERT_CONNECTION_IS_VALID(gc);
-
- account = purple_connection_get_account(gc);
- js = purple_connection_get_protocol_data(gc);
-
- entry = purple_request_fields_get_string(fields, "password");
- remember = purple_request_fields_get_bool(fields, "remember");
-
- if (!entry || !*entry)
- {
- purple_notify_error(account, NULL,
- _("Password is required to sign on."), NULL,
- purple_request_cpar_from_connection(gc));
- return;
- }
-
- if(remember) {
- PurpleCredentialManager *manager = NULL;
-
- purple_account_set_remember_password(account, TRUE);
-
- manager = purple_credential_manager_get_default();
- purple_credential_manager_write_password_async(manager, account, entry,
- NULL, NULL, NULL);
- }
-
- js->sasl_password = g_strdup(entry);
-
- /* Rebuild our callbacks as we now have a password to offer */
- jabber_sasl_build_callbacks(js);
-
- /* Restart our negotiation */
- start_cyrus_wrapper(js);
-}
-
-static void
-auth_no_pass_cb(PurpleConnection *gc,
- G_GNUC_UNUSED PurpleRequestFields *fields)
-{
- PurpleAccount *account;
-
- /* TODO: the password prompt dialog doesn't get disposed if the account disconnects */
- PURPLE_ASSERT_CONNECTION_IS_VALID(gc);
-
- account = purple_connection_get_account(gc);
-
- /* Disable the account as the user has cancelled connecting */
- purple_account_set_enabled(account, FALSE);
-}
-
-static void
-auth_pass_read_cb(GObject *source, GAsyncResult *result, gpointer data) {
- JabberStream *js = data;
- PurpleCredentialManager *manager = PURPLE_CREDENTIAL_MANAGER(source);
- GError *error = NULL;
- char *password = NULL;
-
- password = purple_credential_manager_read_password_finish(manager, result,
- &error);
- if(password == NULL || error != NULL) {
- PurpleAccount *account = NULL;
- const char *message = "unknown error";
-
- if(error != NULL) {
- message = error->message;
- }
-
- purple_debug_warning("jabber", "failed to read password from the "
- "credential manager : %s", message);
-
- g_clear_error(&error);
-
- account = purple_connection_get_account(js->gc);
- purple_account_request_password(account, G_CALLBACK(auth_pass_cb),
- G_CALLBACK(auth_no_pass_cb),
- js->gc);
-
- return;
- }
-
- js->sasl_password = password;
-
- /* Rebuild our callbacks as we now have a password to offer */
- jabber_sasl_build_callbacks(js);
-
- /* Restart our negotiation */
- start_cyrus_wrapper(js);
-}
-
-static gboolean remove_current_mech(JabberStream *js) {
- char *pos;
- if ((pos = strstr(js->sasl_mechs->str, js->current_mech))) {
- size_t len = strlen(js->current_mech);
- /* Clean up space that separated this Mech from the one before or after it */
- if (pos > js->sasl_mechs->str && *(pos - 1) == ' ') {
- /* Handle removing space before when current_mech isn't the first mech in the list */
- pos--;
- len++;
- } else if (strlen(pos) > len && *(pos + len) == ' ') {
- /* Handle removing space after */
- len++;
- }
- g_string_erase(js->sasl_mechs, pos - js->sasl_mechs->str, len);
- return TRUE;
- }
- return FALSE;
-}
-
-static JabberSaslState
-jabber_auth_start_cyrus(JabberStream *js, PurpleXmlNode **reply, char **error)
-{
- PurpleAccount *account;
- const char *clientout = NULL;
- char *enc_out;
- unsigned coutlen = 0;
- sasl_security_properties_t secprops;
- gboolean again;
- gboolean plaintext = TRUE;
-
- /* Set up security properties and options */
- secprops.min_ssf = 0;
- secprops.security_flags = SASL_SEC_NOANONYMOUS;
-
- account = purple_connection_get_account(js->gc);
-
- if (!jabber_stream_is_ssl(js)) {
- secprops.max_ssf = -1;
- secprops.maxbufsize = 4096;
- plaintext = purple_account_get_bool(account, "auth_plain_in_clear", FALSE);
- if (!plaintext)
- secprops.security_flags |= SASL_SEC_NOPLAINTEXT;
- } else {
- secprops.max_ssf = 0;
- secprops.maxbufsize = 0;
- plaintext = TRUE;
- }
- secprops.property_names = 0;
- secprops.property_values = 0;
-
- do {
- again = FALSE;
-
- js->sasl_state = sasl_client_new("xmpp", js->serverFQDN, NULL, NULL, js->sasl_cb, 0, &js->sasl);
- if (js->sasl_state==SASL_OK) {
- sasl_setprop(js->sasl, SASL_SEC_PROPS, &secprops);
- purple_debug_info("sasl", "Mechs found: %s\n", js->sasl_mechs->str);
- js->sasl_state = sasl_client_start(js->sasl, js->sasl_mechs->str, NULL, &clientout, &coutlen, &js->current_mech);
- }
- switch (js->sasl_state) {
- /* Success */
- case SASL_OK:
- case SASL_CONTINUE:
- break;
- case SASL_NOMECH:
- /* No mechanisms have offered to help */
-
- /* Firstly, if we don't have a password try
- * to get one
- */
-
- if (!js->sasl_password) {
- PurpleCredentialManager *manager = NULL;
-
- manager = purple_credential_manager_get_default();
- purple_credential_manager_read_password_async(manager,
- account,
- NULL,
- auth_pass_read_cb,
- js);
- return JABBER_SASL_STATE_CONTINUE;
-
- /* If we've got a password, but aren't sending
- * it in plaintext, see if we can turn on
- * plaintext auth
- */
- /* XXX Should we just check for PLAIN/LOGIN being offered mechanisms? */
- } else if (!plaintext) {
- PurpleContactInfo *info = PURPLE_CONTACT_INFO(account);
- char *msg = g_strdup_printf(_("%s may require plaintext authentication over an unencrypted connection. Allow this and continue authentication?"),
- purple_contact_info_get_username(info));
- purple_request_yes_no(js->gc, _("Plaintext Authentication"),
- _("Plaintext Authentication"),
- msg,
- 1, purple_request_cpar_from_account(account), account,
- allow_cyrus_plaintext_auth,
- disallow_plaintext_auth);
- g_free(msg);
- return JABBER_SASL_STATE_CONTINUE;
-
- } else
- js->auth_fail_count++;
-
- if (js->auth_fail_count == 1 &&
- purple_strequal(js->sasl_mechs->str, "GSSAPI")) {
- /* If we tried GSSAPI first, it failed, and it was the only method we had to try, try jabber:iq:auth
- * for compatibility with iChat 10.5 Server and other jabberd based servers.
- *
- * iChat Server 10.5 and certain other corporate servers offer SASL GSSAPI by default, which is often
- * not configured on the client side, and expects a fallback to jabber:iq:auth when it (predictably) fails.
- *
- * Note: xep-0078 points out that using jabber:iq:auth after a sasl failure is wrong. However,
- * I believe this refers to actual authentication failure, not a simple lack of concordant mechanisms.
- * Doing otherwise means that simply compiling with SASL support renders the client unable to connect to servers
- * which would connect without issue otherwise. -evands
- */
- js->auth_mech = NULL;
- jabber_auth_start_old(js);
- return JABBER_SASL_STATE_CONTINUE;
- }
-
- break;
-
- /* Fatal errors. Give up and go home */
- case SASL_BADPARAM:
- case SASL_NOMEM:
- *error = g_strdup(_("SASL authentication failed"));
- break;
-
- /* For everything else, fail the mechanism and try again */
- default:
- purple_debug_info("sasl", "sasl_state is %d, failing the mech and trying again\n", js->sasl_state);
-
- js->auth_fail_count++;
-
- /*
- * DAA: is this right?
- * The manpage says that "mech" will contain the chosen mechanism on success.
- * Presumably, if we get here that isn't the case and we shouldn't try again?
- * I suspect that this never happens.
- */
- /*
- * SXW: Yes, this is right. What this handles is the situation where a
- * mechanism, say GSSAPI, is tried. If that mechanism fails, it may be
- * due to mechanism specific issues, so we want to try one of the other
- * supported mechanisms. This code handles that case
- */
- if (js->current_mech && *js->current_mech) {
- remove_current_mech(js);
- /* Should we only try again if we've removed the mech? */
- again = TRUE;
- }
-
- sasl_dispose(&js->sasl);
- }
- } while (again);
-
- if (js->sasl_state == SASL_CONTINUE || js->sasl_state == SASL_OK) {
- PurpleXmlNode *auth = purple_xmlnode_new("auth");
- purple_xmlnode_set_namespace(auth, NS_XMPP_SASL);
- purple_xmlnode_set_attrib(auth, "mechanism", js->current_mech);
-
- if (clientout) {
- if (coutlen == 0) {
- purple_xmlnode_insert_data(auth, "=", -1);
- } else {
- enc_out = g_base64_encode((unsigned char*)clientout, coutlen);
- purple_xmlnode_insert_data(auth, enc_out, -1);
- g_free(enc_out);
- }
- }
-
- *reply = auth;
- return JABBER_SASL_STATE_CONTINUE;
- } else {
- return JABBER_SASL_STATE_FAIL;
- }
-}
-
-static int
-jabber_sasl_cb_log(G_GNUC_UNUSED void *context, int level, const char *message)
-{
- if(level <= SASL_LOG_TRACE)
- purple_debug_info("sasl", "%s\n", message);
-
- return SASL_OK;
-}
-
-static void
-jabber_sasl_build_callbacks(JabberStream *js)
-{
- int id;
-
- /* Set up our callbacks structure */
- if (js->sasl_cb == NULL)
- js->sasl_cb = g_new0(sasl_callback_t,6);
-
- id = 0;
- js->sasl_cb[id].id = SASL_CB_GETREALM;
- js->sasl_cb[id].proc = (void *)jabber_sasl_cb_realm;
- js->sasl_cb[id].context = (void *)js;
- id++;
-
- js->sasl_cb[id].id = SASL_CB_AUTHNAME;
- js->sasl_cb[id].proc = (void *)jabber_sasl_cb_simple;
- js->sasl_cb[id].context = (void *)js;
- id++;
-
- js->sasl_cb[id].id = SASL_CB_USER;
- js->sasl_cb[id].proc = (void *)jabber_sasl_cb_simple;
- js->sasl_cb[id].context = (void *)js;
- id++;
-
- if (js->sasl_password != NULL) {
- js->sasl_cb[id].id = SASL_CB_PASS;
- js->sasl_cb[id].proc = (void *)jabber_sasl_cb_secret;
- js->sasl_cb[id].context = (void *)js;
- id++;
- }
-
- js->sasl_cb[id].id = SASL_CB_LOG;
- js->sasl_cb[id].proc = (void *)jabber_sasl_cb_log;
- js->sasl_cb[id].context = (void*)js;
- id++;
-
- js->sasl_cb[id].id = SASL_CB_LIST_END;
-}
-
-static JabberSaslState
-jabber_cyrus_start(JabberStream *js, PurpleXmlNode *mechanisms,
- PurpleXmlNode **reply, char **error)
-{
- PurpleXmlNode *mechnode, *hostname;
- JabberSaslState ret;
-
- js->sasl_mechs = g_string_new("");
- js->sasl_password = g_strdup(purple_connection_get_password(js->gc));
- /* XEP-0233 says we should grab the hostname for Kerberos v5, but there
- * is no claim about other SASL mechanisms. Fortunately, most don't
- * care what we use, so just use the domainpart. */
- hostname = purple_xmlnode_get_child_with_namespace(
- mechanisms, "hostname", NS_XMPP_SERVER_REGISTRATION);
- if (hostname) {
- js->serverFQDN = purple_xmlnode_get_data(hostname);
- }
- if (js->serverFQDN == NULL) {
- js->serverFQDN = g_strdup(js->user->domain);
- }
-
- for(mechnode = purple_xmlnode_get_child(mechanisms, "mechanism"); mechnode;
- mechnode = purple_xmlnode_get_next_twin(mechnode))
- {
- char *mech_name = purple_xmlnode_get_data(mechnode);
-
- /* Ignore blank mechanisms and EXTERNAL. External isn't
- * supported, and Cyrus SASL's mechanism returns
- * SASL_NOMECH when the caller (us) doesn't configure it.
- * Except SASL_NOMECH is supposed to mean "no concordant
- * mechanisms"... Easiest just to blacklist it (for now).
- */
- if (!mech_name || !*mech_name ||
- purple_strequal(mech_name, "EXTERNAL")) {
- g_free(mech_name);
- continue;
- }
-
- g_string_append(js->sasl_mechs, mech_name);
- g_string_append_c(js->sasl_mechs, ' ');
- g_free(mech_name);
- }
-
- /* Strip off the trailing ' ' */
- if (js->sasl_mechs->len > 1)
- g_string_truncate(js->sasl_mechs, js->sasl_mechs->len - 1);
-
- jabber_sasl_build_callbacks(js);
- ret = jabber_auth_start_cyrus(js, reply, error);
-
- /*
- * Triggered if no overlap between server and client
- * supported mechanisms.
- */
- if (ret == JABBER_SASL_STATE_FAIL && *error == NULL)
- *error = g_strdup(_("Server does not use any supported authentication method"));
-
- return ret;
-}
-
-static JabberSaslState
-jabber_cyrus_handle_challenge(JabberStream *js, PurpleXmlNode *packet,
- PurpleXmlNode **reply, char **error)
-{
- char *enc_in = purple_xmlnode_get_data(packet);
- unsigned char *dec_in;
- char *enc_out;
- const char *c_out;
- unsigned int clen;
- gsize declen;
-
- dec_in = g_base64_decode(enc_in, &declen);
-
- js->sasl_state = sasl_client_step(js->sasl, (char*)dec_in, declen,
- NULL, &c_out, &clen);
- g_free(enc_in);
- g_free(dec_in);
- if (js->sasl_state != SASL_CONTINUE && js->sasl_state != SASL_OK) {
- gchar *tmp = g_strdup_printf(_("SASL error: %s"),
- sasl_errdetail(js->sasl));
- purple_debug_error("jabber", "Error is %d : %s\n",
- js->sasl_state, sasl_errdetail(js->sasl));
- *error = tmp;
- return JABBER_SASL_STATE_FAIL;
- } else {
- PurpleXmlNode *response = purple_xmlnode_new("response");
- purple_xmlnode_set_namespace(response, NS_XMPP_SASL);
- if (clen > 0) {
- /* Cyrus SASL 2.1.22 appears to contain code to add the charset
- * to the response for DIGEST-MD5 but there is no possibility
- * it will be executed.
- *
- * My reading of the digestmd5 plugin indicates the username and
- * realm are always encoded in UTF-8 (they seem to be the values
- * we pass in), so we need to ensure charset=utf-8 is set.
- */
- if (!purple_strequal(js->current_mech, "DIGEST-MD5") ||
- strstr(c_out, ",charset="))
- /* If we're not using DIGEST-MD5 or Cyrus SASL is fixed */
- enc_out = g_base64_encode((unsigned char*)c_out, clen);
- else {
- char *tmp = g_strdup_printf("%s,charset=utf-8", c_out);
- enc_out = g_base64_encode((unsigned char*)tmp, clen + 14);
- g_free(tmp);
- }
-
- purple_xmlnode_insert_data(response, enc_out, -1);
- g_free(enc_out);
- }
-
- *reply = response;
- return JABBER_SASL_STATE_CONTINUE;
- }
-}
-
-static JabberSaslState
-jabber_cyrus_handle_success(JabberStream *js, PurpleXmlNode *packet,
- char **error)
-{
- const void *x;
-
- /* The SASL docs say that if the client hasn't returned OK yet, we
- * should try one more round against it
- */
- if (js->sasl_state != SASL_OK) {
- char *enc_in = purple_xmlnode_get_data(packet);
- unsigned char *dec_in = NULL;
- const char *c_out;
- unsigned int clen;
- gsize declen = 0;
-
- if(enc_in != NULL)
- dec_in = g_base64_decode(enc_in, &declen);
-
- js->sasl_state = sasl_client_step(js->sasl, (char*)dec_in, declen, NULL, &c_out, &clen);
-
- g_free(enc_in);
- g_free(dec_in);
-
- if (js->sasl_state != SASL_OK) {
- /* This happens when the server sends back jibberish
- * in the "additional data with success" case.
- * Seen with Wildfire 3.0.1.
- */
- *error = g_strdup(_("Invalid response from server"));
- return JABBER_SASL_STATE_FAIL;
- }
- }
-
- /* If we've negotiated a security layer, we need to enable it */
- if (js->sasl) {
- sasl_getprop(js->sasl, SASL_SSF, &x);
- if (*(int *)x > 0) {
- sasl_getprop(js->sasl, SASL_MAXOUTBUF, &x);
- js->sasl_maxbuf = *(int *)x;
- }
- }
-
- return JABBER_SASL_STATE_OK;
-}
-
-static JabberSaslState
-jabber_cyrus_handle_failure(JabberStream *js,
- G_GNUC_UNUSED PurpleXmlNode *packet,
- PurpleXmlNode **reply, char **error)
-{
- if (js->auth_fail_count++ < 5) {
- if (js->current_mech && *js->current_mech) {
- remove_current_mech(js);
- }
-
- /* Should we only try again if we've actually removed a mech? */
- if (*js->sasl_mechs->str) {
- /* If we have remaining mechs to try, do so */
- sasl_dispose(&js->sasl);
-
- return jabber_auth_start_cyrus(js, reply, error);
-
- } else if ((js->auth_fail_count == 1) &&
- purple_strequal(js->current_mech, "GSSAPI")) {
- /* If we tried GSSAPI first, it failed, and it was the only method we had to try, try jabber:iq:auth
- * for compatibility with iChat 10.5 Server and other jabberd based servers.
- *
- * iChat Server 10.5 and certain other corporate servers offer SASL GSSAPI by default, which is often
- * not configured on the client side, and expects a fallback to jabber:iq:auth when it (predictably) fails.
- *
- * Note: xep-0078 points out that using jabber:iq:auth after a sasl failure is wrong. However,
- * I believe this refers to actual authentication failure, not a simple lack of concordant mechanisms.
- * Doing otherwise means that simply compiling with SASL support renders the client unable to connect to servers
- * which would connect without issue otherwise. -evands
- */
- sasl_dispose(&js->sasl);
- js->sasl = NULL;
- js->auth_mech = NULL;
- jabber_auth_start_old(js);
- return JABBER_SASL_STATE_CONTINUE;
- }
- }
-
- /* Nothing to send */
- return JABBER_SASL_STATE_FAIL;
-}
-
-static JabberSaslMech cyrus_mech = {
- 100, /* priority */
- "*", /* name; Cyrus provides a bunch of mechanisms, so use an invalid
- * mechanism name (per rfc4422 3.1). */
- jabber_cyrus_start,
- jabber_cyrus_handle_challenge,
- jabber_cyrus_handle_success,
- jabber_cyrus_handle_failure,
- NULL,
-};
-
-JabberSaslMech *jabber_auth_get_cyrus_mech(void)
-{
- return &cyrus_mech;
-}
diff --git a/libpurple/protocols/jabber/jabber.c b/libpurple/protocols/jabber/jabber.c
index 63979a1347..29e9227bfc 100644
--- a/libpurple/protocols/jabber/jabber.c
+++ b/libpurple/protocols/jabber/jabber.c
@@ -465,47 +465,6 @@ jabber_send_raw(G_GNUC_UNUSED PurpleProtocolServer *protocol_server,
if (len == -1)
len = strlen(data);
- /* If we've got a security layer, we need to encode the data,
- * splitting it on the maximum buffer length negotiated */
- if (js->sasl_maxbuf>0) {
- int pos = 0;
-
- g_return_if_fail(js->input != NULL);
-
- while (pos < len) {
- int towrite;
- const char *out;
- unsigned olen;
- int rc;
-
- towrite = MIN((len - pos), js->sasl_maxbuf);
-
- rc = sasl_encode(js->sasl, &data[pos], towrite,
- &out, &olen);
- if (rc != SASL_OK) {
- gchar *error =
- g_strdup_printf(_("SASL error: %s"),
- sasl_errdetail(js->sasl));
- purple_debug_error("jabber",
- "sasl_encode error %d: %s\n", rc,
- sasl_errdetail(js->sasl));
- purple_connection_error(gc,
- PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- error);
- g_free(error);
- return;
- }
- pos += towrite;
-
- /* do_jabber_send_raw returns FALSE when it throws a
- * connection error.
- */
- if (!do_jabber_send_raw(js, out, olen))
- break;
- }
- return;
- }
-
if (js->bosh)
jabber_bosh_connection_send(js->bosh, data);
else
@@ -626,30 +585,6 @@ jabber_recv_cb(GObject *stream, gpointer data)
}
purple_connection_update_last_received(gc);
- if (js->sasl_maxbuf > 0) {
- const char *out;
- unsigned int olen;
- int rc;
-
- rc = sasl_decode(js->sasl, buf, len, &out, &olen);
- if (rc != SASL_OK) {
- gchar *error =
- g_strdup_printf(_("SASL error: %s"),
- sasl_errdetail(js->sasl));
- purple_debug_error("jabber",
- "sasl_decode_error %d: %s\n", rc,
- sasl_errdetail(js->sasl));
- purple_connection_error(gc,
- PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- error);
- } else if (olen > 0) {
- purple_debug_info("jabber", "RecvSASL (%u): %s\n", olen, out);
- jabber_parser_process(js, out, olen);
- if (js->reinit)
- jabber_stream_init(js);
- }
- return G_SOURCE_CONTINUE;
- }
buf[len] = '\0';
purple_debug_misc("jabber", "Recv (%" G_GSSIZE_FORMAT "): %s", len,
buf);
@@ -1117,14 +1052,6 @@ jabber_close(G_GNUC_UNUSED PurpleProtocol *protocol, PurpleConnection *gc) {
if (js->auth_mech && js->auth_mech->dispose)
js->auth_mech->dispose(js);
- if(js->sasl)
- sasl_dispose(&js->sasl);
- if(js->sasl_mechs)
- g_string_free(js->sasl_mechs, TRUE);
- g_free(js->sasl_cb);
- /* Note: _not_ g_free. See auth_cyrus.c:jabber_sasl_cb_secret */
- free(js->sasl_secret);
- g_free(js->sasl_password);
g_free(js->serverFQDN);
g_list_free_full(js->commands, (GDestroyNotify)jabber_adhoc_commands_free);
g_free(js->server_name);
@@ -3243,32 +3170,6 @@ jabber_do_init(void)
const gchar *type = "pc"; /* default client type, if unknown or
unspecified */
const gchar *ui_name = NULL;
- /* We really really only want to do this once per process */
- static gboolean sasl_initialized = FALSE;
-#ifdef _WIN32
- UINT old_error_mode;
- gchar *sasldir;
-#endif
- int ret;
-
- /* XXX - If any other plugin wants SASL this won't be good ... */
- if (!sasl_initialized) {
- sasl_initialized = TRUE;
-#ifdef _WIN32
- sasldir = g_strdup(wpurple_lib_dir("sasl2"));
- sasl_set_path(SASL_PATH_TYPE_PLUGIN, sasldir);
- g_free(sasldir);
- /* Suppress error popups for failing to load sasl plugins */
- old_error_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
-#endif
- if ((ret = sasl_client_init(NULL)) != SASL_OK) {
- purple_debug_error("xmpp", "Error (%d) initializing SASL.\n", ret);
- }
-#ifdef _WIN32
- /* Restore the original error mode */
- SetErrorMode(old_error_mode);
-#endif
- }
jabber_cmds = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, cmds_free_func);
diff --git a/libpurple/protocols/jabber/jabber.h b/libpurple/protocols/jabber/jabber.h
index 2c85ff7dc6..5cd3f4ebae 100644
--- a/libpurple/protocols/jabber/jabber.h
+++ b/libpurple/protocols/jabber/jabber.h
@@ -69,8 +69,6 @@ typedef struct _JabberStream JabberStream;
#include "buddy.h"
#include "bosh.h"
-#include <sasl/sasl.h>
-
#define CAPS0115_NODE "https://pidgin.im/"
#define JABBER_TYPE_PROTOCOL (jabber_protocol_get_type())
@@ -191,18 +189,6 @@ struct _JabberStream
char *serverFQDN;
- sasl_conn_t *sasl;
- sasl_callback_t *sasl_cb;
- sasl_secret_t *sasl_secret;
- const char *current_mech;
- int auth_fail_count;
-
- int sasl_state;
- int sasl_maxbuf;
- GString *sasl_mechs;
-
- gchar *sasl_password;
-
gboolean vcard_fetched;
/* Entity Capabilities hash */
diff --git a/libpurple/protocols/jabber/meson.build b/libpurple/protocols/jabber/meson.build
index 08b3c78dfc..f115ee9738 100644
--- a/libpurple/protocols/jabber/meson.build
+++ b/libpurple/protocols/jabber/meson.build
@@ -78,10 +78,6 @@ JABBER_SOURCES = [
'xmpp.h'
]
-if sasl.found()
- JABBER_SOURCES += ['auth_cyrus.c']
-endif
-
if IS_WIN32
jabber_link_args = ['-Wl,--export-all-symbols']
else
@@ -100,7 +96,7 @@ if DYNAMIC_JABBER
jabber_prpl = shared_library('jabber', JABBER_SOURCES,
c_args : ['-DG_LOG_USE_STRUCTURED', '-DG_LOG_DOMAIN="Purple-XMPP"'],
link_args : jabber_link_args,
- dependencies : [gstreamer, idn, libxml, sasl, libpurple_dep, libsoup, glib, gio, math, ws2_32],
+ dependencies : [gstreamer, idn, libxml, libpurple_dep, libsoup, glib, gio, math, ws2_32],
install : true,
install_dir : PURPLE_PLUGINDIR)