]> Pileus Git - ~andy/fetchmail/blobdiff - ntlmsubr.c
Refer to FETCHMAIL_SSL_SECLEVEL.
[~andy/fetchmail] / ntlmsubr.c
index f9d2733071b5ae68eadd78cf3b01d4db38489f93..cf305ef03b71a17bcdf351dd6040b97c09c0f91e 100644 (file)
@@ -44,7 +44,7 @@ int ntlm_helper(int sock, struct query *ctl, const char *proto)
        dumpSmbNtlmAuthRequest(stdout, &request);
 
     memset(msgbuf,0,sizeof msgbuf);
-    to64frombits (msgbuf, &request, SmbLength(&request));
+    to64frombits (msgbuf, &request, SmbLength(&request), sizeof msgbuf);
 
     if (outlevel >= O_MONITOR)
        report(stdout, "%s> %s\n", proto, msgbuf);
@@ -55,7 +55,36 @@ int ntlm_helper(int sock, struct query *ctl, const char *proto)
     if ((result = gen_recv(sock, msgbuf, sizeof msgbuf)))
        goto cancelfail;
 
-    (void)from64tobits (&challenge, msgbuf, sizeof(challenge));
+    /*
+     * < 0: decoding error
+     * >= 0 < 32: too short to be plausible
+     */
+    if ((result = from64tobits (&challenge, msgbuf, sizeof(challenge))) < 0
+           || result < 32)
+    {
+       report (stderr, GT_("could not decode BASE64 challenge\n"));
+       /* We do not goto cancelfail; the server has already sent the
+        * tagged reply, so the protocol exchange has ended, no need
+        * for us to send the asterisk. */
+       return PS_AUTHFAIL;
+    }
+
+    /* validate challenge:
+     * - ident
+     * - message type
+     * - that offset points into buffer
+     * - that offset + length does not wrap
+     * - that offset + length is not bigger than buffer */
+    if (0 != memcmp("NTLMSSP", challenge.ident, 8)
+           || challenge.msgType != 2
+           || challenge.uDomain.offset > (unsigned)result
+           || (challenge.uDomain.offset + challenge.uDomain.len) < challenge.uDomain.offset
+           || (challenge.uDomain.offset + challenge.uDomain.len) > (unsigned)result)
+    {
+       report (stderr, GT_("NTLM challenge contains invalid data.\n"));
+       result = PS_AUTHFAIL;
+       goto cancelfail;
+    }
 
     if (outlevel >= O_DEBUG)
        dumpSmbNtlmAuthChallenge(stdout, &challenge);
@@ -66,7 +95,7 @@ int ntlm_helper(int sock, struct query *ctl, const char *proto)
        dumpSmbNtlmAuthResponse(stdout, &response);
 
     memset(msgbuf,0,sizeof msgbuf);
-    to64frombits (msgbuf, &response, SmbLength(&response));
+    to64frombits (msgbuf, &response, SmbLength(&response), sizeof msgbuf);
 
     if (outlevel >= O_MONITOR)
        report(stdout, "%s> %s\n", proto, msgbuf);