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 */