[evolution-data-server] Allow automatic NTLM authentication unconditionally



commit 2645a6e1801c431a3a7d682747cc9db0918fa0de
Author: David Woodhouse <David Woodhouse intel com>
Date:   Thu Jun 27 22:09:04 2013 +0100

    Allow automatic NTLM authentication unconditionally
    
    As part of bug 703181 we retested imapx+NTLM authentication, and it seems
    that the NTLM SASL mechanism wasn't allowing the ntlm_auth helper to be used
    unless its ->try_empty_password_sync() method was called.
    
    That made sense when this support was first added, since the logic in the
    back end would go something like:
    
      if (try_empty_password())
        { /* Try it and return OK if it worked */ }
      demand_password_from_user()
      ...
    
    However, the setup of the authentication is now different, and the imapx
    back end (for example) doesn't even *care* about the password. Adding an
    artificial call to camel_sasl_try_empty_password_sync() into the imapx code
    seemed like the wrong thing to do; it should be enabled *automatically*.
    
    So do that: try to set up the ntlm_auth helper in sasl_ntlm_challenge_sync()
    if we are invoked with no password.

 camel/camel-sasl-ntlm.c |  180 +++++++++++++++++++++++++----------------------
 1 files changed, 95 insertions(+), 85 deletions(-)
---
diff --git a/camel/camel-sasl-ntlm.c b/camel/camel-sasl-ntlm.c
index b90949e..3018f54 100644
--- a/camel/camel-sasl-ntlm.c
+++ b/camel/camel-sasl-ntlm.c
@@ -38,6 +38,7 @@
 struct _CamelSaslNTLMPrivate {
        gint placeholder;  /* allow for future expansion */
 #ifndef G_OS_WIN32
+       gboolean tried_helper;
        CamelStream *helper_stream;
        gchar *type1_msg;
 #endif
@@ -680,6 +681,97 @@ deskey (DES_KS k,
        }
 }
 
+static gboolean
+sasl_ntlm_try_empty_password_sync (CamelSasl *sasl,
+                                   GCancellable *cancellable,
+                                   GError **error)
+{
+#ifndef G_OS_WIN32
+       CamelStream *stream = camel_stream_process_new ();
+       CamelNetworkSettings *network_settings;
+       CamelSettings *settings;
+       CamelService *service;
+       CamelSaslNTLM *ntlm = CAMEL_SASL_NTLM (sasl);
+       CamelSaslNTLMPrivate *priv = ntlm->priv;
+       const gchar *cp;
+       gchar *user;
+       gchar buf[1024];
+       gsize s;
+       gchar *command;
+       gint ret;
+
+       if (priv->tried_helper)
+               return !!priv->helper_stream;
+
+       priv->tried_helper = TRUE;
+
+       if (access (NTLM_AUTH_HELPER, X_OK))
+               return FALSE;
+
+       service = camel_sasl_get_service (sasl);
+
+       settings = camel_service_ref_settings (service);
+       g_return_val_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings), FALSE);
+
+       network_settings = CAMEL_NETWORK_SETTINGS (settings);
+       user = camel_network_settings_dup_user (network_settings);
+
+       g_object_unref (settings);
+
+       g_return_val_if_fail (user != NULL, FALSE);
+
+       cp = strchr (user, '\\');
+       if (cp != NULL) {
+               command = g_strdup_printf (
+                       "%s --helper-protocol ntlmssp-client-1 "
+                       "--use-cached-creds --username '%s' "
+                       "--domain '%.*s'", NTLM_AUTH_HELPER,
+                       cp + 1, (gint)(cp - user), user);
+       } else {
+               command = g_strdup_printf (
+                       "%s --helper-protocol ntlmssp-client-1 "
+                       "--use-cached-creds --username '%s'",
+                       NTLM_AUTH_HELPER, user);
+       }
+
+       ret = camel_stream_process_connect (
+               CAMEL_STREAM_PROCESS (stream), command, NULL, error);
+
+       g_free (command);
+       g_free (user);
+
+       if (ret) {
+               g_object_unref (stream);
+               return FALSE;
+       }
+
+       if (camel_stream_write_string (stream, "YR\n", cancellable, error) < 0) {
+               g_object_unref (stream);
+               return FALSE;
+       }
+
+       s = camel_stream_read (stream, buf, sizeof (buf), cancellable, NULL);
+       if (s < 4) {
+               g_object_unref (stream);
+               return FALSE;
+       }
+
+       if (buf[0] != 'Y' || buf[1] != 'R' || buf[2] != ' ' || buf[s - 1] != '\n') {
+               g_object_unref (stream);
+               return FALSE;
+       }
+
+       buf[s - 1] = 0;
+
+       priv->helper_stream = stream;
+       priv->type1_msg = g_strdup (buf + 3);
+       return TRUE;
+#else
+       /* Win32 should be able to use SSPI here. */
+       return FALSE;
+#endif
+}
+
 static GByteArray *
 sasl_ntlm_challenge_sync (CamelSasl *sasl,
                           GByteArray *token,
@@ -718,6 +810,9 @@ sasl_ntlm_challenge_sync (CamelSasl *sasl,
 
        ret = g_byte_array_new ();
 
+       if (!priv->tried_helper && password == NULL)
+               sasl_ntlm_try_empty_password_sync (sasl, cancellable, NULL);
+
 #ifndef G_OS_WIN32
        if (priv->helper_stream && password == NULL) {
                guchar *data;
@@ -881,91 +976,6 @@ exit:
        return ret;
 }
 
-static gboolean
-sasl_ntlm_try_empty_password_sync (CamelSasl *sasl,
-                                   GCancellable *cancellable,
-                                   GError **error)
-{
-#ifndef G_OS_WIN32
-       CamelStream *stream = camel_stream_process_new ();
-       CamelNetworkSettings *network_settings;
-       CamelSettings *settings;
-       CamelService *service;
-       CamelSaslNTLM *ntlm = CAMEL_SASL_NTLM (sasl);
-       CamelSaslNTLMPrivate *priv = ntlm->priv;
-       const gchar *cp;
-       gchar *user;
-       gchar buf[1024];
-       gsize s;
-       gchar *command;
-       gint ret;
-
-       if (access (NTLM_AUTH_HELPER, X_OK))
-               return FALSE;
-
-       service = camel_sasl_get_service (sasl);
-
-       settings = camel_service_ref_settings (service);
-       g_return_val_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings), FALSE);
-
-       network_settings = CAMEL_NETWORK_SETTINGS (settings);
-       user = camel_network_settings_dup_user (network_settings);
-
-       g_object_unref (settings);
-
-       g_return_val_if_fail (user != NULL, FALSE);
-
-       cp = strchr (user, '\\');
-       if (cp != NULL) {
-               command = g_strdup_printf (
-                       "%s --helper-protocol ntlmssp-client-1 "
-                       "--use-cached-creds --username '%s' "
-                       "--domain '%.*s'", NTLM_AUTH_HELPER,
-                       cp + 1, (gint)(cp - user), user);
-       } else {
-               command = g_strdup_printf (
-                       "%s --helper-protocol ntlmssp-client-1 "
-                       "--use-cached-creds --username '%s'",
-                       NTLM_AUTH_HELPER, user);
-       }
-
-       ret = camel_stream_process_connect (
-               CAMEL_STREAM_PROCESS (stream), command, NULL, error);
-
-       g_free (command);
-       g_free (user);
-
-       if (ret) {
-               g_object_unref (stream);
-               return FALSE;
-       }
-
-       if (camel_stream_write_string (stream, "YR\n", cancellable, error) < 0) {
-               g_object_unref (stream);
-               return FALSE;
-       }
-
-       s = camel_stream_read (stream, buf, sizeof (buf), cancellable, NULL);
-       if (s < 4) {
-               g_object_unref (stream);
-               return FALSE;
-       }
-
-       if (buf[0] != 'Y' || buf[1] != 'R' || buf[2] != ' ' || buf[s - 1] != '\n') {
-               g_object_unref (stream);
-               return FALSE;
-       }
-
-       buf[s - 1] = 0;
-
-       priv->helper_stream = stream;
-       priv->type1_msg = g_strdup (buf + 3);
-       return TRUE;
-#else
-       /* Win32 should be able to use SSPI here. */
-       return FALSE;
-#endif
-}
 
 static void
 sasl_ntlm_finalize (GObject *object)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]