]> Pileus Git - ~andy/fetchmail/blob - opie.c
Note Earl's regression fix for SSL_CTX_clear_options() on older OpenSSL.
[~andy/fetchmail] / opie.c
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 */