29cf77dd55d9a9c7478b4a9869eb345a6ba05324
[tprouty/samba.git] / source3 / libsmb / pwd_cache.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Password cacheing.  obfuscation is planned
5    Copyright (C) Luke Kenneth Casson Leighton 1996-1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 extern int DEBUGLEVEL;
25
26
27 /****************************************************************************
28 initialises a password structure
29 ****************************************************************************/
30 void pwd_init(struct pwd_info *pwd)
31 {
32         ZERO_STRUCT(pwd->password  );
33         ZERO_STRUCT(pwd->smb_lm_pwd);
34         ZERO_STRUCT(pwd->smb_nt_pwd);
35         ZERO_STRUCT(pwd->smb_lm_owf);
36         ZERO_STRUCT(pwd->smb_nt_owf);
37         ZERO_STRUCT(pwd->sess_key  );
38         pwd->nt_owf_len = 0;
39
40         pwd->null_pwd  = True; /* safest option... */
41         pwd->cleartext = False;
42         pwd->crypted   = False;
43 }
44
45 /****************************************************************************
46 returns NULL password flag
47 ****************************************************************************/
48 BOOL pwd_is_nullpwd(const struct pwd_info *pwd)
49 {
50         return pwd->null_pwd;
51 }
52
53 /****************************************************************************
54 de-obfuscates a password
55 ****************************************************************************/
56 static void pwd_deobfuscate(const struct pwd_info *pwd)
57 {
58 }
59
60 /****************************************************************************
61 obfuscates a password
62 ****************************************************************************/
63 static void pwd_obfuscate(const struct pwd_info *pwd)
64 {
65 }
66
67 /****************************************************************************
68 sets the obfuscation key info
69 ****************************************************************************/
70 void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key)
71 {
72 }
73
74 /****************************************************************************
75 compares two passwords.  hmm, not as trivial as expected.  hmm.
76 ****************************************************************************/
77 BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2)
78 {
79         pwd_deobfuscate(pwd1);
80         pwd_deobfuscate(pwd2);
81         if (pwd1->cleartext && pwd2->cleartext)
82         {
83                 if (strequal(pwd1->password, pwd2->password))
84                 {
85                         pwd_obfuscate(pwd1);
86                         pwd_obfuscate(pwd2);
87                         return True;
88                 }
89         }
90         if (pwd1->null_pwd && pwd2->null_pwd)
91         {
92                 pwd_obfuscate(pwd1);
93                 pwd_obfuscate(pwd2);
94                 return True;
95         }
96
97         if (!pwd1->null_pwd  && !pwd2->null_pwd &&
98             !pwd1->cleartext && !pwd2->cleartext)
99         {
100 #ifdef DEBUG_PASSWORD
101                 DEBUG(100,("pwd compare: nt#\n"));
102                 dump_data(100, pwd1->smb_nt_pwd, 16);
103                 dump_data(100, pwd2->smb_nt_pwd, 16);
104 #endif
105                 if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0)
106                 {
107                         pwd_obfuscate(pwd1);
108                         pwd_obfuscate(pwd2);
109                         return True;
110                 }
111 #ifdef DEBUG_PASSWORD
112                 DEBUG(100,("pwd compare: lm#\n"));
113                 dump_data(100, pwd1->smb_lm_pwd, 16);
114                 dump_data(100, pwd2->smb_lm_pwd, 16);
115 #endif
116                 if (memcmp(pwd1->smb_lm_pwd, pwd2->smb_lm_pwd, 16) == 0)
117                 {
118                         pwd_obfuscate(pwd1);
119                         pwd_obfuscate(pwd2);
120                         return True;
121                 }
122         }
123         pwd_obfuscate(pwd1);
124         pwd_obfuscate(pwd2);
125         return False;
126 }
127 /****************************************************************************
128 reads a password
129 ****************************************************************************/
130 void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt)
131 {
132         /* grab a password */
133         char *user_pass;
134
135         pwd_init(pwd);
136
137         user_pass = (char*)getpass(passwd_report);
138
139         if (user_pass == NULL || user_pass[0] == 0)
140         {
141                 pwd_set_nullpwd(pwd);
142         }
143         else if (do_encrypt)
144         {
145                 pwd_make_lm_nt_16(pwd, user_pass);
146         }
147         else
148         {
149                 pwd_set_cleartext(pwd, user_pass);
150         }
151 }
152
153 /****************************************************************************
154  stores a cleartext password
155  ****************************************************************************/
156 void pwd_set_nullpwd(struct pwd_info *pwd)
157 {
158         pwd_init(pwd);
159
160         pwd->cleartext = False;
161         pwd->null_pwd  = True;
162         pwd->crypted   = False;
163 }
164
165 /****************************************************************************
166  stores a cleartext password
167  ****************************************************************************/
168 void pwd_set_cleartext(struct pwd_info *pwd, char *clr)
169 {
170         pwd_init(pwd);
171         fstrcpy(pwd->password, clr);
172         pwd->cleartext = True;
173         pwd->null_pwd  = False;
174         pwd->crypted   = False;
175
176         pwd_obfuscate(pwd);
177 }
178
179 /****************************************************************************
180  gets a cleartext password
181  ****************************************************************************/
182 void pwd_get_cleartext(struct pwd_info *pwd, char *clr)
183 {
184         pwd_deobfuscate(pwd);
185         if (pwd->cleartext)
186         {
187                 fstrcpy(clr, pwd->password);
188         }
189         else
190         {
191                 clr[0] = 0;
192         }
193         pwd_obfuscate(pwd);
194 }
195
196 /****************************************************************************
197  stores lm and nt hashed passwords
198  ****************************************************************************/
199 void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
200 {
201         pwd_init(pwd);
202
203         if (lm_pwd)
204         {
205                 memcpy(pwd->smb_lm_pwd, lm_pwd, 16);
206         }
207         else
208         {
209                 bzero(pwd->smb_lm_pwd, 16);
210         }
211
212         if (nt_pwd)
213         {
214                 memcpy(pwd->smb_nt_pwd, nt_pwd, 16);
215         }
216         else
217         {
218                 bzero(pwd->smb_nt_pwd, 16);
219         }
220
221         pwd->null_pwd  = False;
222         pwd->cleartext = False;
223         pwd->crypted   = False;
224
225         pwd_obfuscate(pwd);
226 }
227
228 /****************************************************************************
229  gets lm and nt hashed passwords
230  ****************************************************************************/
231 void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
232 {
233         pwd_deobfuscate(pwd);
234         if (lm_pwd != NULL)
235         {
236                 memcpy(lm_pwd, pwd->smb_lm_pwd, 16);
237         }
238         if (nt_pwd != NULL)
239         {
240                 memcpy(nt_pwd, pwd->smb_nt_pwd, 16);
241         }
242         pwd_obfuscate(pwd);
243 }
244
245 /****************************************************************************
246  makes lm and nt hashed passwords
247  ****************************************************************************/
248 void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr)
249 {
250         pwd_init(pwd);
251
252         nt_lm_owf_gen(clr, pwd->smb_nt_pwd, pwd->smb_lm_pwd);
253         pwd->null_pwd  = False;
254         pwd->cleartext = False;
255         pwd->crypted = False;
256
257         pwd_obfuscate(pwd);
258 }
259
260 /****************************************************************************
261  makes lm and nt OWF crypts
262  ****************************************************************************/
263 void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
264                 const char *user, const char *server, const char *domain)
265 {
266         uchar kr[16];
267
268         DEBUG(10,("pwd_make_lm_nt_owf2: user %s, srv %s, dom %s\n",
269                 user, server, domain));
270
271         pwd_deobfuscate(pwd);
272
273         SMBgenclientchals(pwd->lm_cli_chal,
274                           pwd->nt_cli_chal,
275                           &pwd->nt_cli_chal_len,
276                           server, domain);
277         
278         ntv2_owf_gen(pwd->smb_nt_pwd, user, domain, kr);
279
280         /* lm # */
281         SMBOWFencrypt_ntv2(kr,
282                            srv_key, 8,
283                            pwd->lm_cli_chal, 8,
284                            pwd->smb_lm_owf);
285         memcpy(&pwd->smb_lm_owf[16], pwd->lm_cli_chal, 8);
286
287         /* nt # */
288         SMBOWFencrypt_ntv2(kr,
289                        srv_key, 8,
290                        pwd->nt_cli_chal, pwd->nt_cli_chal_len,
291                        pwd->smb_nt_owf);
292         memcpy(&pwd->smb_nt_owf[16], pwd->nt_cli_chal, pwd->nt_cli_chal_len);
293         pwd->nt_owf_len = pwd->nt_cli_chal_len + 16;
294
295         SMBsesskeygen_ntv2(kr, pwd->smb_nt_owf, pwd->sess_key);
296
297 #if DEBUG_PASSWORD
298 #endif
299
300 #ifdef DEBUG_PASSWORD
301         DEBUG(100,("server cryptkey: "));
302         dump_data(100, srv_key, 8);
303
304         DEBUG(100,("client lmv2 cryptkey: "));
305         dump_data(100, pwd->lm_cli_chal, 8);
306
307         DEBUG(100,("client ntv2 cryptkey: "));
308         dump_data(100, pwd->nt_cli_chal, pwd->nt_cli_chal_len);
309
310         DEBUG(100,("ntv2_owf_passwd: "));
311         dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len);
312         DEBUG(100,("nt_sess_pwd: "));
313         dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
314
315         DEBUG(100,("lmv2_owf_passwd: "));
316         dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
317         DEBUG(100,("lm_sess_pwd: "));
318         dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
319
320         DEBUG(100,("session key:\n"));
321         dump_data(100, pwd->sess_key, sizeof(pwd->sess_key));
322 #endif
323         pwd->crypted = True;
324
325         pwd_obfuscate(pwd);
326 }
327
328 /****************************************************************************
329  makes lm and nt OWF crypts
330  ****************************************************************************/
331 void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8])
332 {
333         if (pwd->null_pwd)
334         {
335 #ifdef DEBUG_PASSWORD
336                 DEBUG(100,("pwd_make_lm_nt_owf: NULL password\n"));
337 #endif
338                 pwd->nt_owf_len = 0;
339                 return;
340         }
341         pwd_deobfuscate(pwd);
342
343         /* generate 24-byte hashes */
344         SMBOWFencrypt(pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf);
345         SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf);
346         pwd->nt_owf_len = 24;
347
348         SMBsesskeygen_ntv1(pwd->smb_nt_pwd, pwd->smb_nt_owf, pwd->sess_key);
349
350 #ifdef DEBUG_PASSWORD
351         DEBUG(100,("client cryptkey: "));
352         dump_data(100, cryptkey, 8);
353
354         DEBUG(100,("nt_owf_passwd: "));
355         dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len);
356         DEBUG(100,("nt_sess_pwd: "));
357         dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
358
359         DEBUG(100,("lm_owf_passwd: "));
360         dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
361         DEBUG(100,("lm_sess_pwd: "));
362         dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
363
364         DEBUG(100,("session key:\n"));
365         dump_data(100, pwd->sess_key, sizeof(pwd->sess_key));
366 #endif
367
368         pwd->crypted = True;
369
370         pwd_obfuscate(pwd);
371 }
372
373 /****************************************************************************
374  gets lm and nt crypts
375  ****************************************************************************/
376 void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24],
377                                 uchar *nt_owf, size_t *nt_owf_len,
378                                 uchar *sess_key)
379 {
380         if (pwd->null_pwd)
381         {
382 #ifdef DEBUG_PASSWORD
383                 DEBUG(100,("pwd_get_lm_nt_owf: NULL password\n"));
384 #endif
385                 if (nt_owf_len != NULL)
386                 {
387                         *nt_owf_len = 0;
388                 }
389                 return;
390         }
391                 
392         pwd_deobfuscate(pwd);
393         if (lm_owf != NULL)
394         {
395                 memcpy(lm_owf, pwd->smb_lm_owf, 24);
396         }
397         if (nt_owf != NULL)
398         {
399                 memcpy(nt_owf, pwd->smb_nt_owf, pwd->nt_owf_len);
400         }
401         if (sess_key != NULL)
402         {
403                 memcpy(sess_key, pwd->sess_key, 16);
404         }
405         if (nt_owf_len != NULL)
406         {
407                 *nt_owf_len = pwd->nt_owf_len;
408         }
409         pwd_obfuscate(pwd);
410 }
411