diff --git a/src/camel/camel-ews-provider.c b/src/camel/camel-ews-provider.c
index 719b618..47085a8 100644
--- a/src/camel/camel-ews-provider.c
+++ b/src/camel/camel-ews-provider.c
@@ -108,14 +108,25 @@ CamelServiceAuthType camel_ews_basic_authtype = {
 	TRUE
 };
 
+CamelServiceAuthType camel_ews_gssapi_authtype = {
+	N_("Kerberos"),
+
+	N_("This option will connect to the Exchange server using a "
+	   "Kerberos/GSSAPI authentication."),
+
+	"GSSAPI",
+	FALSE
+};
+
 void
 camel_provider_module_init (void)
 {
 	ews_provider.url_hash = ews_url_hash;
 	ews_provider.url_equal = ews_url_equal;
-	ews_provider.authtypes = g_list_prepend (
-		g_list_prepend (NULL, &camel_ews_basic_authtype),
-		&camel_ews_ntlm_authtype);
+	ews_provider.authtypes = g_list_append (g_list_append (g_list_append (NULL,
+		&camel_ews_ntlm_authtype),
+		&camel_ews_basic_authtype),
+		&camel_ews_gssapi_authtype);
 	ews_provider.translation_domain = GETTEXT_PACKAGE;
 
 	ews_provider.object_types[CAMEL_PROVIDER_STORE] =  CAMEL_TYPE_EWS_STORE;
diff --git a/src/server/e-ews-connection.c b/src/server/e-ews-connection.c
index ca635d3..c0efb09 100644
--- a/src/server/e-ews-connection.c
+++ b/src/server/e-ews-connection.c
@@ -173,9 +173,10 @@ ews_auth_mech_to_use_ntlm (GBinding *binding,
 	const gchar *auth_mechanism;
 	gboolean use_ntlm;
 
-	/* Use NTLM unless the auth mechanism is "PLAIN". */
+	/* Use NTLM unless the auth mechanism is "PLAIN" or "GSSAPI". */
 	auth_mechanism = g_value_get_string (source_value);
-	use_ntlm = (g_strcmp0 (auth_mechanism, "PLAIN") != 0);
+	use_ntlm = g_strcmp0 (auth_mechanism, "PLAIN") != 0 &&
+		   g_strcmp0 (auth_mechanism, "GSSAPI") != 0;
 	g_value_set_boolean (target_value, use_ntlm);
 
 	return TRUE;
@@ -270,6 +271,164 @@ comp_func (gconstpointer a,
 		return 0;
 }
 
+static gchar *
+ews_connection_gssapi_challenge (CamelSasl *sasl,
+				 const gchar *what,
+				 gboolean is_base64,
+				 GError **error)
+{
+	GByteArray *ain, *aout = NULL;
+	gchar *response = NULL;
+	GError *local_error = NULL;
+
+	g_return_val_if_fail (sasl != NULL, NULL);
+
+	ain = g_byte_array_new ();
+
+	if (what && *what) {
+		if (is_base64) {
+			guchar *bytes;
+			gsize len = 0;
+
+			bytes = g_base64_decode (what, &len);
+			if (bytes) {
+				g_byte_array_append (ain, bytes, len);
+				g_free (bytes);
+			}
+		} else {
+			g_byte_array_append (ain, (const guchar *) what, strlen (what));
+		}
+	}
+
+	aout = camel_sasl_challenge_sync (sasl, ain, NULL, &local_error);
+
+	if (local_error) {
+		g_propagate_error (error, local_error);
+	} else if (aout && aout->len) {
+		response = g_base64_encode (aout->data, aout->len);
+	} else {
+		response = g_strdup ("");
+	}
+
+	g_byte_array_unref (ain);
+
+	if (aout)
+		g_byte_array_unref (aout);
+
+	return response;
+}
+
+#define EWS_GSSAPI_SOUP_SESSION "ews-gssapi-soup-session"
+#define EWS_GSSAPI_SASL		"ews-gssapi-sasl"
+#define EWS_GSSAPI_CONNECTION	"ews-gssapi-connection"
+
+static void
+ews_connection_authenticate_gssapi_cb (SoupMessage *message,
+				       gpointer user_data)
+{
+	EEwsConnection *connection = g_object_get_data (G_OBJECT (message), EWS_GSSAPI_CONNECTION);
+	SoupSession *session = g_object_get_data (G_OBJECT (message), EWS_GSSAPI_SOUP_SESSION);
+	CamelSasl *sasl = g_object_get_data (G_OBJECT (message), EWS_GSSAPI_SASL);
+	const gchar *auths_lst;
+	gchar **auths;
+	gint ii;
+
+	g_return_if_fail (E_IS_EWS_CONNECTION (connection));
+	g_return_if_fail (SOUP_IS_SESSION (session));
+	g_return_if_fail (CAMEL_IS_SASL (sasl));
+
+	if (SOUP_STATUS_IS_SUCCESSFUL (message->status_code))
+		return;
+
+	auths_lst = soup_message_headers_get_list (message->response_headers, "WWW-Authenticate");
+	if (!auths_lst)
+		return;
+
+	auths = g_strsplit (auths_lst, ",", -1);
+	for (ii = 0; auths && auths[ii]; ii++) {
+		if (g_ascii_strncasecmp (auths[ii], "Negotiate", 9) == 0) {
+			GError *error = NULL;
+			const gchar *chlg = auths[ii] + 9;
+			gchar *response;
+
+			if (*chlg)
+				chlg++;
+			if (!*chlg)
+				chlg = NULL;
+
+			response = ews_connection_gssapi_challenge (sasl, chlg ? chlg : "\r\n", chlg != NULL, &error);
+
+			if (response && *response) {
+				gchar *sasl_response = g_strconcat ("Negotiate ", response, NULL);
+
+				soup_message_headers_remove (message->request_headers, "Authorization");
+				soup_message_headers_append (message->request_headers, "Authorization", sasl_response);
+				soup_session_requeue_message (session, message);
+
+				g_free (sasl_response);
+			} else if (error) {
+				/* cannot use SOUP_STATUS_UNAUTHORIZED, because it may hide an error message,
+				   which is a local error of Kerberos/GSSAPI call */
+				soup_message_set_status_full (message, SOUP_STATUS_BAD_REQUEST, error->message);
+			}
+
+			g_free (response);
+			break;
+		}
+	}
+
+	g_strfreev (auths);
+}
+
+static void
+ews_connection_setup_msg_gssapi_auth (EEwsConnection *connection,
+				      SoupSession *session,
+				      SoupMessage *message)
+{
+	CamelSasl *gssapi_sasl;
+	CamelEwsSettings *ews_settings;
+	CamelNetworkSettings *network_settings;
+	SoupURI *soup_uri;
+	const gchar *host, *user;
+
+	if (!camel_sasl_gssapi_is_available ())
+		return;
+
+	g_return_if_fail (E_IS_EWS_CONNECTION (connection));
+	g_return_if_fail (SOUP_IS_MESSAGE (message));
+
+	ews_settings = e_ews_connection_ref_settings (connection);
+	network_settings = CAMEL_NETWORK_SETTINGS (ews_settings);
+	gssapi_sasl = g_object_new (camel_sasl_gssapi_get_type (),
+			"mechanism", "GSSAPI",
+			"service-name", "HTTP",
+			NULL);
+
+	soup_uri = soup_message_get_uri (message);
+	host = soup_uri_get_host (soup_uri);
+	user = soup_uri_get_user (soup_uri);
+	if (!host || !*host)
+		host = camel_network_settings_get_host (network_settings);
+	if (!user || !*user)
+		user = camel_network_settings_get_user (network_settings);
+
+	camel_sasl_gssapi_override_host_and_user (CAMEL_SASL_GSSAPI (gssapi_sasl), host, user);
+
+	/* this might not be a cyclic ref dependency, as long as the message
+	   is properly served through the session and freed */
+	g_object_set_data_full (G_OBJECT (message), EWS_GSSAPI_SOUP_SESSION,
+		g_object_ref (session), g_object_unref);
+	g_object_set_data_full (G_OBJECT (message), EWS_GSSAPI_CONNECTION,
+		g_object_ref (connection), g_object_unref);
+	g_object_set_data_full (G_OBJECT (message), EWS_GSSAPI_SASL,
+		gssapi_sasl, g_object_unref);
+
+	soup_message_add_header_handler (message, "got_body", "WWW-Authenticate",
+		G_CALLBACK (ews_connection_authenticate_gssapi_cb), NULL);
+
+	g_object_unref (ews_settings);
+}
+
 typedef enum _EwsScheduleOp {
 	EWS_SCHEDULE_OP_QUEUE_MESSAGE,
 	EWS_SCHEDULE_OP_CANCEL,
@@ -454,7 +613,18 @@ ews_next_request (gpointer _cnc)
 	cnc->priv->active_job_queue = g_slist_append (cnc->priv->active_job_queue, node);
 
 	if (cnc->priv->soup_session) {
-		soup_session_queue_message (cnc->priv->soup_session, SOUP_MESSAGE (node->msg), ews_response_cb, node);
+		SoupMessage *msg = SOUP_MESSAGE (node->msg);
+		CamelEwsSettings *ews_settings = e_ews_connection_ref_settings (cnc);
+		gchar *auth_mech = NULL;
+
+		g_object_get (G_OBJECT (ews_settings), "auth-mechanism", &auth_mech, NULL);
+		if (g_strcmp0 (auth_mech, "GSSAPI") == 0)
+			ews_connection_setup_msg_gssapi_auth (cnc, cnc->priv->soup_session, msg);
+
+		g_object_unref (ews_settings);
+		g_free (auth_mech);
+
+		soup_session_queue_message (cnc->priv->soup_session, msg, ews_response_cb, node);
 		QUEUE_UNLOCK (cnc);
 	} else {
 		QUEUE_UNLOCK (cnc);
