diff options
Diffstat (limited to 'imap.c')
-rw-r--r-- | imap.c | 255 |
1 files changed, 0 insertions, 255 deletions
@@ -15,25 +15,9 @@ #include "fetchmail.h" #include "socket.h" -#ifdef GSSAPI -#ifdef HAVE_GSSAPI_H -#include <gssapi.h> -#endif -#ifdef HAVE_GSSAPI_GSSAPI_H -#include <gssapi/gssapi.h> -#endif -#ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H -#include <gssapi/gssapi_generic.h> -#endif -#ifndef HAVE_GSS_C_NT_HOSTBASED_SERVICE -#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name -#endif -#endif - #include "i18n.h" #if OPIE_ENABLE -#include <opie.h> #endif /* OPIE_ENABLE */ #ifndef strstr /* glibc-2.1 declares this as a macro */ @@ -133,245 +117,6 @@ int imap_ok(int sock, char *argbuf) } } -#if OPIE_ENABLE -static int do_otp(int sock, struct query *ctl) -{ - int i, rval; - char buffer[128]; - char challenge[OPIE_CHALLENGE_MAX+1]; - char response[OPIE_RESPONSE_MAX+1]; - - gen_send(sock, "AUTHENTICATE X-OTP"); - - if (rval = gen_recv(sock, buffer, sizeof(buffer))) - return rval; - - if ((i = from64tobits(challenge, buffer)) < 0) { - report(stderr, _("Could not decode initial BASE64 challenge\n")); - return PS_AUTHFAIL; - }; - - - to64frombits(buffer, ctl->remotename, strlen(ctl->remotename)); - - if (outlevel >= O_MONITOR) - report(stdout, "IMAP> %s\n", buffer); - - /* best not to count on the challenge code handling multiple writes */ - strcat(buffer, "\r\n"); - SockWrite(sock, buffer, strlen(buffer)); - - if (rval = gen_recv(sock, buffer, sizeof(buffer))) - return rval; - - if ((i = from64tobits(challenge, buffer)) < 0) { - report(stderr, _("Could not decode OTP challenge\n")); - return PS_AUTHFAIL; - }; - - rval = opiegenerator(challenge, !strcmp(ctl->password, "opie") ? "" : ctl->password, response); - if ((rval == -2) && !run.poll_interval) { - char secret[OPIE_SECRET_MAX+1]; - fprintf(stderr, _("Secret pass phrase: ")); - if (opiereadpass(secret, sizeof(secret), 0)) - rval = opiegenerator(challenge, secret, response); - memset(secret, 0, sizeof(secret)); - }; - - if (rval) - return(PS_AUTHFAIL); - - to64frombits(buffer, response, strlen(response)); - - if (outlevel >= O_MONITOR) - report(stdout, "IMAP> %s\n", buffer); - strcat(buffer, "\r\n"); - SockWrite(sock, buffer, strlen(buffer)); - - if (rval = gen_recv(sock, buffer, sizeof(buffer))) - return rval; - - if (strstr(buffer, "OK")) - return PS_SUCCESS; - else - return PS_AUTHFAIL; -}; -#endif /* OPIE_ENABLE */ - -#ifdef GSSAPI -#define GSSAUTH_P_NONE 1 -#define GSSAUTH_P_INTEGRITY 2 -#define GSSAUTH_P_PRIVACY 4 - -static int do_gssauth(int sock, char *hostname, char *username) -{ - gss_buffer_desc request_buf, send_token; - gss_buffer_t sec_token; - gss_name_t target_name; - gss_ctx_id_t context; - gss_OID mech_name; - gss_qop_t quality; - int cflags; - OM_uint32 maj_stat, min_stat; - char buf1[8192], buf2[8192], server_conf_flags; - unsigned long buf_size; - int result; - - /* first things first: get an imap ticket for host */ - sprintf(buf1, "imap@%s", hostname); - request_buf.value = buf1; - request_buf.length = strlen(buf1) + 1; - maj_stat = gss_import_name(&min_stat, &request_buf, GSS_C_NT_HOSTBASED_SERVICE, - &target_name); - if (maj_stat != GSS_S_COMPLETE) { - report(stderr, _("Couldn't get service name for [%s]\n"), buf1); - return PS_AUTHFAIL; - } - else if (outlevel >= O_DEBUG) { - maj_stat = gss_display_name(&min_stat, target_name, &request_buf, - &mech_name); - report(stderr, _("Using service name [%s]\n"),request_buf.value); - maj_stat = gss_release_buffer(&min_stat, &request_buf); - } - - gen_send(sock, "AUTHENTICATE GSSAPI"); - - /* upon receipt of the GSSAPI authentication request, server returns - * null data ready response. */ - if (result = gen_recv(sock, buf1, sizeof buf1)) { - return result; - } - - /* now start the security context initialisation loop... */ - sec_token = GSS_C_NO_BUFFER; - context = GSS_C_NO_CONTEXT; - if (outlevel >= O_VERBOSE) - report(stdout, _("Sending credentials\n")); - do { - send_token.length = 0; - send_token.value = NULL; - maj_stat = gss_init_sec_context(&min_stat, - GSS_C_NO_CREDENTIAL, - &context, - target_name, - GSS_C_NO_OID, - GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG, - 0, - GSS_C_NO_CHANNEL_BINDINGS, - sec_token, - NULL, - &send_token, - NULL, - NULL); - if (maj_stat!=GSS_S_COMPLETE && maj_stat!=GSS_S_CONTINUE_NEEDED) { - report(stderr, _("Error exchanging credentials\n")); - gss_release_name(&min_stat, &target_name); - /* wake up server and await NO response */ - SockWrite(sock, "\r\n", 2); - if (result = gen_recv(sock, buf1, sizeof buf1)) - return result; - return PS_AUTHFAIL; - } - to64frombits(buf1, send_token.value, send_token.length); - gss_release_buffer(&min_stat, &send_token); - strcat(buf1, "\r\n"); - SockWrite(sock, buf1, strlen(buf1)); - if (outlevel >= O_MONITOR) - report(stdout, "IMAP> %s\n", buf1); - if (maj_stat == GSS_S_CONTINUE_NEEDED) { - if (result = gen_recv(sock, buf1, sizeof buf1)) { - gss_release_name(&min_stat, &target_name); - return result; - } - request_buf.length = from64tobits(buf2, buf1 + 2); - request_buf.value = buf2; - sec_token = &request_buf; - } - } while (maj_stat == GSS_S_CONTINUE_NEEDED); - gss_release_name(&min_stat, &target_name); - - /* get security flags and buffer size */ - if (result = gen_recv(sock, buf1, sizeof buf1)) { - return result; - } - request_buf.length = from64tobits(buf2, buf1 + 2); - request_buf.value = buf2; - - maj_stat = gss_unwrap(&min_stat, context, &request_buf, &send_token, - &cflags, &quality); - if (maj_stat != GSS_S_COMPLETE) { - report(stderr, _("Couldn't unwrap security level data\n")); - gss_release_buffer(&min_stat, &send_token); - return PS_AUTHFAIL; - } - if (outlevel >= O_DEBUG) - report(stdout, _("Credential exchange complete\n")); - /* first octet is security levels supported. We want none, for now */ - server_conf_flags = ((char *)send_token.value)[0]; - if ( !(((char *)send_token.value)[0] & GSSAUTH_P_NONE) ) { - report(stderr, _("Server requires integrity and/or privacy\n")); - gss_release_buffer(&min_stat, &send_token); - return PS_AUTHFAIL; - } - ((char *)send_token.value)[0] = 0; - buf_size = ntohl(*((long *)send_token.value)); - /* we don't care about buffer size if we don't wrap data */ - gss_release_buffer(&min_stat, &send_token); - if (outlevel >= O_DEBUG) { - report(stdout, _("Unwrapped security level flags: %s%s%s\n"), - server_conf_flags & GSSAUTH_P_NONE ? "N" : "-", - server_conf_flags & GSSAUTH_P_INTEGRITY ? "I" : "-", - server_conf_flags & GSSAUTH_P_PRIVACY ? "C" : "-"); - report(stdout, _("Maximum GSS token size is %ld\n"),buf_size); - } - - /* now respond in kind (hack!!!) */ - buf_size = htonl(buf_size); /* do as they do... only matters if we do enc */ - memcpy(buf1, &buf_size, 4); - buf1[0] = GSSAUTH_P_NONE; - strcpy(buf1+4, username); /* server decides if princ is user */ - request_buf.length = 4 + strlen(username) + 1; - request_buf.value = buf1; - maj_stat = gss_wrap(&min_stat, context, 0, GSS_C_QOP_DEFAULT, &request_buf, - &cflags, &send_token); - if (maj_stat != GSS_S_COMPLETE) { - report(stderr, _("Error creating security level request\n")); - return PS_AUTHFAIL; - } - to64frombits(buf1, send_token.value, send_token.length); - if (outlevel >= O_DEBUG) { - report(stdout, _("Requesting authorization as %s\n"), username); - report(stdout, "IMAP> %s\n",buf1); - } - strcat(buf1, "\r\n"); - SockWrite(sock, buf1, strlen(buf1)); - - /* we should be done. Get status and finish up */ - do { - if (result = gen_recv(sock, buf1, sizeof buf1)) - return result; - } while(strncmp(buf1, tag, strlen(tag)) != 0); - if (strstr(buf1, "OK")) { - /* flush security context */ - if (outlevel >= O_DEBUG) - report(stdout, _("Releasing GSS credentials\n")); - maj_stat = gss_delete_sec_context(&min_stat, &context, &send_token); - if (maj_stat != GSS_S_COMPLETE) { - report(stderr, _("Error releasing credentials\n")); - return PS_AUTHFAIL; - } - /* send_token may contain a notification to the server to flush - * credentials. RFC 1731 doesn't specify what to do, and since this - * support is only for authentication, we'll assume the server - * knows enough to flush its own credentials */ - gss_release_buffer(&min_stat, &send_token); - return PS_SUCCESS; - } - - return PS_AUTHFAIL; -} -#endif /* GSSAPI */ - #if NTLM_ENABLE #include "ntlm.h" |