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