]> sjero.net Git - wget/blobdiff - src/http-ntlm.c
Fix compiler warnings
[wget] / src / http-ntlm.c
index ce7dd9848d9bf6e25333edbc5527e98e2709812b..d9b688450618b796ef6c0b8d5469b1fdd5922a24 100644 (file)
@@ -1,12 +1,13 @@
 /* NTLM code.
-   Copyright (C) 2005 Free Software Foundation, Inc.
-   Donated by Daniel Stenberg.
+   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+   Foundation, Inc.
+   Contributed by Daniel Stenberg.
 
 This file is part of GNU Wget.
 
 GNU Wget is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
+the Free Software Foundation; either version 3 of the License, or
  (at your option) any later version.
 
 GNU Wget is distributed in the hope that it will be useful,
@@ -15,99 +16,70 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with Wget; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+along with Wget.  If not, see <http://www.gnu.org/licenses/>.
 
-In addition, as a special exception, the Free Software Foundation
-gives permission to link the code of its release of Wget with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables.  You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL".  If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so.  If you do not wish to do
-so, delete this exception statement from your version.  */
+Additional permission under GNU GPL version 3 section 7
 
-#include <config.h>
+If you modify this program, or any covered work, by linking or
+combining it with the OpenSSL project's OpenSSL library (or a
+modified version of that library), containing parts covered by the
+terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
+grants you additional permission to convey the resulting work.
+Corresponding Source for a non-source form of such a combination
+shall include the source code for the parts of OpenSSL used as well
+as that of the covered work.  */
+
+#include "wget.h"
 
 /* NTLM details:
-   
+
    http://davenport.sourceforge.net/ntlm.html
    http://www.innovation.ch/java/ntlm.html
 
 */
 
-/* -- WIN32 approved -- */
 #include <stdio.h>
-#ifdef HAVE_STRING_H
-# include <string.h>
-#else
-# include <strings.h>
-#endif
+#include <string.h>
 #include <stdlib.h>
 
-#include <openssl/des.h>
-#include <openssl/md4.h>
-#include <openssl/ssl.h>
-
-#include "wget.h"
 #include "utils.h"
 #include "http-ntlm.h"
 
-#if OPENSSL_VERSION_NUMBER < 0x00907001L
-#define DES_key_schedule des_key_schedule
-#define DES_cblock des_cblock
-#define DES_set_odd_parity des_set_odd_parity
-#define DES_set_key des_set_key
-#define DES_ecb_encrypt des_ecb_encrypt
+#ifdef HAVE_NETTLE
+# include <nettle/md4.h>
+# include <nettle/des.h>
+#else
+# include <openssl/des.h>
+# include <openssl/md4.h>
+# include <openssl/opensslv.h>
+
+# if OPENSSL_VERSION_NUMBER < 0x00907001L
+#  define DES_key_schedule des_key_schedule
+#  define DES_cblock des_cblock
+#  define DES_set_odd_parity des_set_odd_parity
+#  define DES_set_key des_set_key
+#  define DES_ecb_encrypt des_ecb_encrypt
 
 /* This is how things were done in the old days */
-#define DESKEY(x) x
-#define DESKEYARG(x) x
-#else
+#  define DESKEY(x) x
+#  define DESKEYARG(x) x
+# else
 /* Modern version */
-#define DESKEYARG(x) *x
-#define DESKEY(x) &x
+#  define DESKEYARG(x) *x
+#  define DESKEY(x) &x
+# endif
+
 #endif
 
 /* Define this to make the type-3 message include the NT response message */
-#undef USE_NTRESPONSES
+#define USE_NTRESPONSES 1
+
 \f
 /* Flag bits definitions available at on
    http://davenport.sourceforge.net/ntlm.html */
 
-#define NTLMFLAG_NEGOTIATE_UNICODE               (1<<0)
 #define NTLMFLAG_NEGOTIATE_OEM                   (1<<1)
-#define NTLMFLAG_REQUEST_TARGET                  (1<<2)
-/* unknown (1<<3) */
-#define NTLMFLAG_NEGOTIATE_SIGN                  (1<<4)
-#define NTLMFLAG_NEGOTIATE_SEAL                  (1<<5)
-#define NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE        (1<<6)
-#define NTLMFLAG_NEGOTIATE_LM_KEY                (1<<7)
-#define NTLMFLAG_NEGOTIATE_NETWARE               (1<<8)
 #define NTLMFLAG_NEGOTIATE_NTLM_KEY              (1<<9)
-/* unknown (1<<10) */
-/* unknown (1<<11) */
-#define NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED       (1<<12)
-#define NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED  (1<<13)
-#define NTLMFLAG_NEGOTIATE_LOCAL_CALL            (1<<14)
-#define NTLMFLAG_NEGOTIATE_ALWAYS_SIGN           (1<<15)
-#define NTLMFLAG_TARGET_TYPE_DOMAIN              (1<<16)
-#define NTLMFLAG_TARGET_TYPE_SERVER              (1<<17)
-#define NTLMFLAG_TARGET_TYPE_SHARE               (1<<18)
-#define NTLMFLAG_NEGOTIATE_NTLM2_KEY             (1<<19)
-#define NTLMFLAG_REQUEST_INIT_RESPONSE           (1<<20)
-#define NTLMFLAG_REQUEST_ACCEPT_RESPONSE         (1<<21)
-#define NTLMFLAG_REQUEST_NONNT_SESSION_KEY       (1<<22)
-#define NTLMFLAG_NEGOTIATE_TARGET_INFO           (1<<23)
-/* unknown (1<24) */
-/* unknown (1<25) */
-/* unknown (1<26) */
-/* unknown (1<27) */
-/* unknown (1<28) */
-#define NTLMFLAG_NEGOTIATE_128                   (1<<29)
-#define NTLMFLAG_NEGOTIATE_KEY_EXCHANGE          (1<<30)
-#define NTLMFLAG_NEGOTIATE_56                    (1<<31)
 \f
 /*
   (*) = A "security buffer" is a triplet consisting of two shorts and one
@@ -119,14 +91,15 @@ so, delete this exception statement from your version.  */
      beginning of the NTLM message, in bytes.
 */
 
-/* return 1 on success, 0 otherwise */
-int ntlm_input (struct ntlmdata *ntlm, const char *header)
+/* return true on success, false otherwise */
+bool
+ntlm_input (struct ntlmdata *ntlm, const char *header)
 {
   if (0 != strncmp (header, "NTLM", 4))
-    return 0;
+    return false;
 
   header += 4;
-  while (*header && ISSPACE(*header))
+  while (*header && c_isspace(*header))
     header++;
 
   if (*header)
@@ -144,12 +117,14 @@ int ntlm_input (struct ntlmdata *ntlm, const char *header)
          (40)    Target Information  (optional) security buffer(*)
          32 (48) start of data block
       */
-      int size;
-      unsigned char *buffer = (unsigned char *) alloca (strlen (header));
+      ssize_t size;
+      char *buffer = (char *) alloca (strlen (header));
+
+      DEBUGP (("Received a type-2 NTLM message.\n"));
 
       size = base64_decode (header, buffer);
       if (size < 0)
-       return 0;               /* malformed base64 from server */
+        return false;           /* malformed base64 from server */
 
       ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */
 
@@ -162,20 +137,44 @@ int ntlm_input (struct ntlmdata *ntlm, const char *header)
   else
     {
       if (ntlm->state >= NTLMSTATE_TYPE1)
-        return 0; /* this is an error */
+        {
+          DEBUGP (("Unexpected empty NTLM message.\n"));
+          return false; /* this is an error */
+        }
 
+      DEBUGP (("Empty NTLM message, starting transaction.\n"));
       ntlm->state = NTLMSTATE_TYPE1; /* we should sent away a type-1 */
     }
 
-  return 1;
+  return true;
 }
 
 /*
  * Turns a 56 bit key into the 64 bit, odd parity key and sets the key.  The
  * key schedule ks is also set.
  */
-static void setup_des_key(unsigned char *key_56,
-                          DES_key_schedule DESKEYARG(ks))
+#ifdef HAVE_NETTLE
+static void
+setup_des_key(unsigned char *key_56,
+              struct des_ctx *des)
+{
+  unsigned char key[8];
+
+  key[0] = key_56[0];
+  key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1);
+  key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2);
+  key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3);
+  key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4);
+  key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5);
+  key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6);
+  key[7] =  (key_56[6] << 1) & 0xFF;
+
+  nettle_des_set_key(des, key);
+}
+#else
+static void
+setup_des_key(unsigned char *key_56,
+              DES_key_schedule DESKEYARG(ks))
 {
   DES_cblock key;
 
@@ -191,16 +190,28 @@ static void setup_des_key(unsigned char *key_56,
   DES_set_odd_parity(&key);
   DES_set_key(&key, ks);
 }
+#endif
 
  /*
   * takes a 21 byte array and treats it as 3 56-bit DES keys. The
   * 8 byte plaintext is encrypted with each key and the resulting 24
   * bytes are stored in the results array.
   */
-static void calc_resp(unsigned char *keys,
-                      unsigned char *plaintext,
-                      unsigned char *results)
+static void
+calc_resp(unsigned char *keys, unsigned char *plaintext, unsigned char *results)
 {
+#ifdef HAVE_NETTLE
+  struct des_ctx des;
+
+  setup_des_key(keys, &des);
+  nettle_des_encrypt(&des, 8, results, plaintext);
+
+  setup_des_key(keys + 7, &des);
+  nettle_des_encrypt(&des, 8, results + 8, plaintext);
+
+  setup_des_key(keys + 14, &des);
+  nettle_des_encrypt(&des, 8, results + 16, plaintext);
+#else
   DES_key_schedule ks;
 
   setup_des_key(keys, DESKEY(ks));
@@ -214,16 +225,18 @@ static void calc_resp(unsigned char *keys,
   setup_des_key(keys+14, DESKEY(ks));
   DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+16),
                   DESKEY(ks), DES_ENCRYPT);
+#endif
 }
 
 /*
  * Set up lanmanager and nt hashed passwords
  */
-static void mkhash(const char *password,
-                   unsigned char *nonce,  /* 8 bytes */
-                   unsigned char *lmresp  /* must fit 0x18 bytes */
+static void
+mkhash(const char *password,
+       unsigned char *nonce,    /* 8 bytes */
+       unsigned char *lmresp    /* must fit 0x18 bytes */
 #ifdef USE_NTRESPONSES
-                   , unsigned char *ntresp  /* must fit 0x18 bytes */
+       , unsigned char *ntresp  /* must fit 0x18 bytes */
 #endif
   )
 {
@@ -235,32 +248,41 @@ static void mkhash(const char *password,
   static const unsigned char magic[] = {
     0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25
   };
-  int i;
-  int len = strlen(password);
+  size_t i, len = strlen(password);
 
   /* make it fit at least 14 bytes */
   pw = (unsigned char *) alloca (len < 7 ? 14 : len * 2);
 
   if (len > 14)
     len = 14;
-  
+
   for (i=0; i<len; i++)
-    pw[i] = TOUPPER (password[i]);
+    pw[i] = (unsigned char) c_toupper (password[i]);
 
   for (; i<14; i++)
     pw[i] = 0;
 
   {
     /* create LanManager hashed password */
+#ifdef HAVE_NETTLE
+    struct des_ctx des;
+
+    setup_des_key(pw, &des);
+    nettle_des_encrypt(&des, 8, lmbuffer, magic);
+
+    setup_des_key(pw + 7, &des);
+    nettle_des_encrypt(&des, 8, lmbuffer + 8, magic);
+#else
     DES_key_schedule ks;
 
     setup_des_key(pw, DESKEY(ks));
     DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
                     DESKEY(ks), DES_ENCRYPT);
-  
+
     setup_des_key(pw+7, DESKEY(ks));
     DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8),
                     DESKEY(ks), DES_ENCRYPT);
+#endif
 
     memset(lmbuffer+16, 0, 5);
   }
@@ -269,19 +291,29 @@ static void mkhash(const char *password,
 
 #ifdef USE_NTRESPONSES
   {
-    /* create NT hashed password */
+#ifdef HAVE_NETTLE
+    struct md4_ctx MD4;
+#else
     MD4_CTX MD4;
+#endif
 
     len = strlen(password);
 
     for (i=0; i<len; i++) {
-      pw[2*i]   = password[i];
+      pw[2*i]   = (unsigned char) password[i];
       pw[2*i+1] = 0;
     }
 
+#ifdef HAVE_NETTLE
+    nettle_md4_init(&MD4);
+    nettle_md4_update(&MD4, (unsigned) (2 * len), pw);
+    nettle_md4_digest(&MD4, MD4_DIGEST_SIZE, ntbuffer);
+#else
+    /* create NT hashed password */
     MD4_Init(&MD4);
     MD4_Update(&MD4, pw, 2*len);
     MD4_Final(ntbuffer, &MD4);
+#endif
 
     memset(ntbuffer+16, 0, 5);
   }
@@ -290,29 +322,30 @@ static void mkhash(const char *password,
 #endif
 }
 
-#define SHORTPAIR(x) ((x) & 0xff), ((x) >> 8)
+#define SHORTPAIR(x) (char) ((x) & 0xff), (char) ((x) >> 8)
 #define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8)&0xff), \
   (((x) >>16)&0xff), ((x)>>24)
 
 /* this is for creating ntlm header output */
-char *ntlm_output (struct ntlmdata *ntlm, const char *user, const char *passwd,
-                  int *ready)
+char *
+ntlm_output (struct ntlmdata *ntlm, const char *user, const char *passwd,
+             bool *ready)
 {
-  const char *domain=""; /* empty */
-  const char *host=""; /* empty */
-  int domlen=strlen(domain);
-  int hostlen = strlen(host);
-  int hostoff; /* host name offset */
-  int domoff;  /* domain name offset */
-  int size;
+  const char *domain = ""; /* empty */
+  const char *host = ""; /* empty */
+  size_t domlen = strlen(domain);
+  size_t hostlen = strlen(host);
+  size_t hostoff; /* host name offset */
+  size_t domoff;  /* domain name offset */
+  size_t size;
   char *base64;
-  unsigned char ntlmbuf[256]; /* enough, unless the host/domain is very long */
+  char ntlmbuf[256]; /* enough, unless the host/domain is very long */
 
   /* point to the address of the pointer that holds the string to sent to the
      server, which is for a plain host or for a HTTP proxy */
-  char *output;
+  char *output = NULL;
 
-  *ready = 0;
+  *ready = false;
 
   /* not set means empty */
   if(!user)
@@ -320,13 +353,16 @@ char *ntlm_output (struct ntlmdata *ntlm, const char *user, const char *passwd,
 
   if(!passwd)
     passwd="";
-  
+
   switch(ntlm->state) {
   case NTLMSTATE_TYPE1:
-  default: /* for the weird cases we (re)start here */
+  case NTLMSTATE_NONE:
+  case NTLMSTATE_LAST:
     hostoff = 32;
     domoff = hostoff + hostlen;
-    
+
+    DEBUGP (("Creating a type-1 NTLM message.\n"));
+
     /* Create and send a type-1 message:
 
     Index Description          Content
@@ -340,46 +376,46 @@ char *ntlm_output (struct ntlmdata *ntlm, const char *user, const char *passwd,
 
     */
 
-    snprintf((char *)ntlmbuf, sizeof(ntlmbuf), "NTLMSSP%c"
-             "\x01%c%c%c" /* 32-bit type = 1 */
-             "%c%c%c%c"   /* 32-bit NTLM flag field */
-             "%c%c"  /* domain length */
-             "%c%c"  /* domain allocated space */
-             "%c%c"  /* domain name offset */
-             "%c%c"  /* 2 zeroes */
-             "%c%c"  /* host length */
-             "%c%c"  /* host allocated space */
-             "%c%c"  /* host name offset */
-             "%c%c"  /* 2 zeroes */
-             "%s"   /* host name */
-             "%s",  /* domain string */
-             0,     /* trailing zero */
-             0,0,0, /* part of type-1 long */
-
-             LONGQUARTET(
-               NTLMFLAG_NEGOTIATE_OEM|      /*   2 */
-               NTLMFLAG_NEGOTIATE_NTLM_KEY  /* 200 */
-               /* equals 0x0202 */
-               ),
-             SHORTPAIR(domlen),
-             SHORTPAIR(domlen),
-             SHORTPAIR(domoff),
-             0,0,
-             SHORTPAIR(hostlen),
-             SHORTPAIR(hostlen),
-             SHORTPAIR(hostoff),
-             0,0,
-             host, domain);
+    snprintf (ntlmbuf, sizeof(ntlmbuf), "NTLMSSP%c"
+              "\x01%c%c%c" /* 32-bit type = 1 */
+              "%c%c%c%c"   /* 32-bit NTLM flag field */
+              "%c%c"  /* domain length */
+              "%c%c"  /* domain allocated space */
+              "%c%c"  /* domain name offset */
+              "%c%c"  /* 2 zeroes */
+              "%c%c"  /* host length */
+              "%c%c"  /* host allocated space */
+              "%c%c"  /* host name offset */
+              "%c%c"  /* 2 zeroes */
+              "%s"   /* host name */
+              "%s",  /* domain string */
+              0,     /* trailing zero */
+              0,0,0, /* part of type-1 long */
+
+              LONGQUARTET(
+                NTLMFLAG_NEGOTIATE_OEM|      /*   2 */
+                NTLMFLAG_NEGOTIATE_NTLM_KEY  /* 200 */
+                /* equals 0x0202 */
+                ),
+              SHORTPAIR(domlen),
+              SHORTPAIR(domlen),
+              SHORTPAIR(domoff),
+              0,0,
+              SHORTPAIR(hostlen),
+              SHORTPAIR(hostlen),
+              SHORTPAIR(hostoff),
+              0,0,
+              host, domain);
 
     /* initial packet length */
     size = 32 + hostlen + domlen;
 
     base64 = (char *) alloca (BASE64_LENGTH (size) + 1);
-    base64_encode (ntlmbuf, base64, size);
+    base64_encode (ntlmbuf, size, base64);
 
     output = concat_strings ("NTLM ", base64, (char *) 0);
     break;
-    
+
   case NTLMSTATE_TYPE2:
     /* We received the type-2 already, create a type-3 message:
 
@@ -397,25 +433,27 @@ char *ntlm_output (struct ntlmdata *ntlm, const char *user, const char *passwd,
     52 (64) start of data block
 
     */
-  
+
   {
-    int lmrespoff;
-    int ntrespoff;
-    int useroff;
+    size_t lmrespoff;
+    size_t ntrespoff;
+    size_t useroff;
     unsigned char lmresp[0x18]; /* fixed-size */
 #ifdef USE_NTRESPONSES
     unsigned char ntresp[0x18]; /* fixed-size */
 #endif
     const char *usr;
-    int userlen;
+    size_t userlen;
+
+    DEBUGP (("Creating a type-3 NTLM message.\n"));
 
     usr = strchr(user, '\\');
     if(!usr)
       usr = strchr(user, '/');
 
     if (usr) {
-      domain = usr;
-      domlen = usr - domain;
+      domain = user;
+      domlen = (size_t) (usr - domain);
       usr++;
     }
     else
@@ -435,87 +473,93 @@ char *ntlm_output (struct ntlmdata *ntlm, const char *user, const char *passwd,
     ntrespoff = lmrespoff + 0x18;
 
     /* Create the big type-3 message binary blob */
-    size = snprintf((char *)ntlmbuf, sizeof(ntlmbuf),
-                    "NTLMSSP%c"
-                    "\x03%c%c%c" /* type-3, 32 bits */
-
-                    "%c%c%c%c" /* LanManager length + allocated space */
-                    "%c%c" /* LanManager offset */
-                    "%c%c" /* 2 zeroes */
-
-                    "%c%c" /* NT-response length */
-                    "%c%c" /* NT-response allocated space */
-                    "%c%c" /* NT-response offset */
-                    "%c%c" /* 2 zeroes */
-                    
-                    "%c%c"  /* domain length */
-                    "%c%c"  /* domain allocated space */
-                    "%c%c"  /* domain name offset */
-                    "%c%c"  /* 2 zeroes */
-                    
-                    "%c%c"  /* user length */
-                    "%c%c"  /* user allocated space */
-                    "%c%c"  /* user offset */
-                    "%c%c"  /* 2 zeroes */
-                    
-                    "%c%c"  /* host length */
-                    "%c%c"  /* host allocated space */
-                    "%c%c"  /* host offset */
-                    "%c%c%c%c%c%c"  /* 6 zeroes */
-                    
-                    "\xff\xff"  /* message length */
-                    "%c%c"  /* 2 zeroes */
-                    
-                    "\x01\x82" /* flags */
-                    "%c%c"  /* 2 zeroes */
-
-                    /* domain string */
-                    /* user string */
-                    /* host string */
-                    /* LanManager response */
-                    /* NT response */
-                    ,
-                    0, /* zero termination */
-                    0,0,0, /* type-3 long, the 24 upper bits */
-
-                    SHORTPAIR(0x18),  /* LanManager response length, twice */
-                    SHORTPAIR(0x18),
-                    SHORTPAIR(lmrespoff),
-                    0x0, 0x0,
-                    
+
+    size = (size_t) snprintf (ntlmbuf, sizeof(ntlmbuf),
+                     "NTLMSSP%c"
+                     "\x03%c%c%c" /* type-3, 32 bits */
+
+                     "%c%c%c%c" /* LanManager length + allocated space */
+                     "%c%c" /* LanManager offset */
+                     "%c%c" /* 2 zeroes */
+
+                     "%c%c" /* NT-response length */
+                     "%c%c" /* NT-response allocated space */
+                     "%c%c" /* NT-response offset */
+                     "%c%c" /* 2 zeroes */
+
+                     "%c%c"  /* domain length */
+                     "%c%c"  /* domain allocated space */
+                     "%c%c"  /* domain name offset */
+                     "%c%c"  /* 2 zeroes */
+
+                     "%c%c"  /* user length */
+                     "%c%c"  /* user allocated space */
+                     "%c%c"  /* user offset */
+                     "%c%c"  /* 2 zeroes */
+
+                     "%c%c"  /* host length */
+                     "%c%c"  /* host allocated space */
+                     "%c%c"  /* host offset */
+                     "%c%c%c%c%c%c"  /* 6 zeroes */
+
+                     "\xff\xff"  /* message length */
+                     "%c%c"  /* 2 zeroes */
+
+                     "\x01\x82" /* flags */
+                     "%c%c"  /* 2 zeroes */
+
+                     /* domain string */
+                     /* user string */
+                     /* host string */
+                     /* LanManager response */
+                     /* NT response */
+                     ,
+                     0, /* zero termination */
+                     0,0,0, /* type-3 long, the 24 upper bits */
+
+                     SHORTPAIR(0x18),  /* LanManager response length, twice */
+                     SHORTPAIR(0x18),
+                     SHORTPAIR(lmrespoff),
+                     0x0, 0x0,
+
 #ifdef USE_NTRESPONSES
-                    SHORTPAIR(0x18),  /* NT-response length, twice */
-                    SHORTPAIR(0x18),
+                     SHORTPAIR(0x18),  /* NT-response length, twice */
+                     SHORTPAIR(0x18),
 #else
-                    0x0, 0x0,
-                    0x0, 0x0,
+                     0x0, 0x0,
+                     0x0, 0x0,
 #endif
-                    SHORTPAIR(ntrespoff),
-                    0x0, 0x0,
-
-                    SHORTPAIR(domlen),
-                    SHORTPAIR(domlen),
-                    SHORTPAIR(domoff),
-                    0x0, 0x0,
-
-                    SHORTPAIR(userlen),
-                    SHORTPAIR(userlen),
-                    SHORTPAIR(useroff),
-                    0x0, 0x0,
-                    
-                    SHORTPAIR(hostlen),
-                    SHORTPAIR(hostlen),
-                    SHORTPAIR(hostoff),
-                    0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-             
-                    0x0, 0x0,
-
-                    0x0, 0x0);
+                     SHORTPAIR(ntrespoff),
+                     0x0, 0x0,
+
+                     SHORTPAIR(domlen),
+                     SHORTPAIR(domlen),
+                     SHORTPAIR(domoff),
+                     0x0, 0x0,
+
+                     SHORTPAIR(userlen),
+                     SHORTPAIR(userlen),
+                     SHORTPAIR(useroff),
+                     0x0, 0x0,
+
+                     SHORTPAIR(hostlen),
+                     SHORTPAIR(hostlen),
+                     SHORTPAIR(hostoff),
+                     0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+
+                     0x0, 0x0,
+
+                     0x0, 0x0);
 
     /* size is now 64 */
     size=64;
     ntlmbuf[62]=ntlmbuf[63]=0;
 
+    /* Make sure that the user and domain strings fit in the target buffer
+       before we copy them there. */
+    if((size + userlen + domlen) >= sizeof(ntlmbuf))
+      return NULL;
+
     memcpy(&ntlmbuf[size], domain, domlen);
     size += domlen;
 
@@ -523,36 +567,36 @@ char *ntlm_output (struct ntlmdata *ntlm, const char *user, const char *passwd,
     size += userlen;
 
     /* we append the binary hashes to the end of the blob */
-    if(size < ((int)sizeof(ntlmbuf) - 0x18)) {
+    if(size < (sizeof(ntlmbuf) - 0x18)) {
       memcpy(&ntlmbuf[size], lmresp, 0x18);
       size += 0x18;
     }
 
 #ifdef USE_NTRESPONSES
-    if(size < ((int)sizeof(ntlmbuf) - 0x18)) {      
+    if(size < (sizeof(ntlmbuf) - 0x18)) {
       memcpy(&ntlmbuf[size], ntresp, 0x18);
       size += 0x18;
     }
 #endif
 
-    ntlmbuf[56] = size & 0xff;
-    ntlmbuf[57] = size >> 8;
+    ntlmbuf[56] = (char) (size & 0xff);
+    ntlmbuf[57] = (char) (size >> 8);
 
     /* convert the binary blob into base64 */
     base64 = (char *) alloca (BASE64_LENGTH (size) + 1);
-    base64_encode (ntlmbuf, base64, size);
+    base64_encode (ntlmbuf, size, base64);
 
     output = concat_strings ("NTLM ", base64, (char *) 0);
 
     ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
-    *ready = 1;
+    *ready = true;
   }
   break;
 
   case NTLMSTATE_TYPE3:
     /* connection is already authenticated,
      * don't send a header in future requests */
-    *ready = 1;
+    *ready = true;
     output = NULL;
     break;
   }