From 91f1a0e1058f39fc6b75acb77c95eec2d3106a0c Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 20 Feb 1998 04:39:04 +0000 Subject: Changes for OTP-IMAP. svn path=/trunk/; revision=1658 --- imap.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) (limited to 'imap.c') diff --git a/imap.c b/imap.c index 505c9550..b4f52489 100644 --- a/imap.c +++ b/imap.c @@ -31,6 +31,10 @@ #include #endif +#if OPIE +#include +#endif /* OPIE */ + #ifndef strstr /* glibc-2.1 declares this as a macro */ extern char *strstr(); /* needed on sysV68 R3V7.1. */ #endif /* strstr */ @@ -110,6 +114,69 @@ int imap_ok(int sock, char *argbuf) } } +#if OPIE +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 OTP"); + + if (rval = gen_recv(sock, buffer, sizeof(buffer))) + return rval; + + if ((i = from64tobits(challenge, buffer)) < 0) { + error(0, -1, "Could not decode initial BASE64 challenge"); + return PS_AUTHFAIL; + }; + + + to64frombits(buffer, ctl->remotename, strlen(ctl->remotename)); + + if (outlevel == O_VERBOSE) + error(0, 0, "IMAP> %s", buffer); + SockWrite(sock, buffer, strlen(buffer)); + SockWrite(sock, "\r\n", 2); + + if (rval = gen_recv(sock, buffer, sizeof(buffer))) + return rval; + + if ((i = from64tobits(challenge, buffer)) < 0) { + error(0, -1, "Could not decode OTP challenge"); + return PS_AUTHFAIL; + }; + + rval = opiegenerator(challenge, !strcmp(ctl->password, "opie") ? "" : ctl->password, response); + if ((rval == -2) && (cmd_daemon == -1)) { + 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_VERBOSE) + error(0, 0, "IMAP> %s", buffer); + SockWrite(sock, buffer, strlen(buffer)); + SockWrite(sock, "\r\n", 2); + + if (rval = gen_recv(sock, buffer, sizeof(buffer))) + return rval; + + if (strstr(buffer, "OK")) + return PS_SUCCESS; + else + return PS_AUTHFAIL; +}; +#endif /* OPIE */ + #ifdef KERBEROS_V4 #if SIZEOF_INT == 4 typedef int int32; @@ -529,6 +596,14 @@ int imap_getauth(int sock, struct query *ctl, char *greeting) peek_capable = (imap_version >= IMAP4); +#if OPIE + if ((ctl->server.protocol == P_IMAP) && strstr(capabilities, "AUTH=OTP")) { + if (outlevel == O_VERBOSE) + error(0, 0, "OTP authentication is supported"); + return do_otp(sock, ctl); + }; +#endif /* OPIE */ + #ifdef GSSAPI if (strstr(capabilities, "AUTH=GSSAPI")) { -- cgit v1.2.3