00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "../Build.h"
00041
00042 #ifndef __WIN32__RELEASE__
00043 #include <unistd.h>
00044 #endif
00045 #include <stdlib.h>
00046 #include <stdio.h>
00047 #include <ctype.h>
00048 #include <assert.h>
00049 #include <string.h>
00050 #include "ntlm.h"
00051
00052
00053
00054 #ifndef _BYTEORDER_H
00055 #define _BYTEORDER_H
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 #define RW_PCVAL(read,inbuf,outbuf,len) \
00132 { if (read) { PCVAL (inbuf,0,outbuf,len); } \
00133 else { PSCVAL(inbuf,0,outbuf,len); } }
00134
00135 #define RW_PIVAL(read,big_endian,inbuf,outbuf,len) \
00136 { if (read) { if (big_endian) { RPIVAL(inbuf,0,outbuf,len); } else { PIVAL(inbuf,0,outbuf,len); } } \
00137 else { if (big_endian) { RPSIVAL(inbuf,0,outbuf,len); } else { PSIVAL(inbuf,0,outbuf,len); } } }
00138
00139 #define RW_PSVAL(read,big_endian,inbuf,outbuf,len) \
00140 { if (read) { if (big_endian) { RPSVAL(inbuf,0,outbuf,len); } else { PSVAL(inbuf,0,outbuf,len); } } \
00141 else { if (big_endian) { RPSSVAL(inbuf,0,outbuf,len); } else { PSSVAL(inbuf,0,outbuf,len); } } }
00142
00143 #define RW_CVAL(read, inbuf, outbuf, offset) \
00144 { if (read) { (outbuf) = CVAL (inbuf,offset); } \
00145 else { SCVAL(inbuf,offset,outbuf); } }
00146
00147 #define RW_IVAL(read, big_endian, inbuf, outbuf, offset) \
00148 { if (read) { (outbuf) = ((big_endian) ? RIVAL(inbuf,offset) : IVAL (inbuf,offset)); } \
00149 else { if (big_endian) { RSIVAL(inbuf,offset,outbuf); } else { SIVAL(inbuf,offset,outbuf); } } }
00150
00151 #define RW_SVAL(read, big_endian, inbuf, outbuf, offset) \
00152 { if (read) { (outbuf) = ((big_endian) ? RSVAL(inbuf,offset) : SVAL (inbuf,offset)); } \
00153 else { if (big_endian) { RSSVAL(inbuf,offset,outbuf); } else { SSVAL(inbuf,offset,outbuf); } } }
00154
00155 #undef CAREFUL_ALIGNMENT
00156
00157
00158
00159 #ifdef __i386__
00160 #define CAREFUL_ALIGNMENT 0
00161 #endif
00162
00163 #ifndef CAREFUL_ALIGNMENT
00164 #define CAREFUL_ALIGNMENT 1
00165 #endif
00166
00167 #define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
00168 #define PVAL(buf,pos) ((unsigned)CVAL(buf,pos))
00169 #define SCVAL(buf,pos,val) (CVAL(buf,pos) = (val))
00170
00171
00172 #if CAREFUL_ALIGNMENT
00173
00174 #define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8)
00175 #define IVAL(buf,pos) (SVAL(buf,pos)|SVAL(buf,(pos)+2)<<16)
00176 #define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
00177 #define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16))
00178 #define SVALS(buf,pos) ((int16)SVAL(buf,pos))
00179 #define IVALS(buf,pos) ((int32)IVAL(buf,pos))
00180 #define SSVAL(buf,pos,val) SSVALX((buf),(pos),((uint16)(val)))
00181 #define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32)(val)))
00182 #define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16)(val)))
00183 #define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32)(val)))
00184
00185 #else
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 #define SVAL(buf,pos) (*(uint16 *)((char *)(buf) + (pos)))
00196 #define IVAL(buf,pos) (*(uint32 *)((char *)(buf) + (pos)))
00197 #define SVALS(buf,pos) (*(int16 *)((char *)(buf) + (pos)))
00198 #define IVALS(buf,pos) (*(int32 *)((char *)(buf) + (pos)))
00199
00200
00201 #define SSVAL(buf,pos,val) SVAL(buf,pos)=((uint16)(val))
00202 #define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32)(val))
00203 #define SSVALS(buf,pos,val) SVALS(buf,pos)=((int16)(val))
00204 #define SIVALS(buf,pos,val) IVALS(buf,pos)=((int32)(val))
00205
00206 #endif
00207
00208
00209
00210 #define SMBMACRO(macro,buf,pos,val,len,size) \
00211 { int l; for (l = 0; l < (len); l++) (val)[l] = macro((buf), (pos) + (size)*l); }
00212
00213 #define SSMBMACRO(macro,buf,pos,val,len,size) \
00214 { int l; for (l = 0; l < (len); l++) macro((buf), (pos) + (size)*l, (val)[l]); }
00215
00216
00217 #define PCVAL(buf,pos,val,len) SMBMACRO(CVAL,buf,pos,val,len,1)
00218 #define PSVAL(buf,pos,val,len) SMBMACRO(SVAL,buf,pos,val,len,2)
00219 #define PIVAL(buf,pos,val,len) SMBMACRO(IVAL,buf,pos,val,len,4)
00220 #define PCVALS(buf,pos,val,len) SMBMACRO(CVALS,buf,pos,val,len,1)
00221 #define PSVALS(buf,pos,val,len) SMBMACRO(SVALS,buf,pos,val,len,2)
00222 #define PIVALS(buf,pos,val,len) SMBMACRO(IVALS,buf,pos,val,len,4)
00223
00224
00225 #define PSCVAL(buf,pos,val,len) SSMBMACRO(SCVAL,buf,pos,val,len,1)
00226 #define PSSVAL(buf,pos,val,len) SSMBMACRO(SSVAL,buf,pos,val,len,2)
00227 #define PSIVAL(buf,pos,val,len) SSMBMACRO(SIVAL,buf,pos,val,len,4)
00228 #define PSCVALS(buf,pos,val,len) SSMBMACRO(SCVALS,buf,pos,val,len,1)
00229 #define PSSVALS(buf,pos,val,len) SSMBMACRO(SSVALS,buf,pos,val,len,2)
00230 #define PSIVALS(buf,pos,val,len) SSMBMACRO(SIVALS,buf,pos,val,len,4)
00231
00232
00233
00234 #define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
00235 #define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16)))
00236
00237 #define RSVAL(buf,pos) SREV(SVAL(buf,pos))
00238 #define RSVALS(buf,pos) SREV(SVALS(buf,pos))
00239 #define RIVAL(buf,pos) IREV(IVAL(buf,pos))
00240 #define RIVALS(buf,pos) IREV(IVALS(buf,pos))
00241 #define RSSVAL(buf,pos,val) SSVAL(buf,pos,SREV(val))
00242 #define RSSVALS(buf,pos,val) SSVALS(buf,pos,SREV(val))
00243 #define RSIVAL(buf,pos,val) SIVAL(buf,pos,IREV(val))
00244 #define RSIVALS(buf,pos,val) SIVALS(buf,pos,IREV(val))
00245
00246
00247 #define RPSVAL(buf,pos,val,len) SMBMACRO(RSVAL,buf,pos,val,len,2)
00248 #define RPIVAL(buf,pos,val,len) SMBMACRO(RIVAL,buf,pos,val,len,4)
00249 #define RPSVALS(buf,pos,val,len) SMBMACRO(RSVALS,buf,pos,val,len,2)
00250 #define RPIVALS(buf,pos,val,len) SMBMACRO(RIVALS,buf,pos,val,len,4)
00251
00252
00253 #define RPSSVAL(buf,pos,val,len) SSMBMACRO(RSSVAL,buf,pos,val,len,2)
00254 #define RPSIVAL(buf,pos,val,len) SSMBMACRO(RSIVAL,buf,pos,val,len,4)
00255 #define RPSSVALS(buf,pos,val,len) SSMBMACRO(RSSVALS,buf,pos,val,len,2)
00256 #define RPSIVALS(buf,pos,val,len) SSMBMACRO(RSIVALS,buf,pos,val,len,4)
00257
00258 #define DBG_RW_PCVAL(charmode,string,depth,base,read,inbuf,outbuf,len) \
00259 { RW_PCVAL(read,inbuf,outbuf,len) \
00260 DEBUG(5,("%s%04x %s: ", \
00261 tab_depth(depth), base,string)); \
00262 if (charmode) print_asc(5, (unsigned char*)(outbuf), (len)); else \
00263 { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%02x ", (outbuf)[idx])); } } \
00264 DEBUG(5,("\n")); }
00265
00266 #define DBG_RW_PSVAL(charmode,string,depth,base,read,big_endian,inbuf,outbuf,len) \
00267 { RW_PSVAL(read,big_endian,inbuf,outbuf,len) \
00268 DEBUG(5,("%s%04x %s: ", \
00269 tab_depth(depth), base,string)); \
00270 if (charmode) print_asc(5, (unsigned char*)(outbuf), 2*(len)); else \
00271 { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%04x ", (outbuf)[idx])); } } \
00272 DEBUG(5,("\n")); }
00273
00274 #define DBG_RW_PIVAL(charmode,string,depth,base,read,big_endian,inbuf,outbuf,len) \
00275 { RW_PIVAL(read,big_endian,inbuf,outbuf,len) \
00276 DEBUG(5,("%s%04x %s: ", \
00277 tab_depth(depth), base,string)); \
00278 if (charmode) print_asc(5, (unsigned char*)(outbuf), 4*(len)); else \
00279 { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%08x ", (outbuf)[idx])); } } \
00280 DEBUG(5,("\n")); }
00281
00282 #define DBG_RW_CVAL(string,depth,base,read,inbuf,outbuf) \
00283 { RW_CVAL(read,inbuf,outbuf,0) \
00284 DEBUG(5,("%s%04x %s: %02x\n", \
00285 tab_depth(depth), base, string, outbuf)); }
00286
00287 #define DBG_RW_SVAL(string,depth,base,read,big_endian,inbuf,outbuf) \
00288 { RW_SVAL(read,big_endian,inbuf,outbuf,0) \
00289 DEBUG(5,("%s%04x %s: %04x\n", \
00290 tab_depth(depth), base, string, outbuf)); }
00291
00292 #define DBG_RW_IVAL(string,depth,base,read,big_endian,inbuf,outbuf) \
00293 { RW_IVAL(read,big_endian,inbuf,outbuf,0) \
00294 DEBUG(5,("%s%04x %s: %08x\n", \
00295 tab_depth(depth), base, string, outbuf)); }
00296
00297 #endif
00298
00299
00300
00301
00302
00303
00304
00305
00306 static uint32 A, B, C, D;
00307
00308 static uint32 F(uint32 X, uint32 Y, uint32 Z)
00309 {
00310 return (X&Y) | ((~X)&Z);
00311 }
00312
00313 static uint32 G(uint32 X, uint32 Y, uint32 Z)
00314 {
00315 return (X&Y) | (X&Z) | (Y&Z);
00316 }
00317
00318 static uint32 H(uint32 X, uint32 Y, uint32 Z)
00319 {
00320 return X^Y^Z;
00321 }
00322
00323 static uint32 lshift(uint32 x, int s)
00324 {
00325 x &= 0xFFFFFFFF;
00326 return ((x<<s)&0xFFFFFFFF) | (x>>(32-s));
00327 }
00328
00329 #define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s)
00330 #define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + (uint32)0x5A827999,s)
00331 #define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (uint32)0x6ED9EBA1,s)
00332
00333
00334 static void mdfour64(uint32 *M)
00335 {
00336 int j;
00337 uint32 AA, BB, CC, DD;
00338 uint32 X[16];
00339
00340 for (j=0;j<16;j++)
00341 X[j] = M[j];
00342
00343 AA = A; BB = B; CC = C; DD = D;
00344
00345 ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7);
00346 ROUND1(C,D,A,B, 2, 11); ROUND1(B,C,D,A, 3, 19);
00347 ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7);
00348 ROUND1(C,D,A,B, 6, 11); ROUND1(B,C,D,A, 7, 19);
00349 ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7);
00350 ROUND1(C,D,A,B, 10, 11); ROUND1(B,C,D,A, 11, 19);
00351 ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7);
00352 ROUND1(C,D,A,B, 14, 11); ROUND1(B,C,D,A, 15, 19);
00353
00354 ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5);
00355 ROUND2(C,D,A,B, 8, 9); ROUND2(B,C,D,A, 12, 13);
00356 ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5);
00357 ROUND2(C,D,A,B, 9, 9); ROUND2(B,C,D,A, 13, 13);
00358 ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5);
00359 ROUND2(C,D,A,B, 10, 9); ROUND2(B,C,D,A, 14, 13);
00360 ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5);
00361 ROUND2(C,D,A,B, 11, 9); ROUND2(B,C,D,A, 15, 13);
00362
00363 ROUND3(A,B,C,D, 0, 3); ROUND3(D,A,B,C, 8, 9);
00364 ROUND3(C,D,A,B, 4, 11); ROUND3(B,C,D,A, 12, 15);
00365 ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9);
00366 ROUND3(C,D,A,B, 6, 11); ROUND3(B,C,D,A, 14, 15);
00367 ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9);
00368 ROUND3(C,D,A,B, 5, 11); ROUND3(B,C,D,A, 13, 15);
00369 ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9);
00370 ROUND3(C,D,A,B, 7, 11); ROUND3(B,C,D,A, 15, 15);
00371
00372 A += AA; B += BB; C += CC; D += DD;
00373
00374 A &= 0xFFFFFFFF; B &= 0xFFFFFFFF;
00375 C &= 0xFFFFFFFF; D &= 0xFFFFFFFF;
00376
00377 for (j=0;j<16;j++)
00378 X[j] = 0;
00379 }
00380
00381 static void copy64(uint32 *M, unsigned char *in)
00382 {
00383 int i;
00384
00385 for (i=0;i<16;i++)
00386 M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) |
00387 (in[i*4+1]<<8) | (in[i*4+0]<<0);
00388 }
00389
00390 static void copy4(unsigned char *out,uint32 x)
00391 {
00392 out[0] = x&0xFF;
00393 out[1] = (x>>8)&0xFF;
00394 out[2] = (x>>16)&0xFF;
00395 out[3] = (x>>24)&0xFF;
00396 }
00397
00398
00399 void mdfour(unsigned char *out, unsigned char *in, int n)
00400 {
00401 unsigned char buf[128];
00402 uint32 M[16];
00403 uint32 b = n * 8;
00404 int i;
00405
00406 A = 0x67452301;
00407 B = 0xefcdab89;
00408 C = 0x98badcfe;
00409 D = 0x10325476;
00410
00411 while (n > 64) {
00412 copy64(M, in);
00413 mdfour64(M);
00414 in += 64;
00415 n -= 64;
00416 }
00417
00418 for (i=0;i<128;i++)
00419 buf[i] = 0;
00420 memcpy(buf, in, n);
00421 buf[n] = 0x80;
00422
00423 if (n <= 55) {
00424 copy4(buf+56, b);
00425 copy64(M, buf);
00426 mdfour64(M);
00427 } else {
00428 copy4(buf+120, b);
00429 copy64(M, buf);
00430 mdfour64(M);
00431 copy64(M, buf+64);
00432 mdfour64(M);
00433 }
00434
00435 for (i=0;i<128;i++)
00436 buf[i] = 0;
00437 copy64(M, buf);
00438
00439 copy4(out, A);
00440 copy4(out+4, B);
00441 copy4(out+8, C);
00442 copy4(out+12, D);
00443
00444 A = B = C = D = 0;
00445 }
00446
00447
00448
00449 #define uchar unsigned char
00450 #define int16 signed short
00451
00452 #define False 0
00453 #define True 1
00454
00455 static uchar perm1[56] = {57, 49, 41, 33, 25, 17, 9,
00456 1, 58, 50, 42, 34, 26, 18,
00457 10, 2, 59, 51, 43, 35, 27,
00458 19, 11, 3, 60, 52, 44, 36,
00459 63, 55, 47, 39, 31, 23, 15,
00460 7, 62, 54, 46, 38, 30, 22,
00461 14, 6, 61, 53, 45, 37, 29,
00462 21, 13, 5, 28, 20, 12, 4};
00463
00464 static uchar perm2[48] = {14, 17, 11, 24, 1, 5,
00465 3, 28, 15, 6, 21, 10,
00466 23, 19, 12, 4, 26, 8,
00467 16, 7, 27, 20, 13, 2,
00468 41, 52, 31, 37, 47, 55,
00469 30, 40, 51, 45, 33, 48,
00470 44, 49, 39, 56, 34, 53,
00471 46, 42, 50, 36, 29, 32};
00472
00473 static uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2,
00474 60, 52, 44, 36, 28, 20, 12, 4,
00475 62, 54, 46, 38, 30, 22, 14, 6,
00476 64, 56, 48, 40, 32, 24, 16, 8,
00477 57, 49, 41, 33, 25, 17, 9, 1,
00478 59, 51, 43, 35, 27, 19, 11, 3,
00479 61, 53, 45, 37, 29, 21, 13, 5,
00480 63, 55, 47, 39, 31, 23, 15, 7};
00481
00482 static uchar perm4[48] = { 32, 1, 2, 3, 4, 5,
00483 4, 5, 6, 7, 8, 9,
00484 8, 9, 10, 11, 12, 13,
00485 12, 13, 14, 15, 16, 17,
00486 16, 17, 18, 19, 20, 21,
00487 20, 21, 22, 23, 24, 25,
00488 24, 25, 26, 27, 28, 29,
00489 28, 29, 30, 31, 32, 1};
00490
00491 static uchar perm5[32] = { 16, 7, 20, 21,
00492 29, 12, 28, 17,
00493 1, 15, 23, 26,
00494 5, 18, 31, 10,
00495 2, 8, 24, 14,
00496 32, 27, 3, 9,
00497 19, 13, 30, 6,
00498 22, 11, 4, 25};
00499
00500
00501 static uchar perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32,
00502 39, 7, 47, 15, 55, 23, 63, 31,
00503 38, 6, 46, 14, 54, 22, 62, 30,
00504 37, 5, 45, 13, 53, 21, 61, 29,
00505 36, 4, 44, 12, 52, 20, 60, 28,
00506 35, 3, 43, 11, 51, 19, 59, 27,
00507 34, 2, 42, 10, 50, 18, 58, 26,
00508 33, 1, 41, 9, 49, 17, 57, 25};
00509
00510
00511 static uchar sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
00512
00513 static uchar sbox[8][4][16] = {
00514 {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
00515 {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
00516 {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
00517 {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}},
00518
00519 {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
00520 {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
00521 {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
00522 {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}},
00523
00524 {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
00525 {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
00526 {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
00527 {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}},
00528
00529 {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
00530 {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
00531 {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
00532 {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}},
00533
00534 {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
00535 {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
00536 {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
00537 {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}},
00538
00539 {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
00540 {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
00541 {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
00542 {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}},
00543
00544 {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
00545 {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
00546 {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
00547 {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}},
00548
00549 {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
00550 {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
00551 {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
00552 {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}};
00553
00554 static void permute(char *out, char *in, uchar *p, int n)
00555 {
00556 int i;
00557 for (i=0;i<n;i++)
00558 out[i] = in[p[i]-1];
00559 }
00560
00561 static void l_shift(char *d, int count, int n)
00562 {
00563 char out[64];
00564 int i;
00565 for (i=0;i<n;i++)
00566 out[i] = d[(i+count)%n];
00567 for (i=0;i<n;i++)
00568 d[i] = out[i];
00569 }
00570
00571 static void concat(char *out, char *in1, char *in2, int l1, int l2)
00572 {
00573 while (l1--)
00574 *out++ = *in1++;
00575 while (l2--)
00576 *out++ = *in2++;
00577 }
00578
00579 static void xorfunction(char *out, char *in1, char *in2, int n)
00580 {
00581 int i;
00582 for (i=0;i<n;i++)
00583 out[i] = in1[i] ^ in2[i];
00584 }
00585
00586 static void dohash(char *out, char *in, char *key, int forw)
00587 {
00588 int i, j, k;
00589 char pk1[56];
00590 char c[28];
00591 char d[28];
00592 char cd[56];
00593 char ki[16][48];
00594 char pd1[64];
00595 char l[32], r[32];
00596 char rl[64];
00597
00598 permute(pk1, key, perm1, 56);
00599
00600 for (i=0;i<28;i++)
00601 c[i] = pk1[i];
00602 for (i=0;i<28;i++)
00603 d[i] = pk1[i+28];
00604
00605 for (i=0;i<16;i++) {
00606 l_shift(c, sc[i], 28);
00607 l_shift(d, sc[i], 28);
00608
00609 concat(cd, c, d, 28, 28);
00610 permute(ki[i], cd, perm2, 48);
00611 }
00612
00613 permute(pd1, in, perm3, 64);
00614
00615 for (j=0;j<32;j++) {
00616 l[j] = pd1[j];
00617 r[j] = pd1[j+32];
00618 }
00619
00620 for (i=0;i<16;i++) {
00621 char er[48];
00622 char erk[48];
00623 char b[8][6];
00624 char cb[32];
00625 char pcb[32];
00626 char r2[32];
00627
00628 permute(er, r, perm4, 48);
00629
00630 xorfunction(erk, er, ki[forw ? i : 15 - i], 48);
00631
00632 for (j=0;j<8;j++)
00633 for (k=0;k<6;k++)
00634 b[j][k] = erk[j*6 + k];
00635
00636 for (j=0;j<8;j++) {
00637 int m, n;
00638 m = (b[j][0]<<1) | b[j][5];
00639
00640 n = (b[j][1]<<3) | (b[j][2]<<2) | (b[j][3]<<1) | b[j][4];
00641
00642 for (k=0;k<4;k++)
00643 b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0;
00644 }
00645
00646 for (j=0;j<8;j++)
00647 for (k=0;k<4;k++)
00648 cb[j*4+k] = b[j][k];
00649 permute(pcb, cb, perm5, 32);
00650
00651 xorfunction(r2, l, pcb, 32);
00652
00653 for (j=0;j<32;j++)
00654 l[j] = r[j];
00655
00656 for (j=0;j<32;j++)
00657 r[j] = r2[j];
00658 }
00659
00660 concat(rl, r, l, 32, 32);
00661
00662 permute(out, rl, perm6, 64);
00663 }
00664
00665 static void str_to_key(unsigned char *str,unsigned char *key)
00666 {
00667 int i;
00668
00669 key[0] = str[0]>>1;
00670 key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);
00671 key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);
00672 key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);
00673 key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);
00674 key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);
00675 key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);
00676 key[7] = str[6]&0x7F;
00677 for (i=0;i<8;i++) {
00678 key[i] = (key[i]<<1);
00679 }
00680 }
00681
00682
00683 static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw)
00684 {
00685 int i;
00686 char outb[64];
00687 char inb[64];
00688 char keyb[64];
00689 unsigned char key2[8];
00690
00691 str_to_key(key, key2);
00692
00693 for (i=0;i<64;i++) {
00694 inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
00695 keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
00696 outb[i] = 0;
00697 }
00698
00699 dohash(outb, inb, keyb, forw);
00700
00701 for (i=0;i<8;i++) {
00702 out[i] = 0;
00703 }
00704
00705 for (i=0;i<64;i++) {
00706 if (outb[i])
00707 out[i/8] |= (1<<(7-(i%8)));
00708 }
00709 }
00710
00711 void E_P16(unsigned char *p14,unsigned char *p16)
00712 {
00713 unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
00714 smbhash(p16, sp8, p14, 1);
00715 smbhash(p16+8, sp8, p14+7, 1);
00716 }
00717
00718 void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24)
00719 {
00720 smbhash(p24, c8, p21, 1);
00721 smbhash(p24+8, c8, p21+7, 1);
00722 smbhash(p24+16, c8, p21+14, 1);
00723 }
00724
00725 void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out)
00726 {
00727 smbhash(out, in, p14, 0);
00728 smbhash(out+8, in+8, p14+7, 0);
00729 }
00730
00731 void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out)
00732 {
00733 smbhash(out, in, p14, 1);
00734 smbhash(out+8, in+8, p14+7, 1);
00735 }
00736
00737 void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key)
00738 {
00739 unsigned char buf[8];
00740
00741 smbhash(buf, in, key, 1);
00742 smbhash(out, buf, key+9, 1);
00743 }
00744
00745 void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key)
00746 {
00747 unsigned char buf[8];
00748 static unsigned char key2[8];
00749
00750 smbhash(buf, in, key, 1);
00751 key2[0] = key[7];
00752 smbhash(out, buf, key2, 1);
00753 }
00754
00755 void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw)
00756 {
00757 static unsigned char key2[8];
00758
00759 smbhash(out, in, key, forw);
00760 key2[0] = key[7];
00761 smbhash(out + 8, in + 8, key2, forw);
00762 }
00763
00764 void SamOEMhash( unsigned char *data, unsigned char *key, int val)
00765 {
00766 unsigned char s_box[256];
00767 unsigned char index_i = 0;
00768 unsigned char index_j = 0;
00769 unsigned char j = 0;
00770 int ind;
00771
00772 for (ind = 0; ind < 256; ind++)
00773 {
00774 s_box[ind] = (unsigned char)ind;
00775 }
00776
00777 for( ind = 0; ind < 256; ind++)
00778 {
00779 unsigned char tc;
00780
00781 j += (s_box[ind] + key[ind%16]);
00782
00783 tc = s_box[ind];
00784 s_box[ind] = s_box[j];
00785 s_box[j] = tc;
00786 }
00787 for( ind = 0; ind < (val ? 516 : 16); ind++)
00788 {
00789 unsigned char tc;
00790 unsigned char t;
00791
00792 index_i++;
00793 index_j += s_box[index_i];
00794
00795 tc = s_box[index_i];
00796 s_box[index_i] = s_box[index_j];
00797 s_box[index_j] = tc;
00798
00799 t = s_box[index_i] + s_box[index_j];
00800 data[ind] = data[ind] ^ s_box[t];
00801 }
00802 }
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812 char *StrnCpy(char *dest,const char *src, size_t n)
00813 {
00814 char *d = dest;
00815 if (!dest) return(NULL);
00816 if (!src) {
00817 *dest = 0;
00818 return(dest);
00819 }
00820 while (n-- && (*d++ = *src++)) ;
00821 *d = 0;
00822 return(dest);
00823 }
00824
00825 size_t skip_multibyte_char(char c)
00826 {
00827 return 0;
00828 }
00829
00830
00831
00832
00833
00834
00835 #define DEBUG(a,b) ;
00836 char *safe_strcpy(char *dest,const char *src, size_t maxlength)
00837 {
00838 size_t len;
00839
00840 if (!dest) {
00841 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
00842 return NULL;
00843 }
00844
00845 if (!src) {
00846 *dest = 0;
00847 return dest;
00848 }
00849
00850 len = strlen(src);
00851
00852 if (len > maxlength) {
00853 DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
00854 (int)(len-maxlength), src));
00855 len = maxlength;
00856 }
00857
00858 memcpy(dest, src, len);
00859 dest[len] = 0;
00860 return dest;
00861 }
00862
00863
00864 void strupper(char *s)
00865 {
00866 while (*s)
00867 {
00868 {
00869 size_t skip = skip_multibyte_char( *s );
00870 if( skip != 0 )
00871 s += skip;
00872 else
00873 {
00874 if (islower(*s))
00875 *s = toupper(*s);
00876 s++;
00877 }
00878 }
00879 }
00880 }
00881
00882 extern void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]);
00883
00884
00885
00886
00887
00888
00889
00890 void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
00891 {
00892 uchar p14[15], p21[21];
00893
00894 memset(p21,'\0',21);
00895 memset(p14,'\0',14);
00896 StrnCpy((char *)p14,(char *)passwd,14);
00897
00898 strupper((char *)p14);
00899 E_P16(p14, p21);
00900
00901 SMBOWFencrypt(p21, c8, p24);
00902
00903 #ifdef DEBUG_PASSWORD
00904 DEBUG(100,("SMBencrypt: lm#, challenge, response\n"));
00905 dump_data(100, (char *)p21, 16);
00906 dump_data(100, (char *)c8, 8);
00907 dump_data(100, (char *)p24, 24);
00908 #endif
00909 }
00910
00911
00912 static int _my_wcslen(int16 *str)
00913 {
00914 int len = 0;
00915 while(*str++ != 0)
00916 len++;
00917 return len;
00918 }
00919
00920
00921
00922
00923
00924
00925
00926
00927 static int _my_mbstowcs(int16 *dst, uchar *src, int len)
00928 {
00929 int i;
00930 int16 val;
00931
00932 for(i = 0; i < len; i++) {
00933 val = *src;
00934 SSVAL(dst,0,val);
00935 dst++;
00936 src++;
00937 if(val == 0)
00938 break;
00939 }
00940 return i;
00941 }
00942
00943
00944
00945
00946
00947 void E_md4hash(uchar *passwd, uchar *p16)
00948 {
00949 int len;
00950 int16 wpwd[129];
00951
00952
00953 len = (int) strlen((char *)passwd);
00954 if(len > 128)
00955 len = 128;
00956
00957 _my_mbstowcs(wpwd, passwd, len);
00958 wpwd[len] = 0;
00959
00960 len = _my_wcslen(wpwd) * sizeof(int16);
00961
00962 mdfour(p16, (unsigned char *)wpwd, len);
00963 }
00964
00965
00966 void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16])
00967 {
00968 char passwd[130];
00969
00970 memset(passwd,'\0',130);
00971 safe_strcpy( passwd, pwd, sizeof(passwd)-1);
00972
00973
00974 memset(nt_p16, '\0', 16);
00975 E_md4hash((uchar *)passwd, nt_p16);
00976
00977 #ifdef DEBUG_PASSWORD
00978 DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n"));
00979 dump_data(120, passwd, strlen(passwd));
00980 dump_data(100, (char *)nt_p16, 16);
00981 #endif
00982
00983
00984 passwd[14] = '\0';
00985 strupper(passwd);
00986
00987
00988
00989 memset(p16, '\0', 16);
00990 E_P16((uchar *) passwd, (uchar *)p16);
00991
00992 #ifdef DEBUG_PASSWORD
00993 DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n"));
00994 dump_data(120, passwd, strlen(passwd));
00995 dump_data(100, (char *)p16, 16);
00996 #endif
00997
00998 memset(passwd, '\0', sizeof(passwd));
00999 }
01000
01001
01002 void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24])
01003 {
01004 uchar p21[21];
01005
01006 memset(p21,'\0',21);
01007
01008 memcpy(p21, passwd, 16);
01009 E_P24(p21, c8, p24);
01010 }
01011
01012
01013 void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24])
01014 {
01015 uchar p21[21];
01016
01017 memset(p21,'\0',21);
01018 memcpy(p21, passwd, 8);
01019 memset(p21 + 8, 0xbd, 8);
01020
01021 E_P24(p21, ntlmchalresp, p24);
01022 #ifdef DEBUG_PASSWORD
01023 DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n"));
01024 dump_data(100, (char *)p21, 21);
01025 dump_data(100, (char *)ntlmchalresp, 8);
01026 dump_data(100, (char *)p24, 24);
01027 #endif
01028 }
01029
01030
01031
01032
01033 void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
01034 {
01035 uchar p21[21];
01036
01037 memset(p21,'\0',21);
01038
01039 E_md4hash(passwd, p21);
01040 SMBOWFencrypt(p21, c8, p24);
01041
01042 #ifdef DEBUG_PASSWORD
01043 DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n"));
01044 dump_data(100, (char *)p21, 16);
01045 dump_data(100, (char *)c8, 8);
01046 dump_data(100, (char *)p24, 24);
01047 #endif
01048 }
01049
01050 #if 0
01051
01052 BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode)
01053 {
01054 int new_pw_len = strlen(passwd) * (unicode ? 2 : 1);
01055
01056 if (new_pw_len > 512)
01057 {
01058 DEBUG(0,("make_oem_passwd_hash: new password is too long.\n"));
01059 return False;
01060 }
01061
01062
01063
01064
01065
01066
01067
01068 generate_random_buffer((unsigned char *)data, 516, False);
01069 if (unicode)
01070 {
01071 struni2( &data[512 - new_pw_len], passwd);
01072 }
01073 else
01074 {
01075 fstrcpy( &data[512 - new_pw_len], passwd);
01076 }
01077 SIVAL(data, 512, new_pw_len);
01078
01079 #ifdef DEBUG_PASSWORD
01080 DEBUG(100,("make_oem_passwd_hash\n"));
01081 dump_data(100, data, 516);
01082 #endif
01083 SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, True);
01084
01085 return True;
01086 }
01087
01088 #endif
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118 #define AddBytes(ptr, header, buf, count) \
01119 { \
01120 if (buf && count) \
01121 { \
01122 SSVAL(&ptr->header.len,0,count); \
01123 SSVAL(&ptr->header.maxlen,0,count); \
01124 SIVAL(&ptr->header.offset,0,((ptr->buffer - ((uint8*)ptr)) + ptr->bufIndex)); \
01125 memcpy(ptr->buffer+ptr->bufIndex, buf, count); \
01126 ptr->bufIndex += count; \
01127 } \
01128 else \
01129 { \
01130 ptr->header.len = \
01131 ptr->header.maxlen = 0; \
01132 SIVAL(&ptr->header.offset,0,ptr->bufIndex); \
01133 } \
01134 }
01135
01136 #define AddString(ptr, header, string) \
01137 { \
01138 char *p = string; \
01139 int len = 0; \
01140 if (p) len = strlen(p); \
01141 AddBytes(ptr, header, ((unsigned char*)p), len); \
01142 }
01143
01144 #define AddUnicodeString(ptr, header, string) \
01145 { \
01146 char *p = string; \
01147 unsigned char *b = NULL; \
01148 int len = 0; \
01149 if (p) \
01150 { \
01151 len = strlen(p); \
01152 b = strToUnicode(p); \
01153 } \
01154 AddBytes(ptr, header, b, len*2); \
01155 }
01156
01157
01158 #define GetUnicodeString(structPtr, header) \
01159 unicodeToString(((char*)structPtr) + IVAL(&structPtr->header.offset,0) , SVAL(&structPtr->header.len,0)/2)
01160 #define GetString(structPtr, header) \
01161 toString((((char *)structPtr) + IVAL(&structPtr->header.offset,0)), SVAL(&structPtr->header.len,0))
01162 #define DumpBuffer(fp, structPtr, header) \
01163 dumpRaw(fp,((unsigned char*)structPtr)+IVAL(&structPtr->header.offset,0),SVAL(&structPtr->header.len,0))
01164
01165
01166 static void dumpRaw(FILE *fp, unsigned char *buf, size_t len)
01167 {
01168 int i;
01169
01170 for (i=0; i<(signed int)len; ++i)
01171 printf("%02x ",buf[i]);
01172
01173 printf("\n");
01174 }
01175
01176 static char *unicodeToString(char *p, size_t len)
01177 {
01178 int i;
01179 static char buf[1024];
01180
01181 assert(len+1 < sizeof buf);
01182
01183 for (i=0; i<(signed int)len; ++i)
01184 {
01185 buf[i] = *p & 0x7f;
01186 p += 2;
01187 }
01188
01189 buf[i] = '\0';
01190 return buf;
01191 }
01192
01193 static unsigned char *strToUnicode(char *p)
01194 {
01195 static unsigned char buf[1024];
01196 size_t l = strlen(p);
01197 int i = 0;
01198
01199 assert(l*2 < sizeof buf);
01200
01201 while (l--)
01202 {
01203 buf[i++] = *p++;
01204 buf[i++] = 0;
01205 }
01206
01207 return buf;
01208 }
01209
01210 static unsigned char *toString(char *p, size_t len)
01211 {
01212 static unsigned char buf[1024];
01213
01214 assert(len+1 < sizeof buf);
01215
01216 memcpy(buf,p,len);
01217 buf[len] = 0;
01218 return buf;
01219 }
01220
01221
01222 void BuildAuthRequest(tSmbNtlmAuthRequest *request, long flags, char *host, char *domain)
01223 {
01224 char *h = NULL;
01225 char *p = NULL;
01226
01227
01228 if (host == NULL) host = "";
01229 if (domain == NULL) domain = "";
01230
01231 h = _strdup(host);
01232 p = strchr(h,'@');
01233 if (p)
01234 {
01235 if (!domain)
01236 domain = p+1;
01237 *p = '\0';
01238 }
01239 if (flags ==0) flags = 0x0000b207;
01240 request->bufIndex = 0;
01241 memcpy(request->ident,"NTLMSSP\0\0\0",8);
01242 SIVAL(&request->msgType,0,1);
01243 SIVAL(&request->flags,0,flags);
01244
01245 assert(strlen(host) < 128);
01246 AddString(request,host,h);
01247 assert(strlen(domain) < 128);
01248 AddString(request,domain,domain);
01249 free(h);
01250 }
01251
01252 void buildAuthResponse(tSmbNtlmAuthChallenge *challenge, tSmbNtlmAuthResponse *response, long flags, char *user, char *password, char *domainname, char *host)
01253 {
01254 uint8 lmRespData[24];
01255 uint8 ntRespData[24];
01256 char *u = _strdup(user);
01257 char *p = strchr(u,'@');
01258 char *w = NULL;
01259 char *d = _strdup(GetUnicodeString(challenge,uDomain));
01260 char *domain = d;
01261 if (domainname != NULL) domain = domainname;
01262
01263 if (host == NULL) host = "";
01264 w = _strdup(host);
01265
01266 if (p)
01267 {
01268 domain = p+1;
01269 *p = '\0';
01270 }
01271
01272 SMBencrypt((uchar*)password, challenge->challengeData, lmRespData);
01273 SMBNTencrypt((uchar*)password, challenge->challengeData, ntRespData);
01274
01275 response->bufIndex = 0;
01276 memcpy(response->ident,"NTLMSSP\0\0\0",8);
01277 SIVAL(&response->msgType,0,3);
01278
01279 AddBytes(response,lmResponse,lmRespData,24);
01280 AddBytes(response,ntResponse,ntRespData,24);
01281
01282 assert(strlen(domain) < 128);
01283 AddUnicodeString(response,uDomain,domain);
01284 assert(strlen(u) < 128);
01285 AddUnicodeString(response,uUser,u);
01286 assert(strlen(w) < 128);
01287 AddUnicodeString(response,uWks,w);
01288
01289 AddString(response,sessionKey,NULL);
01290
01291 if (flags != 0) challenge->flags = flags;
01292 response->flags = challenge->flags;
01293
01294 if(d) free(d);
01295 if(u) free(u);
01296 if (w) free(w);
01297 }
01298
01299
01300
01301
01302
01303
01304 void dumpAuthRequest(FILE *fp, tSmbNtlmAuthRequest *request);
01305 void dumpAuthChallenge(FILE *fp, tSmbNtlmAuthChallenge *challenge);
01306 void dumpAuthResponse(FILE *fp, tSmbNtlmAuthResponse *response);
01307
01308 void dumpAuthRequest(FILE *fp, tSmbNtlmAuthRequest *request)
01309 {
01310 printf("NTLM Request:\n");
01311 printf(" Ident = %s\n",request->ident);
01312 printf(" mType = %d\n",IVAL(&request->msgType,0));
01313 printf(" Flags = %08x\n",IVAL(&request->flags,0));
01314 printf(" Host = %s\n",GetString(request,host));
01315 printf(" Domain = %s\n",GetString(request,domain));
01316 }
01317
01318 void dumpAuthChallenge(FILE *fp, tSmbNtlmAuthChallenge *challenge)
01319 {
01320 printf("NTLM Challenge:\n");
01321 printf(" Ident = %s\n",challenge->ident);
01322 printf(" mType = %d\n",IVAL(&challenge->msgType,0));
01323 printf(" Domain = %s\n",GetUnicodeString(challenge,uDomain));
01324 printf(" Flags = %08x\n",IVAL(&challenge->flags,0));
01325 printf(" Challenge = "); dumpRaw(fp, challenge->challengeData,8);
01326 printf(" Uncomplete!! parse optional parameters\n");
01327 }
01328
01329 void dumpAuthResponse(FILE *fp, tSmbNtlmAuthResponse *response)
01330 {
01331 printf("NTLM Response:\n");
01332 printf(" Ident = %s\n",response->ident);
01333 printf(" mType = %d\n",IVAL(&response->msgType,0));
01334 printf(" LmResp = "); DumpBuffer(fp,response,lmResponse);
01335 printf(" NTResp = "); DumpBuffer(fp,response,ntResponse);
01336 printf(" Domain = %s\n",GetUnicodeString(response,uDomain));
01337 printf(" User = %s\n",GetUnicodeString(response,uUser));
01338 printf(" Wks = %s\n",GetUnicodeString(response,uWks));
01339 printf(" sKey = "); DumpBuffer(fp, response,sessionKey);
01340 printf(" Flags = %08x\n",IVAL(&response->flags,0));
01341 }
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364 static const char base64digits[] =
01365 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
01366
01367 #define BAD -1
01368 static const char base64val[] = {
01369 BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
01370 BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
01371 BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD, 62, BAD,BAD,BAD, 63,
01372 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,BAD,BAD, BAD,BAD,BAD,BAD,
01373 BAD, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
01374 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,BAD, BAD,BAD,BAD,BAD,
01375 BAD, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
01376 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,BAD, BAD,BAD,BAD,BAD
01377 };
01378 #define DECODE64(c) (isascii(c) ? base64val[c] : BAD)
01379
01380 void to64frombits(unsigned char *out, const unsigned char *in, int inlen)
01381
01382 {
01383 for (; inlen >= 3; inlen -= 3)
01384 {
01385 *out++ = base64digits[in[0] >> 2];
01386 *out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)];
01387 *out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
01388 *out++ = base64digits[in[2] & 0x3f];
01389 in += 3;
01390 }
01391 if (inlen > 0)
01392 {
01393 unsigned char fragment;
01394
01395 *out++ = base64digits[in[0] >> 2];
01396 fragment = (in[0] << 4) & 0x30;
01397 if (inlen > 1)
01398 fragment |= in[1] >> 4;
01399 *out++ = base64digits[fragment];
01400 *out++ = (inlen < 2) ? '=' : base64digits[(in[1] << 2) & 0x3c];
01401 *out++ = '=';
01402 }
01403 *out = '\0';
01404 }
01405
01406 int from64tobits(char *out, const char *in)
01407
01408 {
01409 int len = 0;
01410 register unsigned char digit1, digit2, digit3, digit4;
01411
01412 if (in[0] == '+' && in[1] == ' ')
01413 in += 2;
01414 if (*in == '\r')
01415 return(0);
01416
01417 do {
01418 digit1 = in[0];
01419 if (DECODE64(digit1) == BAD)
01420 return(-1);
01421 digit2 = in[1];
01422 if (DECODE64(digit2) == BAD)
01423 return(-1);
01424 digit3 = in[2];
01425 if (digit3 != '=' && DECODE64(digit3) == BAD)
01426 return(-1);
01427 digit4 = in[3];
01428 if (digit4 != '=' && DECODE64(digit4) == BAD)
01429 return(-1);
01430 in += 4;
01431 *out++ = (DECODE64(digit1) << 2) | (DECODE64(digit2) >> 4);
01432 ++len;
01433 if (digit3 != '=')
01434 {
01435 *out++ = ((DECODE64(digit2) << 4) & 0xf0) | (DECODE64(digit3) >> 2);
01436 ++len;
01437 if (digit4 != '=')
01438 {
01439 *out++ = ((DECODE64(digit3) << 6) & 0xc0) | DECODE64(digit4);
01440 ++len;
01441 }
01442 }
01443 } while
01444 (*in && *in != '\r' && digit4 != '=');
01445
01446 return (len);
01447 }
01448
01449