Undo previous change.
authorRichard M. Stallman <rms@gnu.org>
Mon, 25 May 1998 20:11:54 +0000 (20:11 +0000)
committerRichard M. Stallman <rms@gnu.org>
Mon, 25 May 1998 20:11:54 +0000 (20:11 +0000)
lib-src/Makefile.in
lib-src/pop.c
lib-src/pop.h

index e4d2179..24730fb 100644 (file)
@@ -205,21 +205,12 @@ MOVE_FLAGS=
 # ifdef HAVE_LIBCOM_ERR
        COM_ERRLIB = -lcom_err
 # endif
-# ifdef HAVE_LIBGSSAPI_KRB5
-       GSSAPI_KRB5LIB = -lgssapi_krb5
-# endif
-#endif /* KERBEROS */
-
-#ifdef HAVE_LIBGSSAPI
-       GSSAPILIB = -lgssapi
-#endif
+#endif /* KERBEROS
 
-#ifdef HESIOD
-HESIODLIB= -lhesiod
-#endif
+/* If HESIOD is defined, set this to "-lhesiod". */
+HESIODLIB=
 
-MOVE_LIBS=$(GSSAPI_KRB5LIB) $(GSSAPILIB) $(KRB4LIB) $(DESLIB) $(KRB5LIB) \
-       $(CRYPTOLIB) $(COM_ERRLIB) $(HESIODLIB)
+MOVE_LIBS=$(KRB4LIB) $(DESLIB) $(KRB5LIB) $(CRYPTOLIB) $(COM_ERRLIB) $(HESIODLIB)
 
 #ifdef HAVE_LIBMAIL
 LIBMAIL=-lmail
index 499e8ef..69e6e46 100644 (file)
@@ -161,57 +161,6 @@ static char *find_crlf _P((char *, int));
 #define KPOP_SERVICE "kpop"
 #endif
 
-#ifdef GSSAPI
-# ifdef HAVE_GSSAPI_H
-#  include <gssapi.h>
-# else
-#  include <gssapi/gssapi.h>
-# endif
-#define GSSAPI_SERVICE "pop"
-static int pop_auth (/* popserver server, char *user,
-                       char *host, int flags */);
-static void gen_gss_error (/* char *msg, OM_uint32 major, OM_uint32 minor */);
-struct _pop_gssapi
-{
-  int gss_flags;               /* encryption?  integrity protection? */
-  OM_uint32 max_size;          /* max size we can send the server */
-  gss_ctx_id_t gss_context;    /* the security context */
-};
-#define GSSAPI_NOPROT          0x01
-#define GSSAPI_INTEGRITY       0x02
-#define GSSAPI_PRIVACY         0x04
-#define GSSAPI_NEEDWRAP                (GSSAPI_INTEGRITY|GSSAPI_PRIVACY)
-#define GSSAPI_PROTECTION      (GSSAPI_NOPROT|GSSAPI_INTEGRITY|GSSAPI_PRIVACY)
-#define GSSAPI_RCVBUF          1024
-#define GSSAPI_SVC_TYPE        {10, "\052\206\110\206\367\022\001\002\001\004"}
-#define Gssapi(data)           ((struct _pop_gssapi *) (data))
-
-static int b64_decode (/* char *enc, gss_buffer_t dec */);
-static int b64_encode (/* gss_buffer_t dec, char **enc */);
-#define B64_SUCCESS    0
-#define B64_BADPARAM   1
-#define B64_BADCHAR    2
-#define B64_BADPAD     3
-#define B64_BADLEN     4
-#define B64_NOMEM      5
-static char *b64_error[] =
-{
-  "Success",
-  "Bad parameters",
-  "Bad characters in encoding",
-  "Bad padding in encoding",
-  "Bad length",
-  "Out of memory"
-};
-
-/*
- * This function is only needed if you are using the GSSAPI protection
- * mechanisms; it keeps trying until it has read the requested number
- * bytes from the passed-in fd.
- */
-static int fullread (/* int fd, char *buf, int nbytes */);
-#endif /* GSSAPI */
-
 char pop_error[ERROR_MAX];
 int pop_debug = 0;
 
@@ -320,22 +269,10 @@ pop_open (host, username, password, flags)
     }
 
   /* Determine the password */
-#if defined(KERBEROS) || defined(GSSAPI)
-# ifdef KERBEROS
-#  define NO_KERBEROS  POP_NO_KERBEROS
-# else
-#  define NO_KERBEROS  0
-# endif /* KERBEROS */
-
-# ifdef GSSAPI
-#  define NO_GSSAPI    POP_NO_GSSAPI
-# else
-#  define NO_GSSAPI    0
-# endif /* GSSAPI */
-
-# define DONT_NEED_PASSWORD (! (flags & (NO_KERBEROS | NO_GSSAPI)))
+#ifdef KERBEROS
+#define DONT_NEED_PASSWORD (! (flags & POP_NO_KERBEROS))
 #else
-# define DONT_NEED_PASSWORD 0
+#define DONT_NEED_PASSWORD 0
 #endif
  
   if ((! password) && (! DONT_NEED_PASSWORD))
@@ -351,7 +288,7 @@ pop_open (host, username, password, flags)
        }
     }
   if (password)
-    flags |= POP_NO_KERBEROS | (!(flags & POP_NO_NOPROT) ? POP_NO_GSSAPI : 0);
+    flags |= POP_NO_KERBEROS;
   else
     password = username;
 
@@ -379,46 +316,10 @@ pop_open (host, username, password, flags)
   server->buffer_size = GETLINE_MIN;
   server->in_multi = 0;
   server->trash_started = 0;
-  server->extra = 0;
 
   if (getok (server))
     return (0);
 
-#ifdef GSSAPI
-  /*
-   * unless forbidden to use GSSAPI, try the GSSAPI AUTH mechanism..first.
-   */
-  pop_error[0] = '\0'; /* so we can detect errors later... */
-  if (! (flags & POP_NO_GSSAPI))
-    {
-      int ret;
-
-      ret = pop_auth (server, username, host, flags);
-      if (ret == 0)
-       {
-         return (server);
-       }
-      else if (ret == -2)
-       {
-         pop_close (server);
-         return (0);
-       }
-    }
-#endif /* GSSAPI */
-  /*
-   * POP_NO_NOPROT is used in the case that we want protection; if
-   * the authentication negotiation failed, then we want to fail now.
-   */
-  if ((flags & POP_NO_NOPROT))
-    {
-      pop_close (server);
-#ifdef GSSAPI
-      if (pop_error[0] == '\0')
-#endif
-       strcpy (pop_error, "Unable to provide protection");
-      return (0);
-    }
-
   /*
    * I really shouldn't use the pop_error variable like this, but....
    */
@@ -1103,17 +1004,6 @@ pop_quit (server)
 
   if (server->buffer)
     free (server->buffer);
-#ifdef GSSAPI
-  if (server->extra)
-    {
-      OM_uint32 minor;
-
-      if (Gssapi (server->extra)->gss_context != GSS_C_NO_CONTEXT)
-       gss_delete_sec_context (&minor, &(Gssapi (server->extra)->gss_context),
-                               GSS_C_NO_BUFFER);
-      free ((char *) server->extra);
-    }
-#endif /* GSSAPI */
   free ((char *) server);
 
   return (ret);
@@ -1442,102 +1332,22 @@ pop_getline (server, line)
 
   while (1)
     {
-#ifdef GSSAPI
-      /*
-       * We might be playing with a protected connection.  If we are, then
-       * we need to first read a chunk of ciphertext from the server,
-       * unwrap it, and stuff it into the buffer.
-       */
-      if (server->extra &&
-         ((Gssapi (server->extra)->gss_flags) & GSSAPI_NEEDWRAP))
+      /* There's a "- 1" here to leave room for the null that we put
+         at the end of the read data below.  We put the null there so
+         that find_crlf knows where to stop when we call it. */
+      if (server->data == server->buffer_size - 1)
        {
-         char rcvbuf[GSSAPI_RCVBUF];
-         OM_uint32 major, minor, length;
-         gss_buffer_desc in_tok, out_tok;
-         struct _pop_gssapi *gss_data = Gssapi (server->extra);
-
-         ret = fullread (server->file, (char *) &length, sizeof (length));
-
-         if (ret == sizeof (length))
+         server->buffer_size += GETLINE_INCR;
+         server->buffer = (char *)realloc (server->buffer, server->buffer_size);
+         if (! server->buffer)
            {
-             in_tok.length = ntohl (length);
-
-             if (in_tok.length <= GSSAPI_RCVBUF)
-               {
-                 ret = fullread (server->file, rcvbuf, in_tok.length);
-
-                 if (ret == in_tok.length)
-                   {
-                     in_tok.value = (void *) rcvbuf;
-
-                     major = gss_unwrap (&minor, gss_data->gss_context,
-                                         &in_tok, &out_tok, 0, 0);
-
-                     if (major != GSS_S_COMPLETE)
-                       {
-                         pop_trash (server);
-                         gen_gss_error ("unwrapping", major, minor);
-                         return (-1);
-                       }
-
-                     while (server->data + out_tok.length >=
-                            server->buffer_size - 1)
-                       server->buffer_size += GETLINE_INCR;
-
-                     server->buffer = (char *)realloc (server->buffer,
-                                                       server->buffer_size);
-
-                     if (! server->buffer)
-                       {
-                         gss_release_buffer (&minor, &out_tok);
-                         pop_trash (server);
-                         strcpy (pop_error, "Out of memory in pop_getline");
-                         return (-1);
-                       }
-
-                     bcopy (out_tok.value, server->buffer + server->data,
-                            out_tok.length);
-
-                     ret = out_tok.length;
-
-                     gss_release_buffer (&minor, &out_tok);
-                   }
-                 else
-                   ret = 0;    /* force detection of unexpected EOF */
-               }
-             else
-               {
-                 pop_trash (server);
-                 strcpy (pop_error, "Token from server too long in pop_getline");
-                 return (-1);
-               }
-           }
-         else
-           ret = 0;            /* force detection of unexpected EOF */
-       }
-      else
-       {
-#endif /* GSSAPI */
-         /* There's a "- 1" here to leave room for the null that we put
-            at the end of the read data below.  We put the null there so
-            that find_crlf knows where to stop when we call it. */
-         if (server->data == server->buffer_size - 1)
-           {
-             server->buffer_size += GETLINE_INCR;
-             server->buffer = (char *)realloc (server->buffer,
-                                               server->buffer_size);
-             if (! server->buffer)
-               {
-                 strcpy (pop_error, "Out of memory in pop_getline");
-                 pop_trash (server);
-                 return (-1);
-               }
+             strcpy (pop_error, "Out of memory in pop_getline");
+             pop_trash (server);
+             return (-1);
            }
-         ret = RECV (server->file, server->buffer + server->data,
-                     server->buffer_size - server->data - 1, 0);
-#ifdef GSSAPI
        }
-#endif /* GSSAPI */
+      ret = RECV (server->file, server->buffer + server->data,
+                 server->buffer_size - server->data - 1, 0);
       if (ret < 0)
        {
          strcpy (pop_error, GETLINE_ERROR);
@@ -1581,37 +1391,6 @@ pop_getline (server, line)
   /* NOTREACHED */
 }
 
-#ifdef GSSAPI
-/*
- * Function: fullread
- *
- * Purpose: Just like read, but keeps trying until the specified number
- *     number of bytes has been read into the buffer.  This function is
- *     only needed if you are using the GSSAPI protection mechanisms.
- *
- * Return value: Same as read.  Pop_error is not set.
- */
-static int
-fullread (fd, buf, nbytes)
-     int fd;
-     char *buf;
-     int nbytes;
-{
-  char *cp;
-  int ret;
-
-  cp = buf;
-
-  while (nbytes > 0 && (ret = RECV (fd, cp, nbytes, 0)) > 0)
-    {
-      cp += ret;
-      nbytes -= ret;
-    }
-
-  return (ret);
-}
-#endif /* GSSAPI */
-
 /*
  * Function: sendline
  *
@@ -1638,87 +1417,11 @@ sendline (server, line)
 #define SENDLINE_ERROR "Error writing to POP server: "
   int ret;
 
-#ifdef GSSAPI
-  /*
-   * We might be playing with a protected connection.  If we are, then we
-   * need to build our full plaintext, parse it into chunks small enough
-   * for the server to swallow, wrap each one, and send it over the net as
-   * specified by the RFC.
-   */
-  if (server->extra && ((Gssapi (server->extra)->gss_flags) & GSSAPI_NEEDWRAP))
-    {
-      char *sendbuf, *ptr;
-      OM_uint32 major, minor, length;
-      gss_buffer_desc in_tok, out_tok;
-      int len = 0, tot_len;
-      struct _pop_gssapi *gss_data = Gssapi (server->extra);
-
-      sendbuf = malloc (strlen (line) + 3);
-
-      if (! sendbuf)
-       {
-         pop_trash (server);
-         strcpy (pop_error, "Out of memory in sendline");
-         return (-1);
-       }
-
-      tot_len = sprintf (sendbuf, "%s\r\n", line);
-
-      for (ptr = sendbuf; tot_len > 0; tot_len -= len, ptr += len)
-       {
-         len = ((tot_len > gss_data->max_size) ?
-                gss_data->max_size : tot_len);
-
-         in_tok.value = (void *) ptr;
-         in_tok.length = len;
-
-         major = gss_wrap (&minor, gss_data->gss_context,
-                           (gss_data->gss_flags & GSSAPI_PRIVACY) ? 1 : 0,
-                           GSS_C_QOP_DEFAULT, &in_tok, 0, &out_tok);
-
-         if (major != GSS_S_COMPLETE)
-           {
-             free (sendbuf);
-             pop_trash (server);
-             gen_gss_error ("wrapping", major, minor);
-             return (-1);
-           }
-
-         /*
-          * "Once the protection mechanism is in effect, the stream of
-          *  command and response octets is processed into buffers of
-          *  ciphertext.  Each buffer is transferred over the connection
-          *  as a stream of octets prepended with a four octet field in
-          *  network byte order that represents the length of the
-          *  following data." - RFC 1734, section 2
-          */
-         length = htonl (out_tok.length);
-         ret = fullwrite (server->file, (char *) &length, sizeof (length));
-         if (ret == sizeof (length))
-           {
-             ret = fullwrite (server->file, (char *) out_tok.value,
-                              out_tok.length);
-           }
-
-         gss_release_buffer (&minor, &out_tok);
-
-         if (ret < 0)
-           break;
-       }
-
-      free (sendbuf);
+  ret = fullwrite (server->file, line, strlen (line));
+  if (ret >= 0)
+    {                          /* 0 indicates that a blank line was written */
+      ret = fullwrite (server->file, "\r\n", 2);
     }
-  else
-    {
-#endif /* GSSAPI */
-      ret = fullwrite (server->file, line, strlen (line));
-      if (ret >= 0)
-       {                       /* 0 indicates that a blank line was written */
-         ret = fullwrite (server->file, "\r\n", 2);
-       }
-#ifdef GSSAPI
-    }
-#endif /* GSSAPI */
 
   if (ret < 0)
     {
@@ -1886,19 +1589,6 @@ pop_trash (server)
          free (server->buffer);
          server->buffer = 0;
        }
-#ifdef GSSAPI
-      if (server->extra)
-       {
-         OM_uint32 minor;
-
-         if (Gssapi (server->extra)->gss_context != GSS_C_NO_CONTEXT)
-           gss_delete_sec_context (&minor,
-                                   &(Gssapi (server->extra)->gss_context),
-                                  GSS_C_NO_BUFFER);
-         free ((char *) server->extra);
-         server->extra = 0;
-       }
-#endif /* GSSAPI */
     }
 
 #ifdef WINDOWSNT
@@ -1907,654 +1597,6 @@ pop_trash (server)
 #endif
 }
 
-#ifdef GSSAPI
-/*
- * Function: pop_auth
- *
- * Purpose: To perform a GSSAPI authentication handshake with a POP server.
- *     If the negotiation is successful, it will return 0; otherwise, it
- *     will fill in pop_error with the error message and return either -1,
- *     indicating a potentially recoverable error, or -2, indicating an
- *     unrecoverable error.
- *
- * Side effects: The server may choose to close the connection if the
- *     handshake fails.  The connection will be trashed if the error is
- *     unrecoverable.
- */
-static int
-pop_auth (server, username, host, flags)
-     popserver server;
-     char *username, *host;
-     int flags;
-{
-  int gss_flags, ret;
-  char *fromserver;
-  OM_uint32 max_size, t_flags;
-  gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT;
-  gss_buffer_desc in_tok, out_tok;
-  gss_name_t svc_name;
-  OM_uint32 major, minor, t_minor;
-
-  /* calculate usable protection mechanisms */
-  gss_flags = (GSSAPI_PROTECTION &
-              ~(((flags & POP_NO_NOPROT) ? GSSAPI_NOPROT : 0) |
-                ((flags & POP_NO_INTEG) ? GSSAPI_INTEGRITY : 0) |
-                ((flags & POP_NO_ENCRYPT) ? GSSAPI_PRIVACY : 0)));
-
-  if (gss_flags == 0)
-    {
-      strcpy (pop_error, "Unable to provide selected protection level");
-      return (-1);
-    }
-
-  /* import service name of pop server */
-  in_tok.value = (void *) malloc (strlen (host) + sizeof (GSSAPI_SERVICE) + 2);
-
-  if (! in_tok.value)
-    {
-      strcpy (pop_error, "Out of memory in pop_auth");
-      return (-1);
-    }
-
-  sprintf ((char *) in_tok.value, "%s@%s", GSSAPI_SERVICE, host);
-  in_tok.length = strlen ((char *) in_tok.value);
-
-  {
-    gss_OID_desc svc_name_oid = GSSAPI_SVC_TYPE;
-
-    major = gss_import_name (&minor, &in_tok, &svc_name_oid, &svc_name);
-  }
-
-  free ((char *) in_tok.value);
-
-  if (major != GSS_S_COMPLETE)
-    {
-      gen_gss_error ("parsing name", major, minor);
-      return (-1);
-    }
-
-  /* begin GSSAPI authentication handshake */
-  if (sendline (server, "AUTH GSSAPI") || (pop_getline (server, &fromserver) < 0))
-    {
-      gss_release_name (&t_minor, &svc_name);
-      return (-1);
-    }
-
-  do
-    {
-      /* sanity-check server response */
-      if (strncmp (fromserver, "+ ", 2))
-       {
-         gss_release_name (&t_minor, &svc_name);
-         if (gss_context != GSS_C_NO_CONTEXT)
-           gss_delete_sec_context (&t_minor, &gss_context, GSS_C_NO_BUFFER);
-         if (0 == strncmp (fromserver, "-ERR", 4))
-           {
-             strncpy (pop_error, fromserver, ERROR_MAX);
-             return (-1);
-           }
-         else
-           {
-             pop_trash (server);
-             strcpy (pop_error,
-                     "Unexpected response from POP server in pop_auth");
-             return (-2);
-           }
-       }
-
-      if (strlen (fromserver) > 2)
-       {
-         /* base 64 decode the response... */
-         ret = b64_decode (fromserver + 2, &in_tok);
-         if (ret != B64_SUCCESS)
-           {
-             gss_release_name (&t_minor, &svc_name);
-             if (gss_context != GSS_C_NO_CONTEXT)
-               gss_delete_sec_context (&t_minor, &gss_context,
-                                       GSS_C_NO_BUFFER);
-             sendline (server, "*");
-             strcpy (pop_error, b64_error[ret]);
-             return (-1);
-           }
-       }
-      else
-       {
-         in_tok.length = 0;
-         in_tok.value = 0;
-       }
-
-      /* call init_sec_context */
-      major = gss_init_sec_context (&minor, GSS_C_NO_CREDENTIAL, &gss_context,
-                                   svc_name, GSS_C_NULL_OID,
-                                   GSS_C_MUTUAL_FLAG, 0,
-                                   GSS_C_NO_CHANNEL_BINDINGS,
-                                   in_tok.length ? & in_tok : GSS_C_NO_BUFFER,
-                                   0, &out_tok, 0, 0);
-
-      if (in_tok.length != 0)
-       free ((char *) in_tok.value);
-
-      /* check for error */
-      if (GSS_ERROR (major))
-       {
-         gss_release_name (&t_minor, &svc_name);
-         if (gss_context != GSS_C_NO_CONTEXT)
-           gss_delete_sec_context (&t_minor, &gss_context, GSS_C_NO_BUFFER);
-         sendline (server, "*");
-         gen_gss_error ("in init_sec_context", major, minor);
-         return (-1);
-       }
-
-      if (out_tok.length != 0)
-       {
-         /* base 64 encode output token, if any */
-         ret = b64_encode (&out_tok, &fromserver);
-
-         gss_release_buffer (&t_minor, &out_tok);
-
-         if (ret != B64_SUCCESS)
-           {
-             gss_release_name (&t_minor, &svc_name);
-             if (gss_context != GSS_C_NO_CONTEXT)
-               gss_delete_sec_context (&t_minor, &gss_context,
-                                       GSS_C_NO_BUFFER);
-             sendline (server, "*");
-             strcpy (pop_error, b64_error[ret]);
-             return (-1);
-           }
-
-         /* send output token... */
-         ret = sendline (server, fromserver);
-
-         free (fromserver);
-       }
-      else
-       /* empty output token... */
-       ret = sendline (server, "");
-
-      /* get next token from server */
-      if (ret || (pop_getline (server, &fromserver) < 0))
-       {
-         gss_release_name (&t_minor, &svc_name);
-         if (gss_context != GSS_C_NO_CONTEXT)
-           gss_delete_sec_context (&t_minor, &gss_context, GSS_C_NO_BUFFER);
-         return (-1);
-       }
-    } while ((major & GSS_S_CONTINUE_NEEDED));
-
-  /* release name... */
-  gss_release_name (&t_minor, &svc_name);
-
-  /* get final response from server */
-  if (strncmp (fromserver, "+ ", 2))
-    {
-      gss_delete_sec_context (&t_minor, &gss_context, GSS_C_NO_BUFFER);
-      if (0 == strncmp (fromserver, "-ERR", 4))
-       {
-         strncpy (pop_error, fromserver, ERROR_MAX);
-         return (-1);
-       }
-      else
-       {
-         pop_trash (server);
-         strcpy (pop_error,
-                 "Unexpected response from POP server in pop_auth");
-         return (-2);
-       }
-    }
-
-  /* base 64 decode... */
-  ret = b64_decode (fromserver + 2, &in_tok);
-  if (ret != B64_SUCCESS)
-    {
-      gss_delete_sec_context (&t_minor, &gss_context, GSS_C_NO_BUFFER);
-      sendline (server, "*");
-      strcpy (pop_error, b64_error[ret]);
-      return (-1);
-    }
-
-  /* unwrap... */
-  major = gss_unwrap (&minor, gss_context, &in_tok, &out_tok, 0, 0);
-
-  free ((char *) in_tok.value);
-
-  if (major != GSS_S_COMPLETE || out_tok.length != sizeof (t_flags))
-    {
-      if (out_tok.length != 0)
-       gss_release_buffer (&t_minor, &out_tok);
-      gss_delete_sec_context (&t_minor, &gss_context, GSS_C_NO_BUFFER);
-      sendline (server, "*");
-      gen_gss_error ("in gss_unwrap", major, minor);
-      return (-1);
-    }
-
-  /* get and check flags/size */
-  bcopy ((void *) out_tok.value, (void *) &t_flags, sizeof (t_flags));
-
-  gss_release_buffer (&t_minor, &out_tok);
-
-  max_size = ntohl (t_flags);
-
-  t_flags = ((max_size & 0xFF000000) >> 24) & gss_flags;
-  max_size &= 0x00FFFFFF;
-
-  if ((t_flags & GSSAPI_PRIVACY))
-    gss_flags = GSSAPI_PRIVACY;
-
-  else if ((t_flags & GSSAPI_INTEGRITY))
-    gss_flags = GSSAPI_INTEGRITY;
-
-  else if ((t_flags & GSSAPI_NOPROT))
-    gss_flags = GSSAPI_NOPROT;
-
-  else
-    {
-      gss_delete_sec_context (&t_minor, &gss_context, GSS_C_NO_BUFFER);
-      sendline (server, "*");
-      strcpy (pop_error, "Server does not provide selected protection level");
-      return (-1);
-    }
-
-  if (max_size == 0)
-    {
-      gss_delete_sec_context (&t_minor, &gss_context, GSS_C_NO_BUFFER);
-      sendline (server, "*");
-      strcpy (pop_error, "Bad server max length");
-      return (-1);
-    }
-
-  if ((gss_flags & GSSAPI_NEEDWRAP))
-    {
-      major = gss_wrap_size_limit (&t_minor, gss_context,
-                                  (gss_flags & GSSAPI_PRIVACY) ? 1 : 0,
-                                  GSS_C_QOP_DEFAULT,
-                                  (max_size < GSSAPI_RCVBUF) ? max_size :
-                                  GSSAPI_RCVBUF, &max_size);
-      if (major != GSS_S_COMPLETE)
-       {
-         gss_delete_sec_context (&t_minor, &gss_context, GSS_C_NO_BUFFER);
-         sendline (server, "*");
-         gen_gss_error ("getting max size", major, minor);
-         return (-1);
-       }
-    }
-
-  /* generate return flags */
-  {
-    OM_uint32 tmp;
-
-    tmp = (((gss_flags << 24) & 0xFF000000) | (GSSAPI_RCVBUF & 0x00FFFFFF));
-    t_flags = ntohl (tmp);
-  }
-
-  in_tok.length = sizeof (t_flags) + strlen (username);
-  in_tok.value = (void *) malloc (in_tok.length);
-
-  if (! in_tok.value)
-    {
-      gss_delete_sec_context (&t_minor, &gss_context, GSS_C_NO_BUFFER);
-      sendline (server, "*");
-      strcpy (pop_error, "Out of memory in pop_auth");
-      return (-1);
-    }
-
-  bcopy ((void *) &t_flags, in_tok.value, sizeof (t_flags));
-  bcopy ((void *) username,
-        (void *) (((char *) in_tok.value) + sizeof (t_flags)),
-        in_tok.length - sizeof (t_flags));
-
-  /* wrap result */
-  major = gss_wrap (&minor, gss_context, 0, GSS_C_QOP_DEFAULT,
-                   &in_tok, 0, &out_tok);
-
-  free ((char *) in_tok.value);
-
-  if (major != GSS_S_COMPLETE || out_tok.length == 0)
-    {
-      if (out_tok.length != 0)
-       gss_release_buffer (&t_minor, &out_tok);
-      gss_delete_sec_context (&t_minor, &gss_context, GSS_C_NO_BUFFER);
-      sendline (server, "*");
-      gen_gss_error ("in gss_wrap", major, minor);
-      return (-1);
-    }
-
-  /* base 64 encode... */
-  ret = b64_encode (&out_tok, &fromserver);
-
-  gss_release_buffer (&t_minor, &out_tok);
-
-  if (ret != B64_SUCCESS)
-    {
-      gss_delete_sec_context (&t_minor, &gss_context, GSS_C_NO_BUFFER);
-      sendline (server, "*");
-      strcpy (pop_error, b64_error[ret]);
-      return (-1);
-    }
-
-  /* send to server */
-  ret = sendline (server, fromserver);
-
-  free (fromserver);
-
-  /* see if the server likes me... */
-  if (ret || getok (server))
-    {
-      gss_delete_sec_context (&t_minor, &gss_context, GSS_C_NO_BUFFER);
-      return (-1);
-    }
-
-  /* stash context */
-  {
-    struct _pop_gssapi *gss_data;
-
-    gss_data = (struct _pop_gssapi *) malloc (sizeof (struct _pop_gssapi));
-
-    if (! gss_data)
-      {
-       pop_trash (server);
-       gss_delete_sec_context (&t_minor, &gss_context, GSS_C_NO_BUFFER);
-       strcpy (pop_error, "Out of memory in pop_auth");
-       return (-2);
-      }
-
-    gss_data->gss_flags = gss_flags;
-    gss_data->max_size = max_size;
-    gss_data->gss_context = gss_context;
-
-    server->extra = gss_data;
-  }
-
-  return (0);
-}
-
-/*
- * Add as much error text to pop_error as will fit, but only put complete
- * messages
- */
-static void
-gen_gss_error (msg, major, minor)
-     char *msg;
-     OM_uint32 major, minor;
-{
-  char *p = pop_error, *t, *saved;
-  int max = ERROR_MAX - 1; /* for \0 */
-  OM_uint32 t_minor, msg_ctx = 0;
-  gss_buffer_desc gss_msg;
-
-  while (*msg && max)
-    {
-      *p++ = *msg++;
-      max--;
-    }
-
-  if (max >= 2)
-    {
-      saved = p;
-      *p++ = ':';
-      *p++ = ' ';
-      max -= 2;
-    }
-  else
-    {
-      *p = '\0';
-      return;
-    }
-
-  do
-    {
-      gss_display_status (&t_minor, major, GSS_C_GSS_CODE, GSS_C_NO_OID,
-                         &msg_ctx, &gss_msg);
-      for (t = (char *) gss_msg.value; *t && max; max--)
-       {
-         *p++ = *t++;
-       }
-      gss_release_buffer (&t_minor, &gss_msg);
-      if (max == 0)
-       {
-         *saved = '\0';
-         return;
-       }
-    } while (msg_ctx);
-
-  saved = p;
-
-  do
-    {
-      gss_display_status (&t_minor, minor, GSS_C_MECH_CODE, GSS_C_NO_OID,
-                         &msg_ctx, &gss_msg);
-      for (t = (char *) gss_msg.value; *t && max; max--)
-       {
-         *p++ = *t++;
-       }
-      gss_release_buffer (&t_minor, &gss_msg);
-      if (max == 0)
-       {
-         *saved = '\0';
-         return;
-       }
-    } while (msg_ctx);
-
-  *p = '\0';
-  return;
-}
-
-/*
- * table-based base64 decoding function; takes 4 characters from in and
- * writes from 1 to 3 bytes to out, storing the amount written in len
- */
-static int
-b64_d (in, out, len)
-     char *in, *out;
-     int *len;
-{
-  int decodearray[] =
-  {
-    0x3e,   -1,   -1,   -1, 0x3f, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,
-    0x3b, 0x3c, 0x3d,   -1,   -1,   -1,   -1,   -1,   -1,   -1, 0x00, 0x01,
-    0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
-    0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
-      -1,   -1,   -1,   -1,   -1,   -1, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
-    0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33
-  };
-
-  int d;
-
-  if (!in || !out || !len)
-    return (B64_BADPARAM);
-
-  if (*in < '+' || *in > 'z')
-    return (B64_BADCHAR);
-
-  d = decodearray[*(in++) - '+'];
-  if (d == -1)
-    return (B64_BADCHAR);
-  *out = d << 2;
-
-  if (*in < '+' || *in > 'z')
-    return (B64_BADCHAR);
-
-  d = decodearray[*(in++) - '+'];
-  if (d == -1)
-    return (B64_BADCHAR);
-  *(out++) |= d >> 4;
-  *out = (d & 15) << 4;
-
-  if (*in < '+' || *in > 'z')
-    return (B64_BADCHAR);
-  else if (*in == '=')
-    if (*(in + 1) != '=')
-      return (B64_BADPAD);
-    else
-      {
-       *len = 1;
-       return (B64_SUCCESS);
-      }
-
-  d = decodearray[*(in++) - '+'];
-  if (d == -1)
-    return (B64_BADCHAR);
-  *(out++) |= d >> 2;
-  *out = (d & 3) << 6;
-
-  if (*in < '+' || *in > 'z')
-    return (B64_BADCHAR);
-  else if (*in == '=')
-    {
-      *len = 2;
-      return (B64_SUCCESS);
-    }
-
-  d = decodearray[*in - '+'];
-  if (d == -1)
-    return (B64_BADCHAR);
-  *out |= d;
-
-  *len = 3;
-  return (B64_SUCCESS);
-}
-
-/*
- * simple base64 encoding function that takes from 0 to 3 bytes and
- * outputs 4 encoded characters, with appropriate padding
- */
-static int
-b64_e (in, out, len)
-     unsigned char *in, *out;
-     int len;
-{
-  unsigned char codearray[] =
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-  if (!in || !out || len <= 0 || len > 3)
-    return (B64_BADPARAM);
-
-  *(out++) = codearray[((*in) >> 2)];
-
-  if (--len == 0)
-    {
-      *(out++) = codearray[(((*in) & 3) << 4)];
-      *(out++) = '=';
-      *out = '=';
-      return (B64_SUCCESS);
-    }
-
-  *(out++) = codearray[(((*in) & 3) << 4) | ((*(in + 1)) >> 4)];
-  in++;
-
-  if (--len == 0)
-    {
-      *(out++) = codearray[(((*in) & 15) << 2)];
-      *out = '=';
-      return (B64_SUCCESS);
-    }
-
-  *(out++) = codearray[(((*in) & 15) << 2) | ((*(in + 1)) >> 6)];
-  *out = codearray[((*(in + 1)) & 63)];
-
-  return (B64_SUCCESS);
-}
-
-/*
- * given an input string, generate an output gss_buffer_t containing the
- * decoded data and correct length; works by repeatedly driving b64_d ()
- * over the input string
- */
-static int
-b64_decode (enc, dec)
-     char *enc;
-     gss_buffer_t dec;
-{
-  char *tmp;
-  int inlen, outlen = 0, t_len, ret;
-
-  if (!enc || !dec)
-    return (B64_BADPARAM);
-
-  dec->value = 0;
-  dec->length = 0;
-
-  inlen = strlen (enc);
-  if ((inlen % 4))
-    return (B64_BADLEN);
-
-  dec->value = (void *) (tmp = (char *) malloc ((inlen / 4) * 3));
-
-  if (! tmp)
-    return (B64_NOMEM);
-
-  for (; inlen; inlen -= 4)
-    {
-      ret = b64_d (enc, tmp, &t_len);
-      if (ret != B64_SUCCESS)
-       {
-         free ((char *) dec->value);
-         dec->value = 0;
-         return (ret);
-       }
-      else if (t_len != 3)
-       {
-         dec->length = outlen + t_len;
-         return (B64_SUCCESS);
-       }
-      else
-       {
-         enc += 4;
-         tmp += t_len;
-         outlen += t_len;
-       }
-    }
-
-  dec->length = outlen;
-  return (B64_SUCCESS);
-}
-
-/*
- * given a gss_buffer_t, generate an encoded string containing the data.
- * works by repeatedly driving b64_e () over the contents of the buffer_t
- */
-static int
-b64_encode (dec, enc)
-     gss_buffer_t dec;
-     char **enc;
-{
-  unsigned char *tmp, *in;
-  int ret, len;
-
-  if (!dec || !enc)
-    return (B64_BADPARAM);
-
-  in = (unsigned char *) dec->value;
-  len = dec->length;
-  *enc = (char *) (tmp = (unsigned char *) malloc (((len * 4) / 3) + 5));
-
-  if (! tmp)
-    return (B64_NOMEM);
-
-  do
-    {
-      ret = b64_e (in, tmp, len >= 3 ? 3 : len);
-      if (ret != B64_SUCCESS)
-       {
-         free (*enc);
-         *enc = 0;
-         return (ret);
-       }
-      else
-       {
-         in += 3;
-         tmp += 4;
-       }
-    } while ((len -= 3) > 0);
-
-  *tmp = '\0';
-
-  return (B64_SUCCESS);
-}
-
-#endif /* GSSAPI */
-
 /* Return a pointer to the first CRLF in IN_STRING, which can contain
    embedded nulls and has LEN characters in it not including the final
    null, or 0 if it does not contain one.  */
index 7a56947..cfd333c 100644 (file)
@@ -36,7 +36,6 @@ struct _popserver
   int buffer_size, buffer_index;
   int in_multi;
   int trash_started;
-  void *extra;
 };
 
 typedef struct _popserver *popserver;
@@ -48,30 +47,6 @@ typedef struct _popserver *popserver;
 #define POP_NO_KERBEROS        (1<<0)
 #define POP_NO_HESIOD  (1<<1)
 #define POP_NO_GETPASS         (1<<2)
-#define POP_NO_GSSAPI  (1<<3)  /* don't use the GSSAPI */
-#define POP_NO_NOPROT  (1<<4)  /* prohibit no protection; this *only* */
-                               /* makes sense if you use GSSAPI */
-#define POP_NO_INTEG   (1<<5)  /* don't use plain integrity */
-#define POP_NO_ENCRYPT (1<<6)  /* don't use encryption */
-
-/*
- * GSSAPI documentation
- *
- * This version will attempt to perform a GSSAPI handshake first; if this
- * fails, then it will attempt standard POP authentication.  Note that
- * library conflicts may prevent the use of this with the Kerberos
- * kpop hack.
- *
- * If you specify POP_NO_NOPROT and this library is unable to provide either
- * integrity protection or encryption, pop_open() will fail.  The pop_open()
- * call will attempt the highest level protection available; i.e., if both
- * server and client support encryption (and you do not provide the
- * POP_NO_ENCRYPT flag), that will be used; if both server and client support
- * integrity protection (and you do not provide the POP_NO_INTEG flag), that
- * will be used.  If neither of these are available, and you have not
- * specified the POP_NO_NOPROT flag, then this will be a normal, unprotected
- * connection.
- */
 
 #ifdef __STDC__
 #define _ARGS(a) a