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