2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-1999,
6 * Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
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.
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];
37 for (ind
= 0; ind
< len
; ind
++)
43 index_j
+= hash
[index_i
];
46 hash
[index_i
] = hash
[index_j
];
49 t
= hash
[index_i
] + hash
[index_j
];
50 data
[ind
] = data
[ind
] ^ hash
[t
];
57 /****************************************************************************
58 decrypt data on an rpc pipe
59 ****************************************************************************/
60 static BOOL
decode_ntlmssp_pdu(struct cli_connection
*con
,
62 int len
, int auth_len
)
64 RPC_AUTH_NTLMSSP_CHK chk
;
67 int data_len
= len
- 0x18 - auth_len
- 8;
68 char *reply_data
= prs_data(rdata
, 0x18);
73 ntlmssp_auth_struct
*a
;
74 a
= (ntlmssp_auth_struct
*)cli_conn_get_auth_info(con
);
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
;
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
;
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
))
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
);
134 crc32
= crc32_calc_buffer(data_len
, prs_data(rdata
, 0x18));
135 if (!rpc_auth_ntlmssp_chk(&chk
, crc32
, a
->ntlmssp_seq_num
))
139 a
->ntlmssp_seq_num
++;
144 /****************************************************************************
145 send a request on an rpc pipe.
146 ****************************************************************************/
147 static BOOL
create_ntlmssp_pdu(struct cli_connection
*con
,
149 prs_struct
*data
, int data_start
, int *data_end
,
156 prs_struct auth_verf
;
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
);
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
;
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);
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
),
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);
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
);
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
);
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
);
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
,
295 RPC_IFACE
*abstract
, RPC_IFACE
*transfer
)
299 prs_struct rhdr_auth
;
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
);
314 DEBUG(10,("create_ntlmssp_bind_req: NULL user creds\n"));
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,
349 smb_io_rpc_hdr("hdr" , &hdr
, &rhdr
, 0);
351 if (rhdr
.data
== NULL
|| rhdr_rb
.data
== NULL
) return False
;
354 /*** link rpc header, bind ack and auth responses ***/
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
,
377 BOOL valid_ack
= True
;
379 ntlmssp_auth_struct
*a
;
380 a
= (ntlmssp_auth_struct
*)cli_conn_get_auth_info(con
);
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
))
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
,
411 smb_io_rpc_auth_ntlmssp_chal("", &a
->ntlmssp_chal
, rdata
, 0);
412 if (rdata
->offset
== 0) valid_ack
= False
;
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
,
430 prs_struct
*rhdr_autha
,
431 prs_struct
*auth_resp
)
434 RPC_HDR_AUTHA hdr_autha
;
435 RPC_AUTH_VERIFIER auth_verifier
;
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
,
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,
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
;
467 /*** link rpc header and authentication responses ***/
470 prs_link(NULL
, rhdr
, rhdr_autha
);
471 prs_link(rhdr
, rhdr_autha
, auth_resp
);
472 prs_link(rhdr_autha
, auth_resp
, NULL
);
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
,
491 unsigned char p24
[24];
492 unsigned char lm_owf
[24];
493 unsigned char lm_hash
[16];
494 unsigned char usr_sess_key
[16];
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"));
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
,
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
);
538 for (ind
= 0; ind
< 256; ind
++)
540 a
->ntlmssp_hash
[ind
] = (unsigned char)ind
;
543 for (ind
= 0; ind
< 256; ind
++)
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
);
569 cli_auth_fns cli_ntlmssp_fns
=
571 create_ntlmssp_bind_req
,
572 decode_ntlmssp_bind_resp
,
573 create_ntlmssp_bind_cont
,