| 1 |
/* |
| 2 |
* opie.c -- One-Time Password authentication. |
| 3 |
* |
| 4 |
* For license terms, see the file COPYING in this directory. |
| 5 |
*/ |
| 6 |
|
| 7 |
#include "config.h" |
| 8 |
#include <stdio.h> |
| 9 |
#include <string.h> |
| 10 |
#include <ctype.h> |
| 11 |
#if defined(STDC_HEADERS) |
| 12 |
#include <stdlib.h> |
| 13 |
#endif |
| 14 |
#include "fetchmail.h" |
| 15 |
#include "socket.h" |
| 16 |
|
| 17 |
#include "i18n.h" |
| 18 |
#include "fm_md5.h" |
| 19 |
|
| 20 |
#ifdef OPIE_ENABLE |
| 21 |
#ifdef __cplusplus |
| 22 |
extern "C" { |
| 23 |
#endif |
| 24 |
#include <opie.h> |
| 25 |
#ifdef __cplusplus |
| 26 |
} |
| 27 |
#endif |
| 28 |
|
| 29 |
int do_otp(int sock, const char *command, struct query *ctl) |
| 30 |
{ |
| 31 |
int i, rval; |
| 32 |
char buffer[128]; |
| 33 |
char challenge[OPIE_CHALLENGE_MAX+1+8]; |
| 34 |
char response[OPIE_RESPONSE_MAX+1]; |
| 35 |
|
| 36 |
gen_send(sock, "%s X-OTP", command); |
| 37 |
|
| 38 |
if ((rval = gen_recv(sock, buffer, sizeof(buffer)))) |
| 39 |
return rval; |
| 40 |
|
| 41 |
if (strncmp(buffer, "+", 1)) { |
| 42 |
report(stderr, GT_("server recv fatal\n")); |
| 43 |
return PS_AUTHFAIL; |
| 44 |
} |
| 45 |
|
| 46 |
to64frombits(buffer, ctl->remotename, strlen(ctl->remotename)); |
| 47 |
suppress_tags = TRUE; |
| 48 |
gen_send(sock, "%s", buffer); |
| 49 |
suppress_tags = FALSE; |
| 50 |
|
| 51 |
if ((rval = gen_recv(sock, buffer, sizeof(buffer)))) |
| 52 |
return rval; |
| 53 |
|
| 54 |
memset(challenge, '\0', sizeof(challenge)); |
| 55 |
if ((i = from64tobits(challenge, buffer+2, sizeof(challenge))) < 0) { |
| 56 |
report(stderr, GT_("Could not decode OTP challenge\n")); |
| 57 |
return PS_AUTHFAIL; |
| 58 |
}; |
| 59 |
|
| 60 |
memset(response, '\0', sizeof(response)); |
| 61 |
rval = opiegenerator(challenge, ctl->password, response); |
| 62 |
if ((rval == -2) && !run.poll_interval) { |
| 63 |
char secret[OPIE_SECRET_MAX+1]; |
| 64 |
fprintf(stderr, GT_("Secret pass phrase: ")); |
| 65 |
if (opiereadpass(secret, sizeof(secret), 0)) |
| 66 |
rval = opiegenerator(challenge, secret, response); |
| 67 |
memset(secret, 0, sizeof(secret)); |
| 68 |
}; |
| 69 |
|
| 70 |
if (rval) |
| 71 |
return(PS_AUTHFAIL); |
| 72 |
|
| 73 |
to64frombits(buffer, response, strlen(response)); |
| 74 |
suppress_tags = TRUE; |
| 75 |
gen_send(sock, "%s", buffer); |
| 76 |
suppress_tags = FALSE; |
| 77 |
|
| 78 |
if ((rval = gen_recv(sock, buffer, sizeof(buffer)))) |
| 79 |
return rval; |
| 80 |
|
| 81 |
return PS_SUCCESS; |
| 82 |
} |
| 83 |
#endif /* OPIE_ENABLE */ |
| 84 |
|
| 85 |
/* opie.c ends here */ |