1
#include "config.h"
2
3
#ifdef NTLM_ENABLE
4
#include "fetchmail.h"
5
#include "i18n.h"
6
#include "ntlm.h"
7
#include "socket.h"
8
9
#include <string.h>
10
11
int ntlm_helper(int sock, struct query *ctl, const char *proto)
12
{
13
/*
14
 * NTLM support by Grant Edwards.
15
 *
16
 * Handle MS-Exchange NTLM authentication method.  This is the same
17
 * as the NTLM auth used by Samba for SMB related services. We just
18
 * encode the packets in base64 instead of sending them out via a
19
 * network interface.
20
 *
21
 * Much source (ntlm.h, smb*.c smb*.h) was borrowed from Samba.
22
 */
23
    tSmbNtlmAuthRequest request;
24
    tSmbNtlmAuthChallenge challenge;
25
    tSmbNtlmAuthResponse response;
26
27
    char msgbuf[2048];
28
    int result;
29
30
    if ((result = gen_recv(sock, msgbuf, sizeof msgbuf)))
31
	return result;
32
33
    if (msgbuf[0] != '+' && strspn(msgbuf+1, " \t") < strlen(msgbuf+1)) {
34
	if (outlevel >= O_VERBOSE) {
35
	    report(stdout, GT_("Warning: received malformed challenge to \"AUTH(ENTICATE) NTLM\"!\n"));
36
	}
37
	result = PS_AUTHFAIL;
38
	goto cancelfail;
39
    }
40
41
    buildSmbNtlmAuthRequest(&request,ctl->remotename,NULL);
42
43
    if (outlevel >= O_DEBUG)
44
	dumpSmbNtlmAuthRequest(stdout, &request);
45
46
    memset(msgbuf,0,sizeof msgbuf);
47
    to64frombits (msgbuf, &request, SmbLength(&request));
48
49
    if (outlevel >= O_MONITOR)
50
	report(stdout, "%s> %s\n", proto, msgbuf);
51
52
    strcat(msgbuf,"\r\n");
53
    SockWrite (sock, msgbuf, strlen (msgbuf));
54
55
    if ((result = gen_recv(sock, msgbuf, sizeof msgbuf)))
56
	goto cancelfail;
57
58
    (void)from64tobits (&challenge, msgbuf, sizeof(challenge));
59
60
    if (outlevel >= O_DEBUG)
61
	dumpSmbNtlmAuthChallenge(stdout, &challenge);
62
63
    buildSmbNtlmAuthResponse(&challenge, &response,ctl->remotename,ctl->password);
64
65
    if (outlevel >= O_DEBUG)
66
	dumpSmbNtlmAuthResponse(stdout, &response);
67
68
    memset(msgbuf,0,sizeof msgbuf);
69
    to64frombits (msgbuf, &response, SmbLength(&response));
70
71
    if (outlevel >= O_MONITOR)
72
	report(stdout, "%s> %s\n", proto, msgbuf);
73
74
    strcat(msgbuf,"\r\n");
75
    SockWrite (sock, msgbuf, strlen (msgbuf));
76
77
    return PS_SUCCESS;
78
79
cancelfail: /* cancel authentication and return failure */
80
    {
81
	if (outlevel >= O_MONITOR)
82
	    report(stdout, "%s> *\n", proto);
83
	SockWrite(sock, "*\r\n", 3);
84
	return result;
85
    }
86
}
87
88
#endif /* NTLM_ENABLE */