Mercurial > emacs
changeset 22236:bfaacbee089a
Undo previous change.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Mon, 25 May 1998 20:11:54 +0000 |
parents | ee90e9da3a70 |
children | 566c88b62de6 |
files | lib-src/Makefile.in lib-src/pop.c lib-src/pop.h |
diffstat | 3 files changed, 24 insertions(+), 1016 deletions(-) [+] |
line wrap: on
line diff
--- a/lib-src/Makefile.in Mon May 25 20:10:50 1998 +0000 +++ b/lib-src/Makefile.in Mon May 25 20:11:54 1998 +0000 @@ -205,21 +205,12 @@ # ifdef HAVE_LIBCOM_ERR COM_ERRLIB = -lcom_err # endif -# ifdef HAVE_LIBGSSAPI_KRB5 - GSSAPI_KRB5LIB = -lgssapi_krb5 -# endif -#endif /* KERBEROS */ +#endif /* KERBEROS -#ifdef HAVE_LIBGSSAPI - GSSAPILIB = -lgssapi -#endif +/* If HESIOD is defined, set this to "-lhesiod". */ +HESIODLIB= -#ifdef HESIOD -HESIODLIB= -lhesiod -#endif - -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
--- a/lib-src/pop.c Mon May 25 20:10:50 1998 +0000 +++ b/lib-src/pop.c Mon May 25 20:11:54 1998 +0000 @@ -161,57 +161,6 @@ #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 @@ } /* 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 @@ } } 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 @@ 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 @@ 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 @@ 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); - } + strcpy (pop_error, "Out of memory in pop_getline"); + pop_trash (server); + 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); - } - } - 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 @@ /* 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 @@ #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 @@ 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 @@ #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. */
--- a/lib-src/pop.h Mon May 25 20:10:50 1998 +0000 +++ b/lib-src/pop.h Mon May 25 20:11:54 1998 +0000 @@ -36,7 +36,6 @@ int buffer_size, buffer_index; int in_multi; int trash_started; - void *extra; }; typedef struct _popserver *popserver; @@ -48,30 +47,6 @@ #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