bd7fd41ed0a8fc68c782638c9e928ee0f17ce652
[users/jgh/exim.git] / src / src / auths / auth-spa.c
1 /* $Cambridge: exim/src/src/auths/auth-spa.c,v 1.2 2004/12/29 10:55:58 ph10 Exp $ */
2
3 /*************************************************
4 *     Exim - an Internet mail transport agent    *
5 *************************************************/
6
7 /*
8  * This file provides the necessary methods for authenticating with
9  * Microsoft's Secure Password Authentication.
10
11  * All the original code used here was torn by Marc Prud'hommeaux out of the
12  * Samba project (by Andrew Tridgell, Jeremy Allison, and others).
13
14  * Tom Kistner provided additional code, adding spa_build_auth_challenge() to
15  * support server authentication mode.
16
17  * Mark Lyda provided a patch to solve this problem:
18
19  - Exim is indicating in its Authentication Request message (Type 1) that it
20    can transmit text in either Unicode or OEM format.
21
22  - Microsoft's SMTP server (smtp.email.msn.com) is responding in its
23    Challenge message (Type 2) that it will be expecting the OEM format.
24
25  - Exim does not pay attention to the text format requested by Microsoft's
26    SMTP server and, instead, defaults to using the Unicode format.
27
28  * References:
29  * http://www.innovation.ch/java/ntlm.html
30  * http://www.kuro5hin.org/story/2002/4/28/1436/66154
31
32  * It seems that some systems have existing but different definitions of some
33  * of the following types. I received a complaint about "int16" causing
34  * compilation problems. So I (PH) have renamed them all, to be on the safe
35  * side, by adding 'x' on the end.
36
37  * typedef signed short int16;
38  * typedef unsigned short uint16;
39  * typedef unsigned uint32;
40  * typedef unsigned char  uint8;
41
42  * The API is extremely simple:
43  * 1. Form a SPA authentication request based on the username
44  *    and (optional) domain
45  * 2. Send the request to the server and get an SPA challenge
46  * 3. Build the challenge response and send it back.
47  *
48  * Example usage is as
49  * follows:
50  *
51 int main (int argc, char ** argv)
52 {
53        SPAAuthRequest   request;
54        SPAAuthChallenge challenge;
55        SPAAuthResponse  response;
56        char msgbuf[2048];
57        char buffer[512];
58        char *username, *password, *domain, *challenge_str;
59
60        if (argc < 3)
61        {
62                printf ("Usage: %s <username> <password> [SPA Challenge]\n",
63                        argv [0]);
64                exit (1);
65        }
66
67        username = argv [1];
68        password = argv [2];
69        domain = 0;
70
71        spa_build_auth_request (&request, username, domain);
72
73        spa_bits_to_base64 (msgbuf, (unsigned char*)&request,
74                spa_request_length(&request));
75
76        printf ("SPA Login request for username=%s:\n   %s\n",
77                argv [1], msgbuf);
78
79        if (argc < 4)
80        {
81                printf ("Run: %s <username> <password> [NTLM Challenge] " \
82                        "to complete authenitcation\n", argv [0]);
83                exit (0);
84        }
85
86        challenge_str = argv [3];
87
88        spa_build_auth_response (&challenge, &response, username, password);
89        spa_bits_to_base64 (msgbuf, (unsigned char*)&response,
90                spa_request_length(&response));
91
92        printf ("SPA Response to challenge:\n   %s\n for " \
93                "username=%s, password=%s:\n   %s\n",
94                argv[3], argv [1], argv [2], msgbuf);
95        return 0;
96 }
97  *
98  *
99  * All the client code used here was torn by Marc Prud'hommeaux out of the
100  * Samba project (by Andrew Tridgell, Jeremy Allison, and others).
101  * Previous comments are below:
102  */
103
104 /*
105    Unix SMB/Netbios implementation.
106    Version 1.9.
107
108    a partial implementation of DES designed for use in the
109    SMB authentication protocol
110
111    Copyright (C) Andrew Tridgell 1998
112
113    This program is free software; you can redistribute it and/or modify
114    it under the terms of the GNU General Public License as published by
115    the Free Software Foundation; either version 2 of the License, or
116    (at your option) any later version.
117
118    This program is distributed in the hope that it will be useful,
119    but WITHOUT ANY WARRANTY; without even the implied warranty of
120    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
121    GNU General Public License for more details.
122
123    You should have received a copy of the GNU General Public License
124    along with this program; if not, write to the Free Software
125    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
126 */
127
128
129 /* NOTES:
130
131    This code makes no attempt to be fast! In fact, it is a very
132    slow implementation
133
134    This code is NOT a complete DES implementation. It implements only
135    the minimum necessary for SMB authentication, as used by all SMB
136    products (including every copy of Microsoft Windows95 ever sold)
137
138    In particular, it can only do a unchained forward DES pass. This
139    means it is not possible to use this code for encryption/decryption
140    of data, instead it is only useful as a "hash" algorithm.
141
142    There is no entry point into this code that allows normal DES operation.
143
144    I believe this means that this code does not come under ITAR
145    regulations but this is NOT a legal opinion. If you are concerned
146    about the applicability of ITAR regulations to this code then you
147    should confirm it for yourself (and maybe let me know if you come
148    up with a different answer to the one above)
149 */
150
151 #define DEBUG(a,b) ;
152
153 extern int DEBUGLEVEL;
154
155 #include <sys/types.h>     /* For size_t */
156 #include "auth-spa.h"
157 #include <assert.h>
158 #include <ctype.h>
159 #include <stdio.h>
160 #include <stdlib.h>
161 #include <string.h>
162 #include <time.h>
163 #include <unistd.h>
164
165 #ifndef _AIX
166 typedef unsigned char uchar;
167 #endif
168
169
170 typedef int BOOL;
171 #define False 0
172 #define True  1
173
174 #ifndef _BYTEORDER_H
175 #define _BYTEORDER_H
176
177 #define RW_PCVAL(read,inbuf,outbuf,len) \
178        { if (read) { PCVAL (inbuf,0,outbuf,len); } \
179        else      { PSCVAL(inbuf,0,outbuf,len); } }
180
181 #define RW_PIVAL(read,big_endian,inbuf,outbuf,len) \
182        { if (read) { if (big_endian) { RPIVAL(inbuf,0,outbuf,len); } else { PIVAL(inbuf,0,outbuf,len); } } \
183        else      { if (big_endian) { RPSIVAL(inbuf,0,outbuf,len); } else { PSIVAL(inbuf,0,outbuf,len); } } }
184
185 #define RW_PSVAL(read,big_endian,inbuf,outbuf,len) \
186        { if (read) { if (big_endian) { RPSVAL(inbuf,0,outbuf,len); } else { PSVAL(inbuf,0,outbuf,len); } } \
187        else      { if (big_endian) { RPSSVAL(inbuf,0,outbuf,len); } else { PSSVAL(inbuf,0,outbuf,len); } } }
188
189 #define RW_CVAL(read, inbuf, outbuf, offset) \
190        { if (read) { (outbuf) = CVAL (inbuf,offset); } \
191        else      { SCVAL(inbuf,offset,outbuf); } }
192
193 #define RW_IVAL(read, big_endian, inbuf, outbuf, offset) \
194        { if (read) { (outbuf) = ((big_endian) ? RIVAL(inbuf,offset) : IVAL (inbuf,offset)); } \
195        else      { if (big_endian) { RSIVAL(inbuf,offset,outbuf); } else { SIVAL(inbuf,offset,outbuf); } } }
196
197 #define RW_SVAL(read, big_endian, inbuf, outbuf, offset) \
198        { if (read) { (outbuf) = ((big_endian) ? RSVAL(inbuf,offset) : SVAL (inbuf,offset)); } \
199        else      { if (big_endian) { RSSVAL(inbuf,offset,outbuf); } else { SSVAL(inbuf,offset,outbuf); } } }
200
201 #undef CAREFUL_ALIGNMENT
202
203 /* we know that the 386 can handle misalignment and has the "right"
204    byteorder */
205 #ifdef __i386__
206 #define CAREFUL_ALIGNMENT 0
207 #endif
208
209 #ifndef CAREFUL_ALIGNMENT
210 #define CAREFUL_ALIGNMENT 1
211 #endif
212
213 #define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
214 #define PVAL(buf,pos) ((unsigned)CVAL(buf,pos))
215 #define SCVAL(buf,pos,val) (CVAL(buf,pos) = (val))
216
217
218 #if CAREFUL_ALIGNMENT
219
220 #define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8)
221 #define IVAL(buf,pos) (SVAL(buf,pos)|SVAL(buf,(pos)+2)<<16)
222 #define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
223 #define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16))
224 #define SVALS(buf,pos) ((int16x)SVAL(buf,pos))
225 #define IVALS(buf,pos) ((int32x)IVAL(buf,pos))
226 #define SSVAL(buf,pos,val) SSVALX((buf),(pos),((uint16x)(val)))
227 #define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32x)(val)))
228 #define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16x)(val)))
229 #define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32x)(val)))
230
231 #else /* CAREFUL_ALIGNMENT */
232
233 /* this handles things for architectures like the 386 that can handle
234    alignment errors */
235 /*
236    WARNING: This section is dependent on the length of int16x and int32x
237    being correct
238 */
239
240 /* get single value from an SMB buffer */
241 #define SVAL(buf,pos) (*(uint16x *)((char *)(buf) + (pos)))
242 #define IVAL(buf,pos) (*(uint32x *)((char *)(buf) + (pos)))
243 #define SVALS(buf,pos) (*(int16x *)((char *)(buf) + (pos)))
244 #define IVALS(buf,pos) (*(int32x *)((char *)(buf) + (pos)))
245
246 /* store single value in an SMB buffer */
247 #define SSVAL(buf,pos,val) SVAL(buf,pos)=((uint16x)(val))
248 #define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32x)(val))
249 #define SSVALS(buf,pos,val) SVALS(buf,pos)=((int16x)(val))
250 #define SIVALS(buf,pos,val) IVALS(buf,pos)=((int32x)(val))
251
252 #endif /* CAREFUL_ALIGNMENT */
253
254 /* macros for reading / writing arrays */
255
256 #define SMBMACRO(macro,buf,pos,val,len,size) \
257 { int l; for (l = 0; l < (len); l++) (val)[l] = macro((buf), (pos) + (size)*l); }
258
259 #define SSMBMACRO(macro,buf,pos,val,len,size) \
260 { int l; for (l = 0; l < (len); l++) macro((buf), (pos) + (size)*l, (val)[l]); }
261
262 /* reads multiple data from an SMB buffer */
263 #define PCVAL(buf,pos,val,len) SMBMACRO(CVAL,buf,pos,val,len,1)
264 #define PSVAL(buf,pos,val,len) SMBMACRO(SVAL,buf,pos,val,len,2)
265 #define PIVAL(buf,pos,val,len) SMBMACRO(IVAL,buf,pos,val,len,4)
266 #define PCVALS(buf,pos,val,len) SMBMACRO(CVALS,buf,pos,val,len,1)
267 #define PSVALS(buf,pos,val,len) SMBMACRO(SVALS,buf,pos,val,len,2)
268 #define PIVALS(buf,pos,val,len) SMBMACRO(IVALS,buf,pos,val,len,4)
269
270 /* stores multiple data in an SMB buffer */
271 #define PSCVAL(buf,pos,val,len) SSMBMACRO(SCVAL,buf,pos,val,len,1)
272 #define PSSVAL(buf,pos,val,len) SSMBMACRO(SSVAL,buf,pos,val,len,2)
273 #define PSIVAL(buf,pos,val,len) SSMBMACRO(SIVAL,buf,pos,val,len,4)
274 #define PSCVALS(buf,pos,val,len) SSMBMACRO(SCVALS,buf,pos,val,len,1)
275 #define PSSVALS(buf,pos,val,len) SSMBMACRO(SSVALS,buf,pos,val,len,2)
276 #define PSIVALS(buf,pos,val,len) SSMBMACRO(SIVALS,buf,pos,val,len,4)
277
278
279 /* now the reverse routines - these are used in nmb packets (mostly) */
280 #define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
281 #define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16)))
282
283 #define RSVAL(buf,pos) SREV(SVAL(buf,pos))
284 #define RSVALS(buf,pos) SREV(SVALS(buf,pos))
285 #define RIVAL(buf,pos) IREV(IVAL(buf,pos))
286 #define RIVALS(buf,pos) IREV(IVALS(buf,pos))
287 #define RSSVAL(buf,pos,val) SSVAL(buf,pos,SREV(val))
288 #define RSSVALS(buf,pos,val) SSVALS(buf,pos,SREV(val))
289 #define RSIVAL(buf,pos,val) SIVAL(buf,pos,IREV(val))
290 #define RSIVALS(buf,pos,val) SIVALS(buf,pos,IREV(val))
291
292 /* reads multiple data from an SMB buffer (big-endian) */
293 #define RPSVAL(buf,pos,val,len) SMBMACRO(RSVAL,buf,pos,val,len,2)
294 #define RPIVAL(buf,pos,val,len) SMBMACRO(RIVAL,buf,pos,val,len,4)
295 #define RPSVALS(buf,pos,val,len) SMBMACRO(RSVALS,buf,pos,val,len,2)
296 #define RPIVALS(buf,pos,val,len) SMBMACRO(RIVALS,buf,pos,val,len,4)
297
298 /* stores multiple data in an SMB buffer (big-endian) */
299 #define RPSSVAL(buf,pos,val,len) SSMBMACRO(RSSVAL,buf,pos,val,len,2)
300 #define RPSIVAL(buf,pos,val,len) SSMBMACRO(RSIVAL,buf,pos,val,len,4)
301 #define RPSSVALS(buf,pos,val,len) SSMBMACRO(RSSVALS,buf,pos,val,len,2)
302 #define RPSIVALS(buf,pos,val,len) SSMBMACRO(RSIVALS,buf,pos,val,len,4)
303
304 #define DBG_RW_PCVAL(charmode,string,depth,base,read,inbuf,outbuf,len) \
305        { RW_PCVAL(read,inbuf,outbuf,len) \
306        DEBUG(5,("%s%04x %s: ", \
307              tab_depth(depth), base,string)); \
308     if (charmode) print_asc(5, (unsigned char*)(outbuf), (len)); else \
309        { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%02x ", (outbuf)[idx])); } } \
310        DEBUG(5,("\n")); }
311
312 #define DBG_RW_PSVAL(charmode,string,depth,base,read,big_endian,inbuf,outbuf,len) \
313        { RW_PSVAL(read,big_endian,inbuf,outbuf,len) \
314        DEBUG(5,("%s%04x %s: ", \
315              tab_depth(depth), base,string)); \
316     if (charmode) print_asc(5, (unsigned char*)(outbuf), 2*(len)); else \
317        { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%04x ", (outbuf)[idx])); } } \
318        DEBUG(5,("\n")); }
319
320 #define DBG_RW_PIVAL(charmode,string,depth,base,read,big_endian,inbuf,outbuf,len) \
321        { RW_PIVAL(read,big_endian,inbuf,outbuf,len) \
322        DEBUG(5,("%s%04x %s: ", \
323              tab_depth(depth), base,string)); \
324     if (charmode) print_asc(5, (unsigned char*)(outbuf), 4*(len)); else \
325        { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%08x ", (outbuf)[idx])); } } \
326        DEBUG(5,("\n")); }
327
328 #define DBG_RW_CVAL(string,depth,base,read,inbuf,outbuf) \
329        { RW_CVAL(read,inbuf,outbuf,0) \
330        DEBUG(5,("%s%04x %s: %02x\n", \
331              tab_depth(depth), base, string, outbuf)); }
332
333 #define DBG_RW_SVAL(string,depth,base,read,big_endian,inbuf,outbuf) \
334        { RW_SVAL(read,big_endian,inbuf,outbuf,0) \
335        DEBUG(5,("%s%04x %s: %04x\n", \
336              tab_depth(depth), base, string, outbuf)); }
337
338 #define DBG_RW_IVAL(string,depth,base,read,big_endian,inbuf,outbuf) \
339        { RW_IVAL(read,big_endian,inbuf,outbuf,0) \
340        DEBUG(5,("%s%04x %s: %08x\n", \
341              tab_depth(depth), base, string, outbuf)); }
342
343 #endif /* _BYTEORDER_H */
344
345 void E_P16 (unsigned char *p14, unsigned char *p16);
346 void E_P24 (unsigned char *p21, unsigned char *c8, unsigned char *p24);
347 void D_P16 (unsigned char *p14, unsigned char *in, unsigned char *out);
348 void SMBOWFencrypt (uchar passwd[16], uchar * c8, uchar p24[24]);
349
350 void mdfour (unsigned char *out, unsigned char *in, int n);
351
352
353 /*
354  * base64.c -- base-64 conversion routines.
355  *
356  * For license terms, see the file COPYING in this directory.
357  *
358  * This base 64 encoding is defined in RFC2045 section 6.8,
359  * "Base64 Content-Transfer-Encoding", but lines must not be broken in the
360  * scheme used here.
361  */
362
363 static const char base64digits[] =
364   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
365
366 #define BAD    -1
367 static const char base64val[] = {
368   BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD,
369     BAD,
370   BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD,
371     BAD,
372   BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, 62, BAD, BAD, BAD,
373     63,
374   52, 53, 54, 55, 56, 57, 58, 59, 60, 61, BAD, BAD, BAD, BAD, BAD, BAD,
375   BAD, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
376   15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, BAD, BAD, BAD, BAD, BAD,
377   BAD, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
378   41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, BAD, BAD, BAD, BAD, BAD
379 };
380 #define DECODE64(c)  (isascii(c) ? base64val[c] : BAD)
381
382 void
383 spa_bits_to_base64 (unsigned char *out, const unsigned char *in, int inlen)
384 /* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */
385 {
386   for (; inlen >= 3; inlen -= 3)
387     {
388       *out++ = base64digits[in[0] >> 2];
389       *out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)];
390       *out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
391       *out++ = base64digits[in[2] & 0x3f];
392       in += 3;
393     }
394   if (inlen > 0)
395     {
396       unsigned char fragment;
397
398       *out++ = base64digits[in[0] >> 2];
399       fragment = (in[0] << 4) & 0x30;
400       if (inlen > 1)
401        fragment |= in[1] >> 4;
402       *out++ = base64digits[fragment];
403       *out++ = (inlen < 2) ? '=' : base64digits[(in[1] << 2) & 0x3c];
404       *out++ = '=';
405     }
406   *out = '\0';
407 }
408
409
410 /* The outlength parameter was added by PH, December 2004 */
411
412 int
413 spa_base64_to_bits (char *out, int outlength, const char *in)
414 /* base 64 to raw bytes in quasi-big-endian order, returning count of bytes */
415 {
416   int len = 0;
417   register unsigned char digit1, digit2, digit3, digit4;
418
419   if (in[0] == '+' && in[1] == ' ')
420     in += 2;
421   if (*in == '\r')
422     return (0);
423
424   do
425     {
426       if (len >= outlength)                   /* Added by PH */
427         return (-1);                          /* Added by PH */
428       digit1 = in[0];
429       if (DECODE64 (digit1) == BAD)
430        return (-1);
431       digit2 = in[1];
432       if (DECODE64 (digit2) == BAD)
433        return (-1);
434       digit3 = in[2];
435       if (digit3 != '=' && DECODE64 (digit3) == BAD)
436        return (-1);
437       digit4 = in[3];
438       if (digit4 != '=' && DECODE64 (digit4) == BAD)
439        return (-1);
440       in += 4;
441       *out++ = (DECODE64 (digit1) << 2) | (DECODE64 (digit2) >> 4);
442       ++len;
443       if (digit3 != '=')
444        {
445          if (len >= outlength)                   /* Added by PH */
446            return (-1);                          /* Added by PH */
447          *out++ =
448            ((DECODE64 (digit2) << 4) & 0xf0) | (DECODE64 (digit3) >> 2);
449          ++len;
450          if (digit4 != '=')
451            {
452              if (len >= outlength)                   /* Added by PH */
453                return (-1);                          /* Added by PH */
454              *out++ = ((DECODE64 (digit3) << 6) & 0xc0) | DECODE64 (digit4);
455              ++len;
456            }
457        }
458     }
459   while (*in && *in != '\r' && digit4 != '=');
460
461   return (len);
462 }
463
464
465 #define uchar unsigned char
466
467 static uchar perm1[56] = { 57, 49, 41, 33, 25, 17, 9,
468   1, 58, 50, 42, 34, 26, 18,
469   10, 2, 59, 51, 43, 35, 27,
470   19, 11, 3, 60, 52, 44, 36,
471   63, 55, 47, 39, 31, 23, 15,
472   7, 62, 54, 46, 38, 30, 22,
473   14, 6, 61, 53, 45, 37, 29,
474   21, 13, 5, 28, 20, 12, 4
475 };
476
477 static uchar perm2[48] = { 14, 17, 11, 24, 1, 5,
478   3, 28, 15, 6, 21, 10,
479   23, 19, 12, 4, 26, 8,
480   16, 7, 27, 20, 13, 2,
481   41, 52, 31, 37, 47, 55,
482   30, 40, 51, 45, 33, 48,
483   44, 49, 39, 56, 34, 53,
484   46, 42, 50, 36, 29, 32
485 };
486
487 static uchar perm3[64] = { 58, 50, 42, 34, 26, 18, 10, 2,
488   60, 52, 44, 36, 28, 20, 12, 4,
489   62, 54, 46, 38, 30, 22, 14, 6,
490   64, 56, 48, 40, 32, 24, 16, 8,
491   57, 49, 41, 33, 25, 17, 9, 1,
492   59, 51, 43, 35, 27, 19, 11, 3,
493   61, 53, 45, 37, 29, 21, 13, 5,
494   63, 55, 47, 39, 31, 23, 15, 7
495 };
496
497 static uchar perm4[48] = { 32, 1, 2, 3, 4, 5,
498   4, 5, 6, 7, 8, 9,
499   8, 9, 10, 11, 12, 13,
500   12, 13, 14, 15, 16, 17,
501   16, 17, 18, 19, 20, 21,
502   20, 21, 22, 23, 24, 25,
503   24, 25, 26, 27, 28, 29,
504   28, 29, 30, 31, 32, 1
505 };
506
507 static uchar perm5[32] = { 16, 7, 20, 21,
508   29, 12, 28, 17,
509   1, 15, 23, 26,
510   5, 18, 31, 10,
511   2, 8, 24, 14,
512   32, 27, 3, 9,
513   19, 13, 30, 6,
514   22, 11, 4, 25
515 };
516
517
518 static uchar perm6[64] = { 40, 8, 48, 16, 56, 24, 64, 32,
519   39, 7, 47, 15, 55, 23, 63, 31,
520   38, 6, 46, 14, 54, 22, 62, 30,
521   37, 5, 45, 13, 53, 21, 61, 29,
522   36, 4, 44, 12, 52, 20, 60, 28,
523   35, 3, 43, 11, 51, 19, 59, 27,
524   34, 2, 42, 10, 50, 18, 58, 26,
525   33, 1, 41, 9, 49, 17, 57, 25
526 };
527
528
529 static uchar sc[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
530
531 static uchar sbox[8][4][16] = {
532   {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
533    {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
534    {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
535    {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}},
536
537   {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
538    {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
539    {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
540    {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}},
541
542   {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
543    {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
544    {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
545    {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}},
546
547   {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
548    {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
549    {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
550    {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}},
551
552   {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
553    {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
554    {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
555    {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}},
556
557   {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
558    {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
559    {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
560    {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}},
561
562   {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
563    {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
564    {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
565    {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}},
566
567   {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
568    {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
569    {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
570    {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}
571 };
572
573 static void
574 permute (char *out, char *in, uchar * p, int n)
575 {
576   int i;
577   for (i = 0; i < n; i++)
578     out[i] = in[p[i] - 1];
579 }
580
581 static void
582 lshift (char *d, int count, int n)
583 {
584   char out[64];
585   int i;
586   for (i = 0; i < n; i++)
587     out[i] = d[(i + count) % n];
588   for (i = 0; i < n; i++)
589     d[i] = out[i];
590 }
591
592 static void
593 concat (char *out, char *in1, char *in2, int l1, int l2)
594 {
595   while (l1--)
596     *out++ = *in1++;
597   while (l2--)
598     *out++ = *in2++;
599 }
600
601 static void
602 xor (char *out, char *in1, char *in2, int n)
603 {
604   int i;
605   for (i = 0; i < n; i++)
606     out[i] = in1[i] ^ in2[i];
607 }
608
609 static void
610 dohash (char *out, char *in, char *key, int forw)
611 {
612   int i, j, k;
613   char pk1[56];
614   char c[28];
615   char d[28];
616   char cd[56];
617   char ki[16][48];
618   char pd1[64];
619   char l[32], r[32];
620   char rl[64];
621
622   permute (pk1, key, perm1, 56);
623
624   for (i = 0; i < 28; i++)
625     c[i] = pk1[i];
626   for (i = 0; i < 28; i++)
627     d[i] = pk1[i + 28];
628
629   for (i = 0; i < 16; i++)
630     {
631       lshift (c, sc[i], 28);
632       lshift (d, sc[i], 28);
633
634       concat (cd, c, d, 28, 28);
635       permute (ki[i], cd, perm2, 48);
636     }
637
638   permute (pd1, in, perm3, 64);
639
640   for (j = 0; j < 32; j++)
641     {
642       l[j] = pd1[j];
643       r[j] = pd1[j + 32];
644     }
645
646   for (i = 0; i < 16; i++)
647     {
648       char er[48];
649       char erk[48];
650       char b[8][6];
651       char cb[32];
652       char pcb[32];
653       char r2[32];
654
655       permute (er, r, perm4, 48);
656
657       xor (erk, er, ki[forw ? i : 15 - i], 48);
658
659       for (j = 0; j < 8; j++)
660        for (k = 0; k < 6; k++)
661          b[j][k] = erk[j * 6 + k];
662
663       for (j = 0; j < 8; j++)
664        {
665          int m, n;
666          m = (b[j][0] << 1) | b[j][5];
667
668          n = (b[j][1] << 3) | (b[j][2] << 2) | (b[j][3] << 1) | b[j][4];
669
670          for (k = 0; k < 4; k++)
671            b[j][k] = (sbox[j][m][n] & (1 << (3 - k))) ? 1 : 0;
672        }
673
674       for (j = 0; j < 8; j++)
675        for (k = 0; k < 4; k++)
676          cb[j * 4 + k] = b[j][k];
677       permute (pcb, cb, perm5, 32);
678
679       xor (r2, l, pcb, 32);
680
681       for (j = 0; j < 32; j++)
682        l[j] = r[j];
683
684       for (j = 0; j < 32; j++)
685        r[j] = r2[j];
686     }
687
688   concat (rl, r, l, 32, 32);
689
690   permute (out, rl, perm6, 64);
691 }
692
693 static void
694 str_to_key (unsigned char *str, unsigned char *key)
695 {
696   int i;
697
698   key[0] = str[0] >> 1;
699   key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
700   key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
701   key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
702   key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
703   key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
704   key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
705   key[7] = str[6] & 0x7F;
706   for (i = 0; i < 8; i++)
707     {
708       key[i] = (key[i] << 1);
709     }
710 }
711
712
713 static void
714 smbhash (unsigned char *out, unsigned char *in, unsigned char *key, int forw)
715 {
716   int i;
717   char outb[64];
718   char inb[64];
719   char keyb[64];
720   unsigned char key2[8];
721
722   str_to_key (key, key2);
723
724   for (i = 0; i < 64; i++)
725     {
726       inb[i] = (in[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
727       keyb[i] = (key2[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
728       outb[i] = 0;
729     }
730
731   dohash (outb, inb, keyb, forw);
732
733   for (i = 0; i < 8; i++)
734     {
735       out[i] = 0;
736     }
737
738   for (i = 0; i < 64; i++)
739     {
740       if (outb[i])
741        out[i / 8] |= (1 << (7 - (i % 8)));
742     }
743 }
744
745 void
746 E_P16 (unsigned char *p14, unsigned char *p16)
747 {
748   unsigned char sp8[8] = { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
749   smbhash (p16, sp8, p14, 1);
750   smbhash (p16 + 8, sp8, p14 + 7, 1);
751 }
752
753 void
754 E_P24 (unsigned char *p21, unsigned char *c8, unsigned char *p24)
755 {
756   smbhash (p24, c8, p21, 1);
757   smbhash (p24 + 8, c8, p21 + 7, 1);
758   smbhash (p24 + 16, c8, p21 + 14, 1);
759 }
760
761 void
762 D_P16 (unsigned char *p14, unsigned char *in, unsigned char *out)
763 {
764   smbhash (out, in, p14, 0);
765   smbhash (out + 8, in + 8, p14 + 7, 0);
766 }
767
768 /****************************************************************************
769  Like strncpy but always null terminates. Make sure there is room!
770  The variable n should always be one less than the available size.
771 ****************************************************************************/
772
773 char *
774 StrnCpy (char *dest, const char *src, size_t n)
775 {
776   char *d = dest;
777   if (!dest)
778     return (NULL);
779   if (!src)
780     {
781       *dest = 0;
782       return (dest);
783     }
784   while (n-- && (*d++ = *src++));
785   *d = 0;
786   return (dest);
787 }
788
789 size_t
790 skip_multibyte_char (char c)
791 {
792   /* bogus if to get rid of unused compiler warning */
793   if (c)
794     return 0;
795   else
796     return 0;
797 }
798
799
800 /*******************************************************************
801 safe string copy into a known length string. maxlength does not
802 include the terminating zero.
803 ********************************************************************/
804
805 char *
806 safe_strcpy (char *dest, const char *src, size_t maxlength)
807 {
808   size_t len;
809
810   if (!dest)
811     {
812       DEBUG (0, ("ERROR: NULL dest in safe_strcpy\n"));
813       return NULL;
814     }
815
816   if (!src)
817     {
818       *dest = 0;
819       return dest;
820     }
821
822   len = strlen (src);
823
824   if (len > maxlength)
825     {
826       DEBUG (0, ("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
827                 (int) (len - maxlength), src));
828       len = maxlength;
829     }
830
831   memcpy (dest, src, len);
832   dest[len] = 0;
833   return dest;
834 }
835
836
837 void
838 strupper (char *s)
839 {
840   while (*s)
841     {
842       {
843        size_t skip = skip_multibyte_char (*s);
844        if (skip != 0)
845          s += skip;
846        else
847          {
848            if (islower ((unsigned char)(*s)))
849              *s = toupper (*s);
850            s++;
851          }
852       }
853     }
854 }
855
856
857 /*
858  This implements the X/Open SMB password encryption
859  It takes a password, a 8 byte "crypt key" and puts 24 bytes of
860  encrypted password into p24
861  */
862
863 void
864 spa_smb_encrypt (uchar * passwd, uchar * c8, uchar * p24)
865 {
866   uchar p14[15], p21[21];
867
868   memset (p21, '\0', 21);
869   memset (p14, '\0', 14);
870   StrnCpy ((char *) p14, (char *) passwd, 14);
871
872   strupper ((char *) p14);
873   E_P16 (p14, p21);
874
875   SMBOWFencrypt (p21, c8, p24);
876
877 #ifdef DEBUG_PASSWORD
878   DEBUG (100, ("spa_smb_encrypt: lm#, challenge, response\n"));
879   dump_data (100, (char *) p21, 16);
880   dump_data (100, (char *) c8, 8);
881   dump_data (100, (char *) p24, 24);
882 #endif
883 }
884
885 /* Routines for Windows NT MD4 Hash functions. */
886 static int
887 _my_wcslen (int16x * str)
888 {
889   int len = 0;
890   while (*str++ != 0)
891     len++;
892   return len;
893 }
894
895 /*
896  * Convert a string into an NT UNICODE string.
897  * Note that regardless of processor type
898  * this must be in intel (little-endian)
899  * format.
900  */
901
902 static int
903 _my_mbstowcs (int16x * dst, uchar * src, int len)
904 {
905   int i;
906   int16x val;
907
908   for (i = 0; i < len; i++)
909     {
910       val = *src;
911       SSVAL (dst, 0, val);
912       dst++;
913       src++;
914       if (val == 0)
915        break;
916     }
917   return i;
918 }
919
920 /*
921  * Creates the MD4 Hash of the users password in NT UNICODE.
922  */
923
924 void
925 E_md4hash (uchar * passwd, uchar * p16)
926 {
927   int len;
928   int16x wpwd[129];
929
930   /* Password cannot be longer than 128 characters */
931   len = strlen ((char *) passwd);
932   if (len > 128)
933     len = 128;
934   /* Password must be converted to NT unicode */
935   _my_mbstowcs (wpwd, passwd, len);
936   wpwd[len] = 0;               /* Ensure string is null terminated */
937   /* Calculate length in bytes */
938   len = _my_wcslen (wpwd) * sizeof (int16x);
939
940   mdfour (p16, (unsigned char *) wpwd, len);
941 }
942
943 /* Does both the NT and LM owfs of a user's password */
944 void
945 nt_lm_owf_gen (char *pwd, uchar nt_p16[16], uchar p16[16])
946 {
947   char passwd[130];
948
949   memset (passwd, '\0', 130);
950   safe_strcpy (passwd, pwd, sizeof (passwd) - 1);
951
952   /* Calculate the MD4 hash (NT compatible) of the password */
953   memset (nt_p16, '\0', 16);
954   E_md4hash ((uchar *) passwd, nt_p16);
955
956 #ifdef DEBUG_PASSWORD
957   DEBUG (100, ("nt_lm_owf_gen: pwd, nt#\n"));
958   dump_data (120, passwd, strlen (passwd));
959   dump_data (100, (char *) nt_p16, 16);
960 #endif
961
962   /* Mangle the passwords into Lanman format */
963   passwd[14] = '\0';
964   strupper (passwd);
965
966   /* Calculate the SMB (lanman) hash functions of the password */
967
968   memset (p16, '\0', 16);
969   E_P16 ((uchar *) passwd, (uchar *) p16);
970
971 #ifdef DEBUG_PASSWORD
972   DEBUG (100, ("nt_lm_owf_gen: pwd, lm#\n"));
973   dump_data (120, passwd, strlen (passwd));
974   dump_data (100, (char *) p16, 16);
975 #endif
976   /* clear out local copy of user's password (just being paranoid). */
977   memset (passwd, '\0', sizeof (passwd));
978 }
979
980 /* Does the des encryption from the NT or LM MD4 hash. */
981 void
982 SMBOWFencrypt (uchar passwd[16], uchar * c8, uchar p24[24])
983 {
984   uchar p21[21];
985
986   memset (p21, '\0', 21);
987
988   memcpy (p21, passwd, 16);
989   E_P24 (p21, c8, p24);
990 }
991
992 /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
993 void
994 NTLMSSPOWFencrypt (uchar passwd[8], uchar * ntlmchalresp, uchar p24[24])
995 {
996   uchar p21[21];
997
998   memset (p21, '\0', 21);
999   memcpy (p21, passwd, 8);
1000   memset (p21 + 8, 0xbd, 8);
1001
1002   E_P24 (p21, ntlmchalresp, p24);
1003 #ifdef DEBUG_PASSWORD
1004   DEBUG (100, ("NTLMSSPOWFencrypt: p21, c8, p24\n"));
1005   dump_data (100, (char *) p21, 21);
1006   dump_data (100, (char *) ntlmchalresp, 8);
1007   dump_data (100, (char *) p24, 24);
1008 #endif
1009 }
1010
1011
1012 /* Does the NT MD4 hash then des encryption. */
1013
1014 void
1015 spa_smb_nt_encrypt (uchar * passwd, uchar * c8, uchar * p24)
1016 {
1017   uchar p21[21];
1018
1019   memset (p21, '\0', 21);
1020
1021   E_md4hash (passwd, p21);
1022   SMBOWFencrypt (p21, c8, p24);
1023
1024 #ifdef DEBUG_PASSWORD
1025   DEBUG (100, ("spa_smb_nt_encrypt: nt#, challenge, response\n"));
1026   dump_data (100, (char *) p21, 16);
1027   dump_data (100, (char *) c8, 8);
1028   dump_data (100, (char *) p24, 24);
1029 #endif
1030 }
1031
1032 static uint32x A, B, C, D;
1033
1034 static uint32x
1035 F (uint32x X, uint32x Y, uint32x Z)
1036 {
1037   return (X & Y) | ((~X) & Z);
1038 }
1039
1040 static uint32x
1041 G (uint32x X, uint32x Y, uint32x Z)
1042 {
1043   return (X & Y) | (X & Z) | (Y & Z);
1044 }
1045
1046 static uint32x
1047 H (uint32x X, uint32x Y, uint32x Z)
1048 {
1049   return X ^ Y ^ Z;
1050 }
1051
1052 static uint32x
1053 lshift_a (uint32x x, int s)
1054 {
1055   x &= 0xFFFFFFFF;
1056   return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s));
1057 }
1058
1059 #define ROUND1(a,b,c,d,k,s) a = lshift_a(a + F(b,c,d) + X[k], s)
1060 #define ROUND2(a,b,c,d,k,s) a = lshift_a(a + G(b,c,d) + X[k] + (uint32x)0x5A827999,s)
1061 #define ROUND3(a,b,c,d,k,s) a = lshift_a(a + H(b,c,d) + X[k] + (uint32x)0x6ED9EBA1,s)
1062
1063 /* this applies md4 to 64 byte chunks */
1064 static void
1065 spa_mdfour64 (uint32x * M)
1066 {
1067   int j;
1068   uint32x AA, BB, CC, DD;
1069   uint32x X[16];
1070
1071   for (j = 0; j < 16; j++)
1072     X[j] = M[j];
1073
1074   AA = A;
1075   BB = B;
1076   CC = C;
1077   DD = D;
1078
1079   ROUND1 (A, B, C, D, 0, 3);
1080   ROUND1 (D, A, B, C, 1, 7);
1081   ROUND1 (C, D, A, B, 2, 11);
1082   ROUND1 (B, C, D, A, 3, 19);
1083   ROUND1 (A, B, C, D, 4, 3);
1084   ROUND1 (D, A, B, C, 5, 7);
1085   ROUND1 (C, D, A, B, 6, 11);
1086   ROUND1 (B, C, D, A, 7, 19);
1087   ROUND1 (A, B, C, D, 8, 3);
1088   ROUND1 (D, A, B, C, 9, 7);
1089   ROUND1 (C, D, A, B, 10, 11);
1090   ROUND1 (B, C, D, A, 11, 19);
1091   ROUND1 (A, B, C, D, 12, 3);
1092   ROUND1 (D, A, B, C, 13, 7);
1093   ROUND1 (C, D, A, B, 14, 11);
1094   ROUND1 (B, C, D, A, 15, 19);
1095
1096   ROUND2 (A, B, C, D, 0, 3);
1097   ROUND2 (D, A, B, C, 4, 5);
1098   ROUND2 (C, D, A, B, 8, 9);
1099   ROUND2 (B, C, D, A, 12, 13);
1100   ROUND2 (A, B, C, D, 1, 3);
1101   ROUND2 (D, A, B, C, 5, 5);
1102   ROUND2 (C, D, A, B, 9, 9);
1103   ROUND2 (B, C, D, A, 13, 13);
1104   ROUND2 (A, B, C, D, 2, 3);
1105   ROUND2 (D, A, B, C, 6, 5);
1106   ROUND2 (C, D, A, B, 10, 9);
1107   ROUND2 (B, C, D, A, 14, 13);
1108   ROUND2 (A, B, C, D, 3, 3);
1109   ROUND2 (D, A, B, C, 7, 5);
1110   ROUND2 (C, D, A, B, 11, 9);
1111   ROUND2 (B, C, D, A, 15, 13);
1112
1113   ROUND3 (A, B, C, D, 0, 3);
1114   ROUND3 (D, A, B, C, 8, 9);
1115   ROUND3 (C, D, A, B, 4, 11);
1116   ROUND3 (B, C, D, A, 12, 15);
1117   ROUND3 (A, B, C, D, 2, 3);
1118   ROUND3 (D, A, B, C, 10, 9);
1119   ROUND3 (C, D, A, B, 6, 11);
1120   ROUND3 (B, C, D, A, 14, 15);
1121   ROUND3 (A, B, C, D, 1, 3);
1122   ROUND3 (D, A, B, C, 9, 9);
1123   ROUND3 (C, D, A, B, 5, 11);
1124   ROUND3 (B, C, D, A, 13, 15);
1125   ROUND3 (A, B, C, D, 3, 3);
1126   ROUND3 (D, A, B, C, 11, 9);
1127   ROUND3 (C, D, A, B, 7, 11);
1128   ROUND3 (B, C, D, A, 15, 15);
1129
1130   A += AA;
1131   B += BB;
1132   C += CC;
1133   D += DD;
1134
1135   A &= 0xFFFFFFFF;
1136   B &= 0xFFFFFFFF;
1137   C &= 0xFFFFFFFF;
1138   D &= 0xFFFFFFFF;
1139
1140   for (j = 0; j < 16; j++)
1141     X[j] = 0;
1142 }
1143
1144 static void
1145 copy64 (uint32x * M, unsigned char *in)
1146 {
1147   int i;
1148
1149   for (i = 0; i < 16; i++)
1150     M[i] = (in[i * 4 + 3] << 24) | (in[i * 4 + 2] << 16) |
1151       (in[i * 4 + 1] << 8) | (in[i * 4 + 0] << 0);
1152 }
1153
1154 static void
1155 copy4 (unsigned char *out, uint32x x)
1156 {
1157   out[0] = x & 0xFF;
1158   out[1] = (x >> 8) & 0xFF;
1159   out[2] = (x >> 16) & 0xFF;
1160   out[3] = (x >> 24) & 0xFF;
1161 }
1162
1163 /* produce a md4 message digest from data of length n bytes */
1164 void
1165 mdfour (unsigned char *out, unsigned char *in, int n)
1166 {
1167   unsigned char buf[128];
1168   uint32x M[16];
1169   uint32x b = n * 8;
1170   int i;
1171
1172   A = 0x67452301;
1173   B = 0xefcdab89;
1174   C = 0x98badcfe;
1175   D = 0x10325476;
1176
1177   while (n > 64)
1178     {
1179       copy64 (M, in);
1180       spa_mdfour64 (M);
1181       in += 64;
1182       n -= 64;
1183     }
1184
1185   for (i = 0; i < 128; i++)
1186     buf[i] = 0;
1187   memcpy (buf, in, n);
1188   buf[n] = 0x80;
1189
1190   if (n <= 55)
1191     {
1192       copy4 (buf + 56, b);
1193       copy64 (M, buf);
1194       spa_mdfour64 (M);
1195     }
1196   else
1197     {
1198       copy4 (buf + 120, b);
1199       copy64 (M, buf);
1200       spa_mdfour64 (M);
1201       copy64 (M, buf + 64);
1202       spa_mdfour64 (M);
1203     }
1204
1205   for (i = 0; i < 128; i++)
1206     buf[i] = 0;
1207   copy64 (M, buf);
1208
1209   copy4 (out, A);
1210   copy4 (out + 4, B);
1211   copy4 (out + 8, C);
1212   copy4 (out + 12, D);
1213
1214   A = B = C = D = 0;
1215 }
1216
1217 char versionString[] = "libntlm version 0.21";
1218
1219 /* Utility routines that handle NTLM auth structures. */
1220
1221 /* The [IS]VAL macros are to take care of byte order for non-Intel
1222  * Machines -- I think this file is OK, but it hasn't been tested.
1223  * The other files (the ones stolen from Samba) should be OK.
1224  */
1225
1226
1227 /* I am not crazy about these macros -- they seem to have gotten
1228  * a bit complex.  A new scheme for handling string/buffer fields
1229  * in the structures probably needs to be designed
1230  */
1231
1232 #define spa_bytes_add(ptr, header, buf, count) \
1233 { \
1234 if (buf && count) \
1235   { \
1236   SSVAL(&ptr->header.len,0,count); \
1237   SSVAL(&ptr->header.maxlen,0,count); \
1238   SIVAL(&ptr->header.offset,0,((ptr->buffer - ((uint8x*)ptr)) + ptr->bufIndex)); \
1239   memcpy(ptr->buffer+ptr->bufIndex, buf, count); \
1240   ptr->bufIndex += count; \
1241   } \
1242 else \
1243   { \
1244   ptr->header.len = \
1245   ptr->header.maxlen = 0; \
1246   SIVAL(&ptr->header.offset,0,((ptr->buffer - ((uint8x*)ptr)) + ptr->bufIndex)); \
1247   } \
1248 }
1249
1250 #define spa_string_add(ptr, header, string) \
1251 { \
1252 char *p = string; \
1253 int len = 0; \
1254 if (p) len = strlen(p); \
1255 spa_bytes_add(ptr, header, ((unsigned char*)p), len); \
1256 }
1257
1258 #define spa_unicode_add_string(ptr, header, string) \
1259 { \
1260 char *p = string; \
1261 unsigned char *b = NULL; \
1262 int len = 0; \
1263 if (p) \
1264   { \
1265   len = strlen(p); \
1266   b = strToUnicode(p); \
1267   } \
1268 spa_bytes_add(ptr, header, b, len*2); \
1269 }
1270
1271
1272 #define GetUnicodeString(structPtr, header) \
1273 unicodeToString(((char*)structPtr) + IVAL(&structPtr->header.offset,0) , SVAL(&structPtr->header.len,0)/2)
1274 #define GetString(structPtr, header) \
1275 toString((((char *)structPtr) + IVAL(&structPtr->header.offset,0)), SVAL(&structPtr->header.len,0))
1276 #define DumpBuffer(fp, structPtr, header) \
1277 dumpRaw(fp,((unsigned char*)structPtr)+IVAL(&structPtr->header.offset,0),SVAL(&structPtr->header.len,0))
1278
1279
1280 static void
1281 dumpRaw (FILE * fp, unsigned char *buf, size_t len)
1282 {
1283   int i;
1284
1285   for (i = 0; i < len; ++i)
1286     fprintf (fp, "%02x ", buf[i]);
1287
1288   fprintf (fp, "\n");
1289 }
1290
1291 char *
1292 unicodeToString (char *p, size_t len)
1293 {
1294   int i;
1295   static char buf[1024];
1296
1297   assert (len + 1 < sizeof buf);
1298
1299   for (i = 0; i < len; ++i)
1300     {
1301       buf[i] = *p & 0x7f;
1302       p += 2;
1303     }
1304
1305   buf[i] = '\0';
1306   return buf;
1307 }
1308
1309 static unsigned char *
1310 strToUnicode (char *p)
1311 {
1312   static unsigned char buf[1024];
1313   size_t l = strlen (p);
1314   int i = 0;
1315
1316   assert (l * 2 < sizeof buf);
1317
1318   while (l--)
1319     {
1320       buf[i++] = *p++;
1321       buf[i++] = 0;
1322     }
1323
1324   return buf;
1325 }
1326
1327 static unsigned char *
1328 toString (char *p, size_t len)
1329 {
1330   static unsigned char buf[1024];
1331
1332   assert (len + 1 < sizeof buf);
1333
1334   memcpy (buf, p, len);
1335   buf[len] = 0;
1336   return buf;
1337 }
1338
1339 void
1340 dumpSmbNtlmAuthRequest (FILE * fp, SPAAuthRequest * request)
1341 {
1342   fprintf (fp, "NTLM Request:\n");
1343   fprintf (fp, "      Ident = %s\n", request->ident);
1344   fprintf (fp, "      mType = %d\n", IVAL (&request->msgType, 0));
1345   fprintf (fp, "      Flags = %08x\n", IVAL (&request->flags, 0));
1346   fprintf (fp, "       User = %s\n", GetString (request, user));
1347   fprintf (fp, "     Domain = %s\n", GetString (request, domain));
1348 }
1349
1350 void
1351 dumpSmbNtlmAuthChallenge (FILE * fp, SPAAuthChallenge * challenge)
1352 {
1353   fprintf (fp, "NTLM Challenge:\n");
1354   fprintf (fp, "      Ident = %s\n", challenge->ident);
1355   fprintf (fp, "      mType = %d\n", IVAL (&challenge->msgType, 0));
1356   fprintf (fp, "     Domain = %s\n", GetUnicodeString (challenge, uDomain));
1357   fprintf (fp, "      Flags = %08x\n", IVAL (&challenge->flags, 0));
1358   fprintf (fp, "  Challenge = ");
1359   dumpRaw (fp, challenge->challengeData, 8);
1360 }
1361
1362 void
1363 dumpSmbNtlmAuthResponse (FILE * fp, SPAAuthResponse * response)
1364 {
1365   fprintf (fp, "NTLM Response:\n");
1366   fprintf (fp, "      Ident = %s\n", response->ident);
1367   fprintf (fp, "      mType = %d\n", IVAL (&response->msgType, 0));
1368   fprintf (fp, "     LmResp = ");
1369   DumpBuffer (fp, response, lmResponse);
1370   fprintf (fp, "     NTResp = ");
1371   DumpBuffer (fp, response, ntResponse);
1372   fprintf (fp, "     Domain = %s\n", GetUnicodeString (response, uDomain));
1373   fprintf (fp, "       User = %s\n", GetUnicodeString (response, uUser));
1374   fprintf (fp, "        Wks = %s\n", GetUnicodeString (response, uWks));
1375   fprintf (fp, "       sKey = ");
1376   DumpBuffer (fp, response, sessionKey);
1377   fprintf (fp, "      Flags = %08x\n", IVAL (&response->flags, 0));
1378 }
1379
1380 void
1381 spa_build_auth_request (SPAAuthRequest * request, char *user, char *domain)
1382 {
1383   char *u = strdup (user);
1384   char *p = strchr (u, '@');
1385
1386   if (p)
1387     {
1388       if (!domain)
1389        domain = p + 1;
1390       *p = '\0';
1391     }
1392
1393   request->bufIndex = 0;
1394   memcpy (request->ident, "NTLMSSP\0\0\0", 8);
1395   SIVAL (&request->msgType, 0, 1);
1396   SIVAL (&request->flags, 0, 0x0000b207);      /* have to figure out what these mean */
1397   spa_string_add (request, user, u);
1398   spa_string_add (request, domain, domain);
1399   free (u);
1400 }
1401
1402
1403
1404 void
1405 spa_build_auth_challenge (SPAAuthRequest * request, SPAAuthChallenge * challenge)
1406 {
1407   char chalstr[8];
1408   int i;
1409   int p = (int)getpid();
1410   int random_seed = (int)time(NULL) ^ ((p << 16) | p);
1411
1412   request = request;  /* Added by PH to stop compilers whinging */
1413
1414   /* Ensure challenge data is cleared, in case it isn't all used. This
1415   patch added by PH on suggestion of Russell King */
1416
1417   memset(challenge, 0, sizeof(SPAAuthChallenge));
1418
1419   challenge->bufIndex = 0;
1420   memcpy (challenge->ident, "NTLMSSP\0", 8);
1421   SIVAL (&challenge->msgType, 0, 2);
1422   SIVAL (&challenge->flags, 0, 0x00008201);
1423   SIVAL (&challenge->uDomain.len, 0, 0x0000);
1424   SIVAL (&challenge->uDomain.maxlen, 0, 0x0000);
1425   SIVAL (&challenge->uDomain.offset, 0, 0x00002800);
1426
1427   /* generate eight pseudo random bytes (method ripped from host.c) */
1428
1429   for(i=0;i<8;i++) {
1430     chalstr[i] = (unsigned char)(random_seed >> 16) % 256;
1431     random_seed = (1103515245 - (chalstr[i])) * random_seed + 12345;
1432   };
1433
1434   memcpy(challenge->challengeData,chalstr,8);
1435 }
1436
1437
1438
1439
1440 /* This is the original source of this function, preserved here for reference.
1441 The new version below was re-organized by PH following a patch and some further
1442 suggestions from Mark Lyda to fix the problem that is described at the head of
1443 this module. At the same time, I removed the untidiness in the code below that
1444 involves the "d" and "domain" variables. */
1445
1446 #ifdef NEVER
1447 void
1448 spa_build_auth_response (SPAAuthChallenge * challenge,
1449                         SPAAuthResponse * response, char *user,
1450                         char *password)
1451 {
1452   uint8x lmRespData[24];
1453   uint8x ntRespData[24];
1454   char *d = strdup (GetUnicodeString (challenge, uDomain));
1455   char *domain = d;
1456   char *u = strdup (user);
1457   char *p = strchr (u, '@');
1458
1459   if (p)
1460     {
1461       domain = p + 1;
1462       *p = '\0';
1463     }
1464
1465   spa_smb_encrypt ((uchar *)password, challenge->challengeData, lmRespData);
1466   spa_smb_nt_encrypt ((uchar *)password, challenge->challengeData, ntRespData);
1467
1468   response->bufIndex = 0;
1469   memcpy (response->ident, "NTLMSSP\0\0\0", 8);
1470   SIVAL (&response->msgType, 0, 3);
1471
1472   spa_bytes_add (response, lmResponse, lmRespData, 24);
1473   spa_bytes_add (response, ntResponse, ntRespData, 24);
1474   spa_unicode_add_string (response, uDomain, domain);
1475   spa_unicode_add_string (response, uUser, u);
1476   spa_unicode_add_string (response, uWks, u);
1477   spa_string_add (response, sessionKey, NULL);
1478
1479   response->flags = challenge->flags;
1480
1481   free (d);
1482   free (u);
1483 }
1484 #endif
1485
1486
1487 /* This is the re-organized version (see comments above) */
1488
1489 void
1490 spa_build_auth_response (SPAAuthChallenge * challenge,
1491                         SPAAuthResponse * response, char *user,
1492                         char *password)
1493 {
1494   uint8x lmRespData[24];
1495   uint8x ntRespData[24];
1496   uint32x cf = IVAL(&challenge->flags, 0);
1497   char *u = strdup (user);
1498   char *p = strchr (u, '@');
1499   char *d = NULL;
1500   char *domain;
1501
1502   if (p)
1503     {
1504     domain = p + 1;
1505     *p = '\0';
1506     }
1507
1508   else domain = d = strdup((cf & 0x1)?
1509     (const char *)GetUnicodeString(challenge, uDomain) :
1510     (const char *)GetString(challenge, uDomain));
1511
1512   spa_smb_encrypt ((uchar *)password, challenge->challengeData, lmRespData);
1513   spa_smb_nt_encrypt ((uchar *)password, challenge->challengeData, ntRespData);
1514
1515   response->bufIndex = 0;
1516   memcpy (response->ident, "NTLMSSP\0\0\0", 8);
1517   SIVAL (&response->msgType, 0, 3);
1518
1519   spa_bytes_add (response, lmResponse, lmRespData, (cf & 0x200) ? 24 : 0);
1520   spa_bytes_add (response, ntResponse, ntRespData, (cf & 0x8000) ? 24 : 0);
1521
1522   if (cf & 0x1) {      /* Unicode Text */
1523        spa_unicode_add_string (response, uDomain, domain);
1524        spa_unicode_add_string (response, uUser, u);
1525        spa_unicode_add_string (response, uWks, u);
1526   } else {             /* OEM Text */
1527        spa_string_add (response, uDomain, domain);
1528        spa_string_add (response, uUser, u);
1529        spa_string_add (response, uWks, u);
1530   }
1531
1532   spa_string_add (response, sessionKey, NULL);
1533   response->flags = challenge->flags;
1534
1535   if (d != NULL) free (d);
1536   free (u);
1537 }