aboutsummaryrefslogtreecommitdiffstats
path: root/ntlmsubr.c
diff options
context:
space:
mode:
authorMatthias Andree <matthias.andree@gmx.de>2012-08-14 20:47:22 +0200
committerMatthias Andree <matthias.andree@gmx.de>2012-08-14 20:56:47 +0200
commitc189f6a54f36f5b6f7734303db3cfc52311aab5f (patch)
treed477669cc743ee2186ee368005236fd272ac03a5 /ntlmsubr.c
parent4bb8724c875163a426d7da7044b08582600367d1 (diff)
downloadfetchmail-c189f6a54f36f5b6f7734303db3cfc52311aab5f.tar.gz
fetchmail-c189f6a54f36f5b6f7734303db3cfc52311aab5f.tar.bz2
fetchmail-c189f6a54f36f5b6f7734303db3cfc52311aab5f.zip
Validate NTLM challenge fields.
This is to avoid reading from bad locations, and possibly conveying confidential data. Credit to Nico Golde.
Diffstat (limited to 'ntlmsubr.c')
-rw-r--r--ntlmsubr.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/ntlmsubr.c b/ntlmsubr.c
index 9321d26e..63cbed8f 100644
--- a/ntlmsubr.c
+++ b/ntlmsubr.c
@@ -55,7 +55,8 @@ int ntlm_helper(int sock, struct query *ctl, const char *proto)
if ((result = gen_recv(sock, msgbuf, sizeof msgbuf)))
goto cancelfail;
- if ((result = from64tobits (&challenge, msgbuf, sizeof(challenge))) < 0)
+ if ((result = from64tobits (&challenge, msgbuf, sizeof(challenge))) < 0
+ || result < ((void *)&challenge.context - (void *)&challenge))
{
report (stderr, GT_("could not decode BASE64 challenge\n"));
/* We do not goto cancelfail; the server has already sent the
@@ -64,6 +65,23 @@ int ntlm_helper(int sock, struct query *ctl, const char *proto)
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 > result
+ || challenge.uDomain.offset + challenge.uDomain.len < challenge.uDomain.offset
+ || challenge.uDomain.offset + challenge.uDomain.len > result)
+ {
+ report (stderr, GT_("NTLM challenge contains invalid data.\n"));
+ result = PS_AUTHFAIL;
+ goto cancelfail;
+ }
+
if (outlevel >= O_DEBUG)
dumpSmbNtlmAuthChallenge(stdout, &challenge);