]> granicus.if.org Git - neomutt/commitdiff
Hi - this is a patch against mutt-1.4 to use version 2 of the Cyrus
authorNathan Dushman <nhd+mutt@andrew.cmu.edu>
Tue, 12 Nov 2002 08:20:08 +0000 (08:20 +0000)
committerNathan Dushman <nhd+mutt@andrew.cmu.edu>
Tue, 12 Nov 2002 08:20:08 +0000 (08:20 +0000)
SASL library; all changes are ifdef'd so as not to break SASLv1
support. This includes a patch to configure.in to allow the choice
between v1 and v2, but someone with a better understanding of
autoconf should double-check it.

configure.in
imap/auth_gss.c
imap/auth_sasl.c
main.c
mutt_sasl.c
mutt_sasl.h

index 31510e3062070a287544ccaad3a38bb86f90d3d2..fd9115cdfb51ad26c2c5d26f8c4bcf1fc9699cb3 100644 (file)
@@ -611,6 +611,72 @@ AC_ARG_WITH(sasl, [  --with-sasl[=PFX]          Use Cyrus SASL library for POP/I
         ])
 AM_CONDITIONAL(USE_SASL, test x$need_sasl = xyes)
 
+AC_ARG_WITH(sasl2, [  --with-sasl2[=PFX]          Use Cyrus SASL library version 2 for POP/IMAP authentication],
+        [
+        if test "$need_socket" != "yes"
+        then
+          AC_MSG_ERROR([SASL support is only useful with POP or IMAP support])
+        fi
+
+        if test "$with_sasl2" != "no"
+        then
+          if test "$with_sasl2" != "yes"
+          then
+            CPPFLAGS="$CPPFLAGS -I$with_sasl2/include"
+            LDFLAGS="$LDFLAGS -L$with_sasl2/lib"
+          fi
+
+          saved_LIBS="$LIBS"
+
+          AC_CHECK_LIB(sasl2, sasl_client_init,,
+            AC_MSG_ERROR([could not find libsasl]),)
+
+          MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS mutt_sasl.o"
+          MUTTLIBS="$MUTTLIBS -lsasl2"
+          LIBS="$saved_LIBS"
+          AC_DEFINE(USE_SASL,1,
+                  [ Define if want to use the Cyrus SASL library for POP/IMAP authentication. ])
+          AC_DEFINE(USE_SASL2,1,
+                  [ Define if want to use version 2 of the Cyrus SASL library. ])
+          need_sasl=yes
+          need_md5=no
+        fi
+        ])
+AM_CONDITIONAL(USE_SASL, test x$need_sasl = xyes)
+
+AC_ARG_WITH(sasl2, [  --with-sasl2[=PFX]          Use Cyrus SASL library version 2 for POP/IMAP authentication],
+        [
+        if test "$need_socket" != "yes"
+        then
+          AC_MSG_ERROR([SASL support is only useful with POP or IMAP support])
+        fi
+
+        if test "$with_sasl2" != "no"
+        then
+          if test "$with_sasl2" != "yes"
+          then
+            CPPFLAGS="$CPPFLAGS -I$with_sasl2/include"
+            LDFLAGS="$LDFLAGS -L$with_sasl2/lib"
+          fi
+
+          saved_LIBS="$LIBS"
+
+          AC_CHECK_LIB(sasl2, sasl_client_init,,
+            AC_MSG_ERROR([could not find libsasl]),)
+
+          MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS mutt_sasl.o"
+          MUTTLIBS="$MUTTLIBS -lsasl2"
+          LIBS="$saved_LIBS"
+          AC_DEFINE(USE_SASL,1,
+                  [ Define if want to use the Cyrus SASL library for POP/IMAP authentication. ])
+          AC_DEFINE(USE_SASL2,1,
+                  [ Define if want to use version 2 of the Cyrus SASL library. ])
+          need_sasl=yes
+          need_md5=no
+        fi
+        ])
+AM_CONDITIONAL(USE_SASL, test x$need_sasl = xyes)
+
 if test "$need_md5" = "yes"
 then
         MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS md5c.o"
index 1a7491e87cfd32f868c000a3503f4482ecbfc06c..a6a290862fbf889032f49704683b287344d596bb 100644 (file)
@@ -28,7 +28,7 @@
 #include <netinet/in.h>
 
 #ifdef HAVE_HEIMDAL
-#  include <gssapi.h>
+#  include <gssapi/gssapi.h>
 #  define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
 #else
 #  include <gssapi/gssapi.h>
index c8e656edfa1910b6aa1f88d679d397e0e1846e2b..4bfaab42a9d9ea91e5704ece5d2b4b3516fe2f9a 100644 (file)
 #include "imap_private.h"
 #include "auth.h"
 
+#ifdef USE_SASL2
+#include <sasl/sasl.h>
+#include <sasl/saslutil.h>
+#else
 #include <sasl.h>
 #include <saslutil.h>
+#endif
 
 /* imap_auth_sasl: Default authenticator if available. */
 imap_auth_res_t imap_auth_sasl (IMAP_DATA* idata, const char* method)
@@ -34,7 +39,11 @@ imap_auth_res_t imap_auth_sasl (IMAP_DATA* idata, const char* method)
   int rc, irc;
   char buf[LONG_STRING];
   const char* mech;
+#ifdef USE_SASL2
+  const char *pc = NULL;
+#else
   char* pc = NULL;
+#endif
   unsigned int len, olen;
   unsigned char client_start;
 
@@ -63,15 +72,25 @@ imap_auth_res_t imap_auth_sasl (IMAP_DATA* idata, const char* method)
     if (mutt_bit_isset (idata->capabilities, AUTH_ANON) &&
        (!idata->conn->account.user[0] ||
         !ascii_strncmp (idata->conn->account.user, "anonymous", 9)))
+#ifdef USE_SASL2
+      rc = sasl_client_start (saslconn, "AUTH=ANONYMOUS", NULL, &pc, &olen, 
+                              &mech);
+#else
       rc = sasl_client_start (saslconn, "AUTH=ANONYMOUS", NULL, NULL, &pc, &olen,
                              &mech);
+#endif
   }
   
   if (rc != SASL_OK && rc != SASL_CONTINUE)
     do
     {
+#ifdef USE_SASL2
+      rc = sasl_client_start (saslconn, method, &interaction,
+        &pc, &olen, &mech);
+#else
       rc = sasl_client_start (saslconn, method, NULL, &interaction,
         &pc, &olen, &mech);
+#endif
       if (rc == SASL_INTERACT)
        mutt_sasl_interact (interaction);
     }
@@ -108,7 +127,11 @@ imap_auth_res_t imap_auth_sasl (IMAP_DATA* idata, const char* method)
 
     if (irc == IMAP_CMD_RESPOND)
     {
+#ifdef USE_SASL2
+      if (sasl_decode64 (idata->cmd.buf+2, strlen (idata->cmd.buf+2), buf, LONG_STRING-1,
+#else
       if (sasl_decode64 (idata->cmd.buf+2, strlen (idata->cmd.buf+2), buf,
+#endif
                         &len) != SASL_OK)
       {
        dprint (1, (debugfile, "imap_auth_sasl: error base64-decoding server response.\n"));
@@ -140,7 +163,9 @@ imap_auth_res_t imap_auth_sasl (IMAP_DATA* idata, const char* method)
 
       /* sasl_client_st(art|ep) allocate pc with malloc, expect me to 
        * free it */
+#ifndef USE_SASL2
       FREE (&pc);
+#endif
     }
     
     if (olen || rc == SASL_CONTINUE)
diff --git a/main.c b/main.c
index 7a7c24762fd952fdf004d2d7bd25130db9140df9..d2091a0025b56600e7de7478bfbd8e23b05486c1 100644 (file)
--- a/main.c
+++ b/main.c
@@ -232,6 +232,11 @@ static void show_version (void)
        "+USE_SASL  "
 #else
        "-USE_SASL  "
+#endif
+#ifdef USE_SASL2
+       "+USE_SASL2  "
+#else
+       "-USE_SASL2  "
 #endif
        "\n"
        
index 4d6d7fe6ebb5ec593f50374737b838257e2784cc..350cc307ac65777c17a1f4ebfb2c14be09dae30f 100644 (file)
 #include "mutt_sasl.h"
 #include "mutt_socket.h"
 
+#ifdef USE_SASL2
+#include <netdb.h>
+#include <sasl/sasl.h>
+#else
 #include <sasl.h>
+#endif
 #include <sys/socket.h>
 #include <netinet/in.h>
 
  * a protection buffer. */ 
 #define M_SASL_MAXBUF 65536
 
+#ifdef USE_SASL2
+#define IP_PORT_BUFLEN 1024
+#endif
+
 static sasl_callback_t mutt_sasl_callbacks[5];
 
 static int mutt_sasl_start (void);
@@ -50,6 +59,26 @@ static int mutt_sasl_conn_read (CONNECTION* conn, char* buf, size_t len);
 static int mutt_sasl_conn_write (CONNECTION* conn, const char* buf,
   size_t count);
 
+#ifdef USE_SASL2
+/* utility function, stolen from sasl2 sample code */
+static int iptostring(const struct sockaddr *addr, socklen_t addrlen,
+                     char *out, unsigned outlen) {
+    char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
+    
+    if(!addr || !out) return SASL_BADPARAM;
+
+    getnameinfo(addr, addrlen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
+                NI_NUMERICHOST | NI_WITHSCOPEID | NI_NUMERICSERV);
+
+    if(outlen < strlen(hbuf) + strlen(pbuf) + 2)
+        return SASL_BUFOVER;
+
+    snprintf(out, outlen, "%s;%s", hbuf, pbuf);
+
+    return SASL_OK;
+}
+#endif
+
 /* mutt_sasl_start: called before doing a SASL exchange - initialises library
  *   (if neccessary). */
 int mutt_sasl_start (void)
@@ -93,7 +122,13 @@ int mutt_sasl_start (void)
 int mutt_sasl_client_new (CONNECTION* conn, sasl_conn_t** saslconn)
 {
   sasl_security_properties_t secprops;
+#ifdef USE_SASL2
+  struct sockaddr local, remote;
+  socklen_t size;
+  char iplocalport[IP_PORT_BUFLEN], ipremoteport[IP_PORT_BUFLEN];
+#else
   sasl_external_properties_t extprops;
+#endif
   const char* service;
   int rc;
 
@@ -112,10 +147,40 @@ int mutt_sasl_client_new (CONNECTION* conn, sasl_conn_t** saslconn)
       dprint (1, (debugfile, "mutt_sasl_client_new: account type unset\n"));
       return -1;
   }
+
+#ifdef USE_SASL2
+  size = sizeof (local);
+  if (getsockname (conn->fd, &local, &size)){
+    dprint (1, (debugfile, "mutt_sasl_client_new: getsockname for local failed\n"));
+    return -1;
+  }
+  else 
+  if (iptostring(&local, size, iplocalport, IP_PORT_BUFLEN) != SASL_OK){
+    dprint (1, (debugfile, "mutt_sasl_client_new: iptostring for local failed\n"));
+    return -1;
+  }
   
+  size = sizeof (remote);
+  if (getpeername (conn->fd, &remote, &size)){
+    dprint (1, (debugfile, "mutt_sasl_client_new: getsockname for remote failed\n"));
+    return -1;
+  }
+  else 
+  if (iptostring(&remote, size, ipremoteport, IP_PORT_BUFLEN) != SASL_OK){
+    dprint (1, (debugfile, "mutt_sasl_client_new: iptostring for remote failed\n"));
+    return -1;
+  }
+
+dprint(1,(debugfile, "local ip: %s, remote ip:%s\n", iplocalport, ipremoteport));
+  
+  rc = sasl_client_new (service, conn->account.host, iplocalport, ipremoteport,
+    mutt_sasl_get_callbacks (&conn->account), 0, saslconn);
+
+#else
   rc = sasl_client_new (service, conn->account.host,
     mutt_sasl_get_callbacks (&conn->account), SASL_SECURITY_LAYER, saslconn);
-  
+#endif
+
   if (rc != SASL_OK)
   {
     dprint (1, (debugfile,
@@ -127,6 +192,7 @@ int mutt_sasl_client_new (CONNECTION* conn, sasl_conn_t** saslconn)
   /* Do we need to fail if this fails? I would assume having these unset
    * would just disable KRB4. Who wrote this code? I'm not sure how this
    * interacts with the NSS code either, since that mucks with the fd. */
+#ifndef USE_SASL2 /* with SASLv2 this all happens in sasl_client_new */
   {
     struct sockaddr_in local, remote;
     socklen_t size;
@@ -157,6 +223,7 @@ int mutt_sasl_client_new (CONNECTION* conn, sasl_conn_t** saslconn)
     }
 #endif
   }
+#endif
 
   /* set security properties. We use NOPLAINTEXT globally, since we can
    * just fall back to LOGIN in the IMAP case anyway. If that doesn't
@@ -181,14 +248,27 @@ int mutt_sasl_client_new (CONNECTION* conn, sasl_conn_t** saslconn)
 #if defined(USE_SSL) && !defined(USE_NSS)
   if (conn->account.flags & M_ACCT_SSL)
   {
+#ifdef USE_SASL2 /* I'm not sure this actually has an effect, at least with SASLv2 */
+    dprint (2, (debugfile, "External SSF: %d\n", conn->ssf));
+    if (sasl_setprop (*saslconn, SASL_SSF_EXTERNAL, &(conn->ssf)) != SASL_OK)
+#else
     memset (&extprops, 0, sizeof (extprops));
     extprops.ssf = conn->ssf;
     dprint (2, (debugfile, "External SSF: %d\n", extprops.ssf));
     if (sasl_setprop (*saslconn, SASL_SSF_EXTERNAL, &extprops) != SASL_OK)
+#endif
     {
       dprint (1, (debugfile, "mutt_sasl_client_new: Error setting external properties\n"));
       return -1;
     }
+#ifdef USE_SASL2
+    dprint (2, (debugfile, "External authentication name: %s\n","NULL"));
+    if (sasl_setprop (*saslconn, SASL_AUTH_EXTERNAL, NULL) != SASL_OK)
+     {
+      dprint (1, (debugfile, "mutt_sasl_client_new: Error setting external properties\n"));
+      return -1;
+    }
+#endif
   }
 #endif
 
@@ -274,11 +354,19 @@ void mutt_sasl_setup_conn (CONNECTION* conn, sasl_conn_t* saslconn)
 
   sasldata->saslconn = saslconn;
   /* get ssf so we know whether we have to (en|de)code read/write */
+#ifdef USE_SASL2
+  sasl_getprop (saslconn, SASL_SSF, (const void**) &sasldata->ssf);
+#else
   sasl_getprop (saslconn, SASL_SSF, (void**) &sasldata->ssf);
+#endif
   dprint (3, (debugfile, "SASL protection strength: %u\n", *sasldata->ssf));
   /* Add SASL SSF to transport SSF */
   conn->ssf += *sasldata->ssf;
+#ifdef USE_SASL2
+  sasl_getprop (saslconn, SASL_MAXOUTBUF, (const void**) &sasldata->pbufsize);
+#else
   sasl_getprop (saslconn, SASL_MAXOUTBUF, (void**) &sasldata->pbufsize);
+#endif
   dprint (3, (debugfile, "SASL protection buffer size: %u\n", *sasldata->pbufsize));
 
   /* clear input buffer */
@@ -398,7 +486,9 @@ static int mutt_sasl_conn_close (CONNECTION* conn)
 
   /* release sasl resources */
   sasl_dispose (&sasldata->saslconn);
+#ifndef USE_SASL2
   FREE (&sasldata->buf);
+#endif
   FREE (&sasldata);
 
   /* call underlying close */
@@ -430,7 +520,9 @@ static int mutt_sasl_conn_read (CONNECTION* conn, char* buf, size_t len)
   
   conn->sockdata = sasldata->sockdata;
 
+#ifndef USE_SASL2
   FREE (&sasldata->buf);
+#endif
   sasldata->bpos = 0;
   sasldata->blen = 0;
 
@@ -478,7 +570,11 @@ static int mutt_sasl_conn_write (CONNECTION* conn, const char* buf,
   SASL_DATA* sasldata;
   int rc;
 
+#ifdef USE_SASL2
+  const char *pbuf;
+#else
   char* pbuf;
+#endif
   unsigned int olen, plen;
 
   sasldata = (SASL_DATA*) conn->sockdata;
@@ -501,7 +597,9 @@ static int mutt_sasl_conn_write (CONNECTION* conn, const char* buf,
       }
 
       rc = (sasldata->write) (conn, pbuf, plen);
+#ifndef USE_SASL2
       FREE (&pbuf);
+#endif
       if (rc != plen)
        goto fail;
 
index 2e7e473910f1060ff22aee8893db7064bc95d206..eaba032f82ec12039f829613f0b68cbbd3e1f407 100644 (file)
 #ifndef _MUTT_SASL_H_
 #define _MUTT_SASL_H_ 1
 
+#ifdef USE_SASL2
+#include <sasl/sasl.h>
+#else
 #include <sasl.h>
+#endif
 
 #include "mutt_socket.h"
 
@@ -37,7 +41,11 @@ typedef struct
   const unsigned int* pbufsize;
 
   /* read buffer */
+#ifdef USE_SASL2
+  const char *buf;
+#else
   char* buf;
+#endif
   unsigned int blen;
   unsigned int bpos;