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