diff --git a/libpurple/protocols/jabber/auth.h b/libpurple/protocols/jabber/auth.h
--- a/libpurple/protocols/jabber/auth.h
+++ b/libpurple/protocols/jabber/auth.h
@@ -56,7 +56,6 @@
 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);
# HG changeset patch
# Node ID 2df95c047e80
# Parent  13adc8e7563d
diff --git a/libpurple/protocols/jabber/auth.c b/libpurple/protocols/jabber/auth.c
--- a/libpurple/protocols/jabber/auth.c
+++ b/libpurple/protocols/jabber/auth.c
@@ -197,12 +197,6 @@
 	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 @@
 
 	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_cyrus.c b/libpurple/protocols/jabber/auth_cyrus.c
deleted file mode 100644
--- 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.h b/libpurple/protocols/jabber/jabber.h
--- a/libpurple/protocols/jabber/jabber.h
+++ b/libpurple/protocols/jabber/jabber.h
@@ -69,8 +69,6 @@
 #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 @@
 
 	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/jabber.c b/libpurple/protocols/jabber/jabber.c
--- a/libpurple/protocols/jabber/jabber.c
+++ b/libpurple/protocols/jabber/jabber.c
@@ -465,47 +465,6 @@
 	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 @@
 		}
 
 		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 @@
 
 	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 @@
 	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/meson.build b/libpurple/protocols/jabber/meson.build
--- a/libpurple/protocols/jabber/meson.build
+++ b/libpurple/protocols/jabber/meson.build
@@ -78,10 +78,6 @@
 	'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 @@
 	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)
 
