11 int ntlm_helper(int sock, struct query *ctl, const char *proto)
14 * NTLM support by Grant Edwards.
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
21 * Much source (ntlm.h, smb*.c smb*.h) was borrowed from Samba.
23 tSmbNtlmAuthRequest request;
24 tSmbNtlmAuthChallenge challenge;
25 tSmbNtlmAuthResponse response;
30 if ((result = gen_recv(sock, msgbuf, sizeof msgbuf)))
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"));
41 buildSmbNtlmAuthRequest(&request,ctl->remotename,NULL);
43 if (outlevel >= O_DEBUG)
44 dumpSmbNtlmAuthRequest(stdout, &request);
46 memset(msgbuf,0,sizeof msgbuf);
47 to64frombits (msgbuf, &request, SmbLength(&request));
49 if (outlevel >= O_MONITOR)
50 report(stdout, "%s> %s\n", proto, msgbuf);
52 strcat(msgbuf,"\r\n");
53 SockWrite (sock, msgbuf, strlen (msgbuf));
55 if ((result = gen_recv(sock, msgbuf, sizeof msgbuf)))
60 * >= 0 < 32: too short to be plausible
62 if ((result = from64tobits (&challenge, msgbuf, sizeof(challenge))) < 0
65 report (stderr, GT_("could not decode BASE64 challenge\n"));
66 /* We do not goto cancelfail; the server has already sent the
67 * tagged reply, so the protocol exchange has ended, no need
68 * for us to send the asterisk. */
72 /* validate challenge:
75 * - that offset points into buffer
76 * - that offset + length does not wrap
77 * - that offset + length is not bigger than buffer */
78 if (0 != memcmp("NTLMSSP", challenge.ident, 8)
79 || challenge.msgType != 2
80 || challenge.uDomain.offset > (unsigned)result
81 || (challenge.uDomain.offset + challenge.uDomain.len) < challenge.uDomain.offset
82 || (challenge.uDomain.offset + challenge.uDomain.len) > (unsigned)result)
84 report (stderr, GT_("NTLM challenge contains invalid data.\n"));
89 if (outlevel >= O_DEBUG)
90 dumpSmbNtlmAuthChallenge(stdout, &challenge);
92 buildSmbNtlmAuthResponse(&challenge, &response,ctl->remotename,ctl->password);
94 if (outlevel >= O_DEBUG)
95 dumpSmbNtlmAuthResponse(stdout, &response);
97 memset(msgbuf,0,sizeof msgbuf);
98 to64frombits (msgbuf, &response, SmbLength(&response));
100 if (outlevel >= O_MONITOR)
101 report(stdout, "%s> %s\n", proto, msgbuf);
103 strcat(msgbuf,"\r\n");
104 SockWrite (sock, msgbuf, strlen (msgbuf));
108 cancelfail: /* cancel authentication and return failure */
110 if (outlevel >= O_MONITOR)
111 report(stdout, "%s> *\n", proto);
112 SockWrite(sock, "*\r\n", 3);
117 #endif /* NTLM_ENABLE */