preparing for release of alpha-2.6
[Samba/gbeck.git] / source / rpc_client / cli_pipe_ntlmssp.c
blob0fda507a7f2d465e39a495ed9349c658d4968dd5
1 /*
2 * Unix SMB/Netbios implementation.
3 * Version 1.9.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-1999,
6 * Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "includes.h"
24 #include "rpc_parse.h"
25 #include "rpc_client.h"
27 extern int DEBUGLEVEL;
28 extern pstring global_myname;
30 static void NTLMSSPcalc_ap( struct ntlmssp_auth_struct *a, unsigned char *data, int len)
32 unsigned char *hash = a->ntlmssp_hash;
33 unsigned char index_i = hash[256];
34 unsigned char index_j = hash[257];
35 int ind;
37 for (ind = 0; ind < len; ind++)
39 unsigned char tc;
40 unsigned char t;
42 index_i++;
43 index_j += hash[index_i];
45 tc = hash[index_i];
46 hash[index_i] = hash[index_j];
47 hash[index_j] = tc;
49 t = hash[index_i] + hash[index_j];
50 data[ind] = data[ind] ^ hash[t];
53 hash[256] = index_i;
54 hash[257] = index_j;
57 /****************************************************************************
58 decrypt data on an rpc pipe
59 ****************************************************************************/
60 static BOOL decode_ntlmssp_pdu(struct cli_connection *con,
61 prs_struct *rdata,
62 int len, int auth_len)
64 RPC_AUTH_NTLMSSP_CHK chk;
65 uint32 crc32;
67 int data_len = len - 0x18 - auth_len - 8;
68 char *reply_data = prs_data(rdata, 0x18);
70 BOOL auth_verify;
71 BOOL auth_seal ;
73 ntlmssp_auth_struct *a;
74 a = (ntlmssp_auth_struct *)cli_conn_get_auth_info(con);
76 if (a == NULL)
78 return False;
81 auth_verify = IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags,
82 NTLMSSP_NEGOTIATE_SIGN);
83 auth_seal = IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags,
84 NTLMSSP_NEGOTIATE_SEAL);
86 DEBUG(5,("decode_ntlmssp_pdu: len: %d auth_len: %d verify %s seal %s\n",
87 len, auth_len, BOOLSTR(auth_verify), BOOLSTR(auth_seal)));
89 if (reply_data == NULL) return False;
91 if (auth_seal)
93 DEBUG(10,("decode_ntlmssp_pdu: seal\n"));
94 dump_data(100, reply_data, data_len);
95 NTLMSSPcalc_ap(a, (uchar*)reply_data, data_len);
96 dump_data(100, reply_data, data_len);
99 if (auth_verify || auth_seal)
101 RPC_HDR_AUTH rhdr_auth;
102 prs_struct auth_req;
103 prs_init(&auth_req , 0x0, 4, True);
104 prs_append_data(&auth_req,
105 prs_data(rdata, len - auth_len - 8),
107 smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &auth_req, 0);
108 prs_free_data(&auth_req);
110 if (!rpc_hdr_ntlmssp_auth_chk(&rhdr_auth))
112 return False;
116 if (auth_verify)
118 prs_struct auth_verf;
119 char *data = prs_data(rdata, len - auth_len);
120 if (data == NULL) return False;
122 DEBUG(10,("decode_ntlmssp_pdu: verify\n"));
123 dump_data(100, data, auth_len);
124 NTLMSSPcalc_ap(a, (uchar*)(data+4), auth_len - 4);
125 prs_init(&auth_verf, 0x0, 4, True);
126 prs_append_data(&auth_verf, data, 16);
127 smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0);
128 dump_data(100, data, auth_len);
129 prs_free_data(&auth_verf);
132 if (auth_verify)
134 crc32 = crc32_calc_buffer(data_len, prs_data(rdata, 0x18));
135 if (!rpc_auth_ntlmssp_chk(&chk, crc32 , a->ntlmssp_seq_num))
137 return False;
139 a->ntlmssp_seq_num++;
141 return True;
144 /****************************************************************************
145 send a request on an rpc pipe.
146 ****************************************************************************/
147 static BOOL create_ntlmssp_pdu(struct cli_connection *con,
148 uint8 op_num,
149 prs_struct *data, int data_start, int *data_end,
150 prs_struct *dataa,
151 uint8 *flags)
153 prs_struct data_t;
154 prs_struct hdr;
155 prs_struct hdr_auth;
156 prs_struct auth_verf;
157 int data_len;
158 int frag_len;
159 int auth_len;
160 BOOL auth_verify;
161 BOOL auth_seal;
162 uint32 crc32 = 0;
164 struct ntdom_info *nt = cli_conn_get_ntinfo(con);
165 ntlmssp_auth_struct *a;
166 a = (ntlmssp_auth_struct *)cli_conn_get_auth_info(con);
168 if (a == NULL)
170 return False;
173 (*flags) = 0;
175 auth_verify = IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags,
176 NTLMSSP_NEGOTIATE_SIGN);
177 auth_seal = IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags,
178 NTLMSSP_NEGOTIATE_SEAL);
180 auth_len = (auth_verify ? 16 : 0);
181 data_len = data->offset - data_start;
183 if (data_start == 0)
185 (*flags) |= RPC_FLG_FIRST;
188 if (data_len > nt->max_recv_frag)
190 data_len = nt->max_recv_frag - (auth_len + (auth_verify ? 8 : 0) + 0x18);
192 else
194 (*flags) |= RPC_FLG_LAST;
197 (*data_end) += data_len;
199 /* happen to know that NTLMSSP authentication verifier is 16 bytes */
200 frag_len = data_len + auth_len + (auth_verify ? 8 : 0) + 0x18;
202 prs_init(&data_t , 0 , 4, False);
203 prs_init(&hdr , frag_len, 4, False);
204 prs_init(&hdr_auth , 0 , 4, False);
205 prs_init(&auth_verf, auth_len, 4, False);
207 prs_append_data(&data_t, prs_data(data, data_start), data_len);
208 data_t.end = data_t.data_size;
209 data_t.offset = data_t.data_size;
211 create_rpc_request(&hdr, nt->key.vuid, op_num, (*flags),
212 frag_len, auth_len);
214 if (auth_seal)
216 char *buf = prs_data(&data_t, 0);
217 size_t len = prs_buf_len(&data_t);
218 crc32 = crc32_calc_buffer(len, buf);
219 NTLMSSPcalc_ap(a, (uchar*)buf, len);
222 if (auth_seal || auth_verify)
224 RPC_HDR_AUTH rhdr_auth;
226 make_rpc_hdr_auth(&rhdr_auth, 0x0a, 0x06, 0x08, (auth_verify ? 1 : 0));
227 smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &hdr_auth, 0);
230 if (auth_verify)
232 RPC_AUTH_NTLMSSP_CHK chk;
234 make_rpc_auth_ntlmssp_chk(&chk, NTLMSSP_SIGN_VERSION, crc32, a->ntlmssp_seq_num++);
235 smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0);
236 NTLMSSPcalc_ap(a, (uchar*)prs_data(&auth_verf, 4), 12);
239 if (auth_seal || auth_verify)
241 prs_link(NULL , &hdr , &data_t );
242 prs_link(&hdr , &data_t , &hdr_auth );
243 prs_link(&data_t , &hdr_auth , &auth_verf);
244 prs_link(&hdr_auth, &auth_verf, NULL );
246 else
248 prs_link(NULL, &hdr , &data_t);
249 prs_link(&hdr, &data_t, NULL );
252 DEBUG(100,("frag_len: 0x%x data_len: 0x%x data_calc_len: 0x%x\n",
253 frag_len, data_len, prs_buf_len(&data_t)));
255 if (frag_len != prs_buf_len(&hdr))
257 DEBUG(0,("expected fragment length does not match\n"));
259 prs_free_data(&hdr_auth );
260 prs_free_data(&auth_verf);
261 prs_free_data(&hdr );
262 prs_free_data(&data_t );
264 return False;
267 DEBUG(100,("create_ntlmssp_pdu: %d\n", __LINE__));
269 /* this is all a hack */
270 prs_init(dataa, prs_buf_len(&hdr), 4, False);
271 prs_debug_out(dataa, "create_ntlmssp_pdu", 200);
272 prs_buf_copy(dataa->data, &hdr, 0, frag_len);
274 DEBUG(100,("create_ntlmssp_pdu: %d\n", __LINE__));
276 prs_free_data(&hdr_auth );
277 prs_free_data(&auth_verf);
278 prs_free_data(&hdr );
279 prs_free_data(&data_t );
281 return True;
284 /*******************************************************************
285 creates a DCE/RPC bind request
287 - initialises the parse structure.
288 - dynamically allocates the header data structure
289 - caller is expected to free the header data structure once used.
291 ********************************************************************/
292 static BOOL create_ntlmssp_bind_req(struct cli_connection *con,
293 prs_struct *data,
294 uint32 rpc_call_id,
295 RPC_IFACE *abstract, RPC_IFACE *transfer)
297 prs_struct rhdr;
298 prs_struct rhdr_rb;
299 prs_struct rhdr_auth;
300 prs_struct auth_req;
302 RPC_HDR_RB hdr_rb;
303 RPC_HDR hdr;
304 RPC_HDR_AUTH hdr_auth;
305 RPC_AUTH_VERIFIER auth_verifier;
306 RPC_AUTH_NTLMSSP_NEG ntlmssp_neg;
308 struct ntdom_info *nt = cli_conn_get_ntinfo(con);
309 struct ntuser_creds *usr;
310 usr = (struct ntuser_creds*)cli_conn_get_auth_creds(con);
312 if (usr == NULL)
314 DEBUG(10,("create_ntlmssp_bind_req: NULL user creds\n"));
315 return False;
318 prs_init(&rhdr , 0x0, 4, False);
319 prs_init(&rhdr_rb , 0x0, 4, False);
320 prs_init(&rhdr_auth, 0x0, 4, False);
321 prs_init(&auth_req , 0x0, 4, False);
323 /* create the bind request RPC_HDR_RB */
324 make_rpc_hdr_rb(&hdr_rb, 0x1630, 0x1630, nt->key.pid,
325 0x1, nt->key.vuid, 0x1, abstract, transfer);
327 /* stream the bind request data */
328 smb_io_rpc_hdr_rb("", &hdr_rb, &rhdr_rb, 0);
330 make_rpc_hdr_auth(&hdr_auth, 0x0a, 0x06, 0x00, 1);
331 smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &rhdr_auth, 0);
333 make_rpc_auth_verifier(&auth_verifier,
334 "NTLMSSP", NTLMSSP_NEGOTIATE);
336 smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, &auth_req, 0);
338 make_rpc_auth_ntlmssp_neg(&ntlmssp_neg,
339 usr->ntlmssp_flags, global_myname, usr->domain);
341 smb_io_rpc_auth_ntlmssp_neg("ntlmssp_neg", &ntlmssp_neg, &auth_req, 0);
343 /* create the request RPC_HDR */
344 make_rpc_hdr(&hdr, RPC_BIND, 0x0, rpc_call_id,
345 auth_req .offset + rhdr_auth.offset +
346 rhdr_rb.offset + 0x10,
347 auth_req .offset);
349 smb_io_rpc_hdr("hdr" , &hdr , &rhdr, 0);
351 if (rhdr.data == NULL || rhdr_rb.data == NULL) return False;
353 /***/
354 /*** link rpc header, bind ack and auth responses ***/
355 /***/
357 prs_link(NULL , &rhdr , &rhdr_rb );
358 prs_link(&rhdr , &rhdr_rb , &rhdr_auth);
359 prs_link(&rhdr_rb , &rhdr_auth , &auth_req );
360 prs_link(&rhdr_auth, &auth_req , NULL );
362 prs_init(data, prs_buf_len(&rhdr), 4, False);
363 prs_buf_copy(data->data, &rhdr, 0, prs_buf_len(&rhdr));
365 prs_free_data(&rhdr );
366 prs_free_data(&rhdr_rb );
367 prs_free_data(&rhdr_auth);
368 prs_free_data(&auth_req );
370 return cli_conn_set_auth_info(con,
371 (void*)malloc(sizeof(struct ntlmssp_auth_struct)));
374 static BOOL decode_ntlmssp_bind_resp(struct cli_connection *con,
375 prs_struct *rdata)
377 BOOL valid_ack = True;
379 ntlmssp_auth_struct *a;
380 a = (ntlmssp_auth_struct *)cli_conn_get_auth_info(con);
382 if (a == NULL)
384 return False;
387 if (valid_ack)
389 RPC_HDR_AUTH rhdr_auth;
390 smb_io_rpc_hdr_auth("", &rhdr_auth, rdata, 0);
391 if (rdata->offset == 0 ||
392 !rpc_hdr_ntlmssp_auth_chk(&rhdr_auth))
394 valid_ack = False;
397 if (valid_ack)
399 RPC_AUTH_VERIFIER rhdr_verf;
400 smb_io_rpc_auth_verifier("", &rhdr_verf, rdata, 0);
401 if (rdata->offset == 0 ||
402 !rpc_auth_verifier_chk(&rhdr_verf,
403 "NTLMSSP",
404 NTLMSSP_CHALLENGE))
406 valid_ack = False;
409 if (valid_ack)
411 smb_io_rpc_auth_ntlmssp_chal("", &a->ntlmssp_chal, rdata, 0);
412 if (rdata->offset == 0) valid_ack = False;
414 return valid_ack;
417 /*******************************************************************
418 creates a DCE/RPC bind authentication response
420 - initialises the parse structure.
421 - dynamically allocates the header data structure
422 - caller is expected to free the header data structure once used.
424 ********************************************************************/
425 static BOOL create_ntlmssp_rpc_bind_resp(struct pwd_info *pwd,
426 char *domain, char *user_name, char *my_name,
427 uint32 ntlmssp_cli_flgs,
428 uint32 rpc_call_id,
429 prs_struct *rhdr,
430 prs_struct *rhdr_autha,
431 prs_struct *auth_resp)
433 RPC_HDR hdr;
434 RPC_HDR_AUTHA hdr_autha;
435 RPC_AUTH_VERIFIER auth_verifier;
436 uchar lm_owf[24];
437 uchar nt_owf[128];
438 size_t nt_owf_len;
440 make_rpc_hdr_autha(&hdr_autha, 0x1630, 0x1630, 0x0a, 0x06, 0x00);
441 smb_io_rpc_hdr_autha("hdr_autha", &hdr_autha, rhdr_autha, 0);
442 prs_realloc_data(rhdr_autha, rhdr_autha->offset);
444 make_rpc_auth_verifier(&auth_verifier,
445 "NTLMSSP", NTLMSSP_AUTH);
447 smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, auth_resp, 0);
448 prs_realloc_data(auth_resp, auth_resp->offset);
450 pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf, &nt_owf_len);
452 create_ntlmssp_resp(lm_owf, nt_owf, nt_owf_len,
453 domain, user_name, my_name, ntlmssp_cli_flgs,
454 auth_resp);
456 /* create the request RPC_HDR */
457 make_rpc_hdr(&hdr, RPC_BINDRESP, 0x0, rpc_call_id,
458 auth_resp->offset + rhdr_autha->offset + 0x10,
459 auth_resp->offset);
461 smb_io_rpc_hdr("hdr" , &hdr , rhdr, 0);
462 prs_realloc_data(rhdr, rhdr->offset);
464 if (rhdr->data == NULL || rhdr_autha->data == NULL) return False;
466 /***/
467 /*** link rpc header and authentication responses ***/
468 /***/
470 prs_link(NULL , rhdr , rhdr_autha);
471 prs_link(rhdr , rhdr_autha , auth_resp );
472 prs_link(rhdr_autha, auth_resp , NULL );
474 return True;
477 /*******************************************************************
478 creates a DCE/RPC bind continue request
480 - initialises the parse structure.
481 - dynamically allocates the header data structure
482 - caller is expected to free the header data structure once used.
484 ********************************************************************/
485 static BOOL create_ntlmssp_bind_cont(struct cli_connection *con,
486 prs_struct *dataa,
487 uint32 rpc_call_id)
489 BOOL ret = False;
491 unsigned char p24[24];
492 unsigned char lm_owf[24];
493 unsigned char lm_hash[16];
494 unsigned char usr_sess_key[16];
496 prs_struct hdra;
497 prs_struct hdr_autha;
498 prs_struct auth_resp;
500 struct ntuser_creds *usr;
501 ntlmssp_auth_struct *a;
502 a = (ntlmssp_auth_struct *)cli_conn_get_auth_info(con);
503 usr = (struct ntuser_creds*)cli_conn_get_auth_creds(con);
505 DEBUG(5,("Bind RPC Cont\n"));
507 if (a == NULL)
509 return False;
512 prs_init(&hdra , 0x0, 4, False);
513 prs_init(&hdr_autha, 0x0, 4, False);
514 prs_init(&auth_resp, 0x0, 4, False);
516 pwd_make_lm_nt_owf(&usr->pwd, a->ntlmssp_chal.challenge, usr_sess_key);
518 create_ntlmssp_rpc_bind_resp(&usr->pwd, usr->domain,
519 usr->user_name, global_myname,
520 a->ntlmssp_chal.neg_flags,
521 rpc_call_id,
522 &hdra, &hdr_autha, &auth_resp);
524 cli_set_con_usr_sesskey(con, usr_sess_key);
525 pwd_get_lm_nt_owf(&usr->pwd, lm_owf, NULL, NULL);
526 pwd_get_lm_nt_16(&usr->pwd, lm_hash, NULL);
527 NTLMSSPOWFencrypt(lm_hash, lm_owf, p24);
529 unsigned char j = 0;
530 int ind;
531 unsigned char k2[8];
533 memcpy(k2, p24, 5);
534 k2[5] = 0xe5;
535 k2[6] = 0x38;
536 k2[7] = 0xb0;
538 for (ind = 0; ind < 256; ind++)
540 a->ntlmssp_hash[ind] = (unsigned char)ind;
543 for (ind = 0; ind < 256; ind++)
545 unsigned char tc;
547 j += (a->ntlmssp_hash[ind] + k2[ind%8]);
549 tc = a->ntlmssp_hash[ind];
550 a->ntlmssp_hash[ind] = a->ntlmssp_hash[j];
551 a->ntlmssp_hash[j] = tc;
554 a->ntlmssp_hash[256] = 0;
555 a->ntlmssp_hash[257] = 0;
557 ZERO_STRUCT(lm_hash);
559 prs_init(dataa, 0, 4, False);
560 ret = prs_copy(dataa, &hdra);
562 prs_free_data(&hdra);
563 prs_free_data(&hdr_autha);
564 prs_free_data(&auth_resp);
566 return ret;
569 cli_auth_fns cli_ntlmssp_fns =
571 create_ntlmssp_bind_req,
572 decode_ntlmssp_bind_resp,
573 create_ntlmssp_bind_cont,
574 create_ntlmssp_pdu,
575 decode_ntlmssp_pdu