2 Unix SMB/CIFS implementation.
4 Copyright (C) Jeremy Allison 2003.
5 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
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.
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.
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.
24 /* Lookup a packet's MID (multiplex id) and figure out it's sequence number */
25 struct outstanding_packet_lookup
{
28 struct outstanding_packet_lookup
*prev
, *next
;
31 /* Store the data for an ongoing trans/trans2/nttrans operation. */
32 struct trans_info_context
{
38 struct smb_basic_signing_context
{
41 struct trans_info_context
*trans_info
;
42 struct outstanding_packet_lookup
*outstanding_packet_list
;
45 static BOOL
store_sequence_for_reply(struct outstanding_packet_lookup
**list
,
46 uint16 mid
, uint32 reply_seq_num
)
48 struct outstanding_packet_lookup
*t
;
50 /* Ensure we only add a mid once. */
51 for (t
= *list
; t
; t
= t
->next
) {
57 t
= smb_xmalloc(sizeof(*t
));
61 t
->reply_seq_num
= reply_seq_num
;
64 * Add to the *start* of the list not the end of the list.
65 * This ensures that the *last* send sequence with this mid
66 * is returned by preference.
67 * This can happen if the mid wraps and one of the early
68 * mid numbers didn't get a reply and is still lurking on
69 * the list. JRA. Found by Fran Fabrizio <fran@cis.uab.edu>.
73 DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n",
74 (unsigned int)reply_seq_num
, (unsigned int)mid
));
78 static BOOL
get_sequence_for_reply(struct outstanding_packet_lookup
**list
,
79 uint16 mid
, uint32
*reply_seq_num
)
81 struct outstanding_packet_lookup
*t
;
83 for (t
= *list
; t
; t
= t
->next
) {
85 *reply_seq_num
= t
->reply_seq_num
;
86 DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n",
87 (unsigned int)t
->reply_seq_num
, (unsigned int)t
->mid
));
88 DLIST_REMOVE(*list
, t
);
96 /***********************************************************
97 SMB signing - Common code before we set a new signing implementation
98 ************************************************************/
100 static BOOL
cli_set_smb_signing_common(struct cli_state
*cli
)
102 if (!cli
->sign_info
.negotiated_smb_signing
103 && !cli
->sign_info
.mandatory_signing
) {
107 if (cli
->sign_info
.doing_signing
) {
111 if (cli
->sign_info
.free_signing_context
)
112 cli
->sign_info
.free_signing_context(&cli
->sign_info
);
114 /* These calls are INCOMPATIBLE with SMB signing */
115 cli
->readbraw_supported
= False
;
116 cli
->writebraw_supported
= False
;
121 /***********************************************************
122 SMB signing - Common code for 'real' implementations
123 ************************************************************/
125 static BOOL
set_smb_signing_real_common(struct smb_sign_info
*si
)
127 if (si
->mandatory_signing
) {
128 DEBUG(5, ("Mandatory SMB signing enabled!\n"));
131 si
->doing_signing
= True
;
132 DEBUG(5, ("SMB signing enabled!\n"));
137 static void mark_packet_signed(char *outbuf
)
140 flags2
= SVAL(outbuf
,smb_flg2
);
141 flags2
|= FLAGS2_SMB_SECURITY_SIGNATURES
;
142 SSVAL(outbuf
,smb_flg2
, flags2
);
145 /***********************************************************
146 SMB signing - NULL implementation - calculate a MAC to send.
147 ************************************************************/
149 static void null_sign_outgoing_message(char *outbuf
, struct smb_sign_info
*si
)
151 /* we can't zero out the sig, as we might be trying to send a
152 session request - which is NBT-level, not SMB level and doesn't
157 /***********************************************************
158 SMB signing - NULL implementation - check a MAC sent by server.
159 ************************************************************/
161 static BOOL
null_check_incoming_message(char *inbuf
, struct smb_sign_info
*si
, BOOL must_be_ok
)
166 /***********************************************************
167 SMB signing - NULL implementation - free signing context
168 ************************************************************/
170 static void null_free_signing_context(struct smb_sign_info
*si
)
176 SMB signing - NULL implementation - setup the MAC key.
178 @note Used as an initialisation only - it will not correctly
179 shut down a real signing mechanism
182 static BOOL
null_set_signing(struct smb_sign_info
*si
)
184 si
->signing_context
= NULL
;
186 si
->sign_outgoing_message
= null_sign_outgoing_message
;
187 si
->check_incoming_message
= null_check_incoming_message
;
188 si
->free_signing_context
= null_free_signing_context
;
194 * Free the signing context
197 static void free_signing_context(struct smb_sign_info
*si
)
199 if (si
->free_signing_context
) {
200 si
->free_signing_context(si
);
201 si
->signing_context
= NULL
;
204 null_set_signing(si
);
208 static BOOL
signing_good(char *inbuf
, struct smb_sign_info
*si
, BOOL good
, uint32 seq
, BOOL must_be_ok
)
212 if (!si
->doing_signing
) {
213 si
->doing_signing
= True
;
216 if (!si
->seen_valid
) {
217 si
->seen_valid
= True
;
221 if (!si
->mandatory_signing
&& !si
->seen_valid
) {
226 /* Non-mandatory signing - just turn off if this is the first bad packet.. */
227 DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and peer\n"
228 "isn't sending correct signatures. Turning off.\n"));
229 si
->negotiated_smb_signing
= False
;
230 si
->allow_smb_signing
= False
;
231 si
->doing_signing
= False
;
232 free_signing_context(si
);
234 } else if (!must_be_ok
) {
235 /* This packet is known to be unsigned */
238 /* Mandatory signing or bad packet after signing started - fail and disconnect. */
240 DEBUG(0, ("signing_good: BAD SIG: seq %u\n", (unsigned int)seq
));
247 /***********************************************************
248 SMB signing - Simple implementation - calculate a MAC on the packet
249 ************************************************************/
251 static void simple_packet_signature(struct smb_basic_signing_context
*data
,
252 const uchar
*buf
, uint32 seq_number
,
253 unsigned char calc_md5_mac
[16])
255 const size_t offset_end_of_sig
= (smb_ss_field
+ 8);
256 unsigned char sequence_buf
[8];
257 struct MD5Context md5_ctx
;
258 unsigned char key_buf
[16];
261 * Firstly put the sequence number into the first 4 bytes.
262 * and zero out the next 4 bytes.
264 * We do this here, to avoid modifying the packet.
267 DEBUG(10,("simple_packet_signature: sequence number %u\n", seq_number
));
269 SIVAL(sequence_buf
, 0, seq_number
);
270 SIVAL(sequence_buf
, 4, 0);
272 /* Calculate the 16 byte MAC - but don't alter the data in the
275 This makes for a bit of fussing about, but it's not too bad.
279 /* intialise with the key */
280 /* NB. When making and verifying SMB signatures, Windows apparently
281 zero-pads the key to 128 bits if it isn't long enough.
282 From Nalin Dahyabhai <nalin@redhat.com> */
283 MD5Update(&md5_ctx
, data
->mac_key
.data
, data
->mac_key
.length
);
284 if (data
->mac_key
.length
< sizeof(key_buf
)) {
285 memset(key_buf
, 0, sizeof(key_buf
));
286 MD5Update(&md5_ctx
, key_buf
, sizeof(key_buf
) - data
->mac_key
.length
);
289 /* copy in the first bit of the SMB header */
290 MD5Update(&md5_ctx
, buf
+ 4, smb_ss_field
- 4);
292 /* copy in the sequence number, instead of the signature */
293 MD5Update(&md5_ctx
, sequence_buf
, sizeof(sequence_buf
));
295 /* copy in the rest of the packet in, skipping the signature */
296 MD5Update(&md5_ctx
, buf
+ offset_end_of_sig
,
297 smb_len(buf
) - (offset_end_of_sig
- 4));
299 /* calculate the MD5 sig */
300 MD5Final(calc_md5_mac
, &md5_ctx
);
304 /***********************************************************
305 SMB signing - Client implementation - send the MAC.
306 ************************************************************/
308 static void client_sign_outgoing_message(char *outbuf
, struct smb_sign_info
*si
)
310 unsigned char calc_md5_mac
[16];
311 struct smb_basic_signing_context
*data
= si
->signing_context
;
314 if (!si
->doing_signing
)
317 /* JRA Paranioa test - we should be able to get rid of this... */
318 if (smb_len(outbuf
) < (smb_ss_field
+ 8 - 4)) {
319 DEBUG(1, ("client_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n",
324 /* mark the packet as signed - BEFORE we sign it...*/
325 mark_packet_signed(outbuf
);
327 if (data
->trans_info
)
328 send_seq_num
= data
->trans_info
->send_seq_num
;
330 send_seq_num
= data
->send_seq_num
;
332 simple_packet_signature(data
, (const unsigned char *)outbuf
, send_seq_num
, calc_md5_mac
);
334 DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n"));
335 dump_data(10, (const char *)calc_md5_mac
, 8);
337 memcpy(&outbuf
[smb_ss_field
], calc_md5_mac
, 8);
339 /* cli->outbuf[smb_ss_field+2]=0;
340 Uncomment this to test if the remote server actually verifies signatures...*/
342 if (data
->trans_info
)
345 data
->send_seq_num
++;
346 store_sequence_for_reply(&data
->outstanding_packet_list
,
347 SVAL(outbuf
,smb_mid
), data
->send_seq_num
);
348 data
->send_seq_num
++;
351 /***********************************************************
352 SMB signing - Client implementation - check a MAC sent by server.
353 ************************************************************/
355 static BOOL
client_check_incoming_message(char *inbuf
, struct smb_sign_info
*si
, BOOL must_be_ok
)
358 uint32 reply_seq_number
;
360 unsigned char calc_md5_mac
[16];
361 unsigned char *server_sent_mac
;
363 struct smb_basic_signing_context
*data
= si
->signing_context
;
365 if (!si
->doing_signing
)
368 if (smb_len(inbuf
) < (smb_ss_field
+ 8 - 4)) {
369 DEBUG(1, ("client_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf
)));
373 if (data
->trans_info
) {
374 reply_seq_number
= data
->trans_info
->reply_seq_num
;
375 } else if (!get_sequence_for_reply(&data
->outstanding_packet_list
,
376 SVAL(inbuf
, smb_mid
), &reply_seq_number
)) {
377 DEBUG(1, ("client_check_incoming_message: failed to get sequence number %u for reply.\n",
378 (unsigned int) SVAL(inbuf
, smb_mid
) ));
382 saved_seq
= reply_seq_number
;
383 simple_packet_signature(data
, (const unsigned char *)inbuf
, reply_seq_number
, calc_md5_mac
);
385 server_sent_mac
= (unsigned char *)&inbuf
[smb_ss_field
];
386 good
= (memcmp(server_sent_mac
, calc_md5_mac
, 8) == 0);
389 DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n"));
390 dump_data(5, (const char *)calc_md5_mac
, 8);
392 DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n"));
393 dump_data(5, (const char *)server_sent_mac
, 8);
397 reply_seq_number
-= 5;
398 for (i
= 0; i
< 10; i
++, reply_seq_number
++) {
399 simple_packet_signature(data
, (const unsigned char *)inbuf
, reply_seq_number
, calc_md5_mac
);
400 if (memcmp(server_sent_mac
, calc_md5_mac
, 8) == 0) {
401 DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches. \
402 We were expecting seq %u\n", reply_seq_number
, saved_seq
));
410 DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number
));
411 dump_data(10, (const char *)server_sent_mac
, 8);
413 return signing_good(inbuf
, si
, good
, saved_seq
, must_be_ok
);
416 /***********************************************************
417 SMB signing - Simple implementation - free signing context
418 ************************************************************/
420 static void simple_free_signing_context(struct smb_sign_info
*si
)
422 struct smb_basic_signing_context
*data
= si
->signing_context
;
423 struct outstanding_packet_lookup
*list
= data
->outstanding_packet_list
;
426 struct outstanding_packet_lookup
*old_head
= list
;
427 DLIST_REMOVE(list
, list
);
431 data_blob_free(&data
->mac_key
);
433 if (data
->trans_info
)
434 SAFE_FREE(data
->trans_info
);
436 SAFE_FREE(si
->signing_context
);
441 /***********************************************************
442 SMB signing - Simple implementation - setup the MAC key.
443 ************************************************************/
445 BOOL
cli_simple_set_signing(struct cli_state
*cli
,
446 const DATA_BLOB user_session_key
,
447 const DATA_BLOB response
)
449 struct smb_basic_signing_context
*data
;
451 if (!user_session_key
.length
)
454 if (!cli_set_smb_signing_common(cli
)) {
458 if (!set_smb_signing_real_common(&cli
->sign_info
)) {
462 data
= smb_xmalloc(sizeof(*data
));
463 memset(data
, '\0', sizeof(*data
));
465 cli
->sign_info
.signing_context
= data
;
467 data
->mac_key
= data_blob(NULL
, response
.length
+ user_session_key
.length
);
469 memcpy(&data
->mac_key
.data
[0], user_session_key
.data
, user_session_key
.length
);
471 DEBUG(10, ("cli_simple_set_signing: user_session_key\n"));
472 dump_data(10, (const char *)user_session_key
.data
, user_session_key
.length
);
474 if (response
.length
) {
475 memcpy(&data
->mac_key
.data
[user_session_key
.length
],response
.data
, response
.length
);
476 DEBUG(10, ("cli_simple_set_signing: response_data\n"));
477 dump_data(10, (const char *)response
.data
, response
.length
);
479 DEBUG(10, ("cli_simple_set_signing: NULL response_data\n"));
482 dump_data_pw("MAC ssession key is:\n", data
->mac_key
.data
, data
->mac_key
.length
);
484 /* Initialise the sequence number */
485 data
->send_seq_num
= 0;
487 /* Initialise the list of outstanding packets */
488 data
->outstanding_packet_list
= NULL
;
490 cli
->sign_info
.sign_outgoing_message
= client_sign_outgoing_message
;
491 cli
->sign_info
.check_incoming_message
= client_check_incoming_message
;
492 cli
->sign_info
.free_signing_context
= simple_free_signing_context
;
497 /***********************************************************
498 Tell client code we are in a multiple trans reply state.
499 We call this after the last outgoing trans2 packet (which
500 has incremented the sequence numbers), so we must save the
501 current mid and sequence number -2.
502 ************************************************************/
504 void cli_signing_trans_start(struct cli_state
*cli
, uint16 mid
)
506 struct smb_basic_signing_context
*data
= cli
->sign_info
.signing_context
;
507 uint32 reply_seq_num
;
509 if (!cli
->sign_info
.doing_signing
|| !data
)
512 data
->trans_info
= smb_xmalloc(sizeof(struct trans_info_context
));
513 ZERO_STRUCTP(data
->trans_info
);
515 /* This ensures the sequence is pulled off the outstanding packet list */
516 if (!get_sequence_for_reply(&data
->outstanding_packet_list
,
517 mid
, &reply_seq_num
)) {
518 DEBUG(1, ("get_sequence_for_reply failed - did we enter the trans signing state without sending a packet?\n"));
522 data
->trans_info
->send_seq_num
= reply_seq_num
- 1;
523 data
->trans_info
->mid
= mid
;
524 data
->trans_info
->reply_seq_num
= reply_seq_num
;
526 DEBUG(10,("cli_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \
527 data->send_seq_num = %u\n",
528 (unsigned int)data
->trans_info
->mid
,
529 (unsigned int)data
->trans_info
->reply_seq_num
,
530 (unsigned int)data
->trans_info
->send_seq_num
,
531 (unsigned int)data
->send_seq_num
));
534 /***********************************************************
535 Tell client code we are out of a multiple trans reply state.
536 ************************************************************/
538 void cli_signing_trans_stop(struct cli_state
*cli
)
540 struct smb_basic_signing_context
*data
= cli
->sign_info
.signing_context
;
542 if (!cli
->sign_info
.doing_signing
|| !data
)
545 DEBUG(10,("cli_signing_trans_stop: freeing mid = %u, reply_seq_num = %u, send_seq_num = %u \
546 data->send_seq_num = %u\n",
547 (unsigned int)data
->trans_info
->mid
,
548 (unsigned int)data
->trans_info
->reply_seq_num
,
549 (unsigned int)data
->trans_info
->send_seq_num
,
550 (unsigned int)data
->send_seq_num
));
552 SAFE_FREE(data
->trans_info
);
553 data
->trans_info
= NULL
;
556 /***********************************************************
557 SMB signing - TEMP implementation - calculate a MAC to send.
558 ************************************************************/
560 static void temp_sign_outgoing_message(char *outbuf
, struct smb_sign_info
*si
)
562 /* mark the packet as signed - BEFORE we sign it...*/
563 mark_packet_signed(outbuf
);
565 /* I wonder what BSRSPYL stands for - but this is what MS
567 memcpy(&outbuf
[smb_ss_field
], "BSRSPYL ", 8);
571 /***********************************************************
572 SMB signing - TEMP implementation - check a MAC sent by server.
573 ************************************************************/
575 static BOOL
temp_check_incoming_message(char *inbuf
, struct smb_sign_info
*si
, BOOL foo
)
580 /***********************************************************
581 SMB signing - TEMP implementation - free signing context
582 ************************************************************/
584 static void temp_free_signing_context(struct smb_sign_info
*si
)
589 /***********************************************************
590 SMB signing - NULL implementation - setup the MAC key.
591 ************************************************************/
593 BOOL
cli_null_set_signing(struct cli_state
*cli
)
595 return null_set_signing(&cli
->sign_info
);
598 /***********************************************************
599 SMB signing - temp implementation - setup the MAC key.
600 ************************************************************/
602 BOOL
cli_temp_set_signing(struct cli_state
*cli
)
604 if (!cli_set_smb_signing_common(cli
)) {
608 cli
->sign_info
.signing_context
= NULL
;
610 cli
->sign_info
.sign_outgoing_message
= temp_sign_outgoing_message
;
611 cli
->sign_info
.check_incoming_message
= temp_check_incoming_message
;
612 cli
->sign_info
.free_signing_context
= temp_free_signing_context
;
617 void cli_free_signing_context(struct cli_state
*cli
)
619 free_signing_context(&cli
->sign_info
);
623 * Sign a packet with the current mechanism
626 void cli_calculate_sign_mac(struct cli_state
*cli
)
628 cli
->sign_info
.sign_outgoing_message(cli
->outbuf
, &cli
->sign_info
);
632 * Check a packet with the current mechanism
633 * @return False if we had an established signing connection
634 * which had a bad checksum, True otherwise.
637 BOOL
cli_check_sign_mac(struct cli_state
*cli
)
639 if (!cli
->sign_info
.check_incoming_message(cli
->inbuf
, &cli
->sign_info
, True
)) {
640 free_signing_context(&cli
->sign_info
);
646 /***********************************************************
647 SMB signing - Server implementation - send the MAC.
648 ************************************************************/
650 static void srv_sign_outgoing_message(char *outbuf
, struct smb_sign_info
*si
)
652 unsigned char calc_md5_mac
[16];
653 struct smb_basic_signing_context
*data
= si
->signing_context
;
654 uint32 send_seq_number
= data
->send_seq_num
;
655 BOOL was_deferred_packet
= False
;
658 if (!si
->doing_signing
) {
662 /* JRA Paranioa test - we should be able to get rid of this... */
663 if (smb_len(outbuf
) < (smb_ss_field
+ 8 - 4)) {
664 DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't send signature on short packet! smb_len = %u\n",
669 /* mark the packet as signed - BEFORE we sign it...*/
670 mark_packet_signed(outbuf
);
672 mid
= SVAL(outbuf
, smb_mid
);
674 /* See if this is a reply for a deferred packet. */
675 was_deferred_packet
= get_sequence_for_reply(&data
->outstanding_packet_list
, mid
, &send_seq_number
);
677 if (data
->trans_info
&& (data
->trans_info
->mid
== mid
)) {
678 /* This is a reply in a trans stream. Use the sequence
679 * number associated with the stream mid. */
680 send_seq_number
= data
->trans_info
->send_seq_num
;
683 simple_packet_signature(data
, (const unsigned char *)outbuf
, send_seq_number
, calc_md5_mac
);
685 DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number
));
686 dump_data(10, (const char *)calc_md5_mac
, 8);
688 memcpy(&outbuf
[smb_ss_field
], calc_md5_mac
, 8);
690 /* cli->outbuf[smb_ss_field+2]=0;
691 Uncomment this to test if the remote client actually verifies signatures...*/
693 /* Don't mess with the sequence number for a deferred packet. */
694 if (was_deferred_packet
) {
698 if (!data
->trans_info
) {
699 /* Always increment if not in a trans stream. */
700 data
->send_seq_num
++;
701 } else if ((data
->trans_info
->send_seq_num
== data
->send_seq_num
) || (data
->trans_info
->mid
!= mid
)) {
702 /* Increment if this is the first reply in a trans stream or a
703 * packet that doesn't belong to this stream (different mid). */
704 data
->send_seq_num
++;
708 /***********************************************************
709 Is an incoming packet an oplock break reply ?
710 ************************************************************/
712 static BOOL
is_oplock_break(char *inbuf
)
714 if (CVAL(inbuf
,smb_com
) != SMBlockingX
)
717 if (!(CVAL(inbuf
,smb_vwv3
) & LOCKING_ANDX_OPLOCK_RELEASE
))
720 DEBUG(10,("is_oplock_break: Packet is oplock break\n"));
724 /***********************************************************
725 SMB signing - Server implementation - check a MAC sent by server.
726 ************************************************************/
728 static BOOL
srv_check_incoming_message(char *inbuf
, struct smb_sign_info
*si
, BOOL must_be_ok
)
731 struct smb_basic_signing_context
*data
= si
->signing_context
;
732 uint32 reply_seq_number
= data
->send_seq_num
;
734 unsigned char calc_md5_mac
[16];
735 unsigned char *server_sent_mac
;
738 if (!si
->doing_signing
)
741 if (smb_len(inbuf
) < (smb_ss_field
+ 8 - 4)) {
742 DEBUG(1, ("srv_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf
)));
746 mid
= SVAL(inbuf
, smb_mid
);
748 /* Is this part of a trans stream ? */
749 if (data
->trans_info
&& (data
->trans_info
->mid
== mid
)) {
750 /* If so we don't increment the sequence. */
751 reply_seq_number
= data
->trans_info
->reply_seq_num
;
753 /* We always increment the sequence number. */
754 data
->send_seq_num
++;
756 /* If we get an asynchronous oplock break reply and there
757 * isn't a reply pending we need to re-sync the sequence
760 if (is_oplock_break(inbuf
)) {
761 DEBUG(10,("srv_check_incoming_message: oplock break at seq num %u\n", data
->send_seq_num
));
762 data
->send_seq_num
++;
766 saved_seq
= reply_seq_number
;
767 simple_packet_signature(data
, (const unsigned char *)inbuf
, reply_seq_number
, calc_md5_mac
);
769 server_sent_mac
= (unsigned char *)&inbuf
[smb_ss_field
];
770 good
= (memcmp(server_sent_mac
, calc_md5_mac
, 8) == 0);
775 DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n",
776 (unsigned int)saved_seq
));
777 dump_data(5, (const char *)calc_md5_mac
, 8);
779 DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n",
780 (unsigned int)reply_seq_number
));
781 dump_data(5, (const char *)server_sent_mac
, 8);
787 reply_seq_number
-= 5;
788 for (i
= 0; i
< 10; i
++, reply_seq_number
++) {
789 simple_packet_signature(data
, (const unsigned char *)inbuf
, reply_seq_number
, calc_md5_mac
);
790 if (memcmp(server_sent_mac
, calc_md5_mac
, 8) == 0) {
791 DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches. \
792 We were expecting seq %u\n", reply_seq_number
, saved_seq
));
800 DEBUG(10, ("srv_check_incoming_message: seq %u: (current is %u) got good SMB signature of\n", (unsigned int)reply_seq_number
, (unsigned int)data
->send_seq_num
));
801 dump_data(10, (const char *)server_sent_mac
, 8);
804 return (signing_good(inbuf
, si
, good
, saved_seq
, must_be_ok
));
807 /***********************************************************
808 SMB signing - server API's.
809 ************************************************************/
811 static struct smb_sign_info srv_sign_info
= {
812 null_sign_outgoing_message
,
813 null_check_incoming_message
,
814 null_free_signing_context
,
822 /***********************************************************
823 Turn signing off or on for oplock break code.
824 ************************************************************/
826 BOOL
srv_oplock_set_signing(BOOL onoff
)
828 BOOL ret
= srv_sign_info
.doing_signing
;
829 srv_sign_info
.doing_signing
= onoff
;
833 /***********************************************************
834 Called to validate an incoming packet from the client.
835 ************************************************************/
837 BOOL
srv_check_sign_mac(char *inbuf
, BOOL must_be_ok
)
839 /* Check if it's a session keepalive. */
840 if(CVAL(inbuf
,0) == SMBkeepalive
)
843 return srv_sign_info
.check_incoming_message(inbuf
, &srv_sign_info
, must_be_ok
);
846 /***********************************************************
847 Called to sign an outgoing packet to the client.
848 ************************************************************/
850 void srv_calculate_sign_mac(char *outbuf
)
852 /* Check if it's a session keepalive. */
853 /* JRA Paranioa test - do we ever generate these in the server ? */
854 if(CVAL(outbuf
,0) == SMBkeepalive
)
857 srv_sign_info
.sign_outgoing_message(outbuf
, &srv_sign_info
);
860 /***********************************************************
861 Called by server to defer an outgoing packet.
862 ************************************************************/
864 void srv_defer_sign_response(uint16 mid
)
866 struct smb_basic_signing_context
*data
;
868 if (!srv_sign_info
.doing_signing
)
871 data
= (struct smb_basic_signing_context
*)srv_sign_info
.signing_context
;
877 * Ensure we only store this mid reply once...
880 if (store_sequence_for_reply(&data
->outstanding_packet_list
, mid
, data
->send_seq_num
)) {
881 data
->send_seq_num
++;
885 /***********************************************************
886 Called to remove sequence records when a deferred packet is
887 cancelled by mid. This should never find one....
888 ************************************************************/
890 void srv_cancel_sign_response(uint16 mid
)
892 struct smb_basic_signing_context
*data
;
895 if (!srv_sign_info
.doing_signing
)
898 data
= (struct smb_basic_signing_context
*)srv_sign_info
.signing_context
;
903 DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid
));
905 while (get_sequence_for_reply(&data
->outstanding_packet_list
, mid
, &dummy_seq
))
909 /***********************************************************
910 Called by server negprot when signing has been negotiated.
911 ************************************************************/
913 void srv_set_signing_negotiated(void)
915 srv_sign_info
.allow_smb_signing
= True
;
916 srv_sign_info
.negotiated_smb_signing
= True
;
917 if (lp_server_signing() == Required
)
918 srv_sign_info
.mandatory_signing
= True
;
920 srv_sign_info
.sign_outgoing_message
= temp_sign_outgoing_message
;
921 srv_sign_info
.check_incoming_message
= temp_check_incoming_message
;
922 srv_sign_info
.free_signing_context
= temp_free_signing_context
;
925 /***********************************************************
926 Returns whether signing is active. We can't use sendfile or raw
927 reads/writes if it is.
928 ************************************************************/
930 BOOL
srv_is_signing_active(void)
932 return srv_sign_info
.doing_signing
;
936 /***********************************************************
937 Returns whether signing is negotiated. We can't use it unless it was
939 ************************************************************/
941 BOOL
srv_is_signing_negotiated(void)
943 return srv_sign_info
.negotiated_smb_signing
;
946 /***********************************************************
947 Returns whether signing is actually happening
948 ************************************************************/
950 BOOL
srv_signing_started(void)
952 struct smb_basic_signing_context
*data
;
954 if (!srv_sign_info
.doing_signing
) {
958 data
= (struct smb_basic_signing_context
*)srv_sign_info
.signing_context
;
962 if (data
->send_seq_num
== 0) {
970 /***********************************************************
971 Tell server code we are in a multiple trans reply state.
972 ************************************************************/
974 void srv_signing_trans_start(uint16 mid
)
976 struct smb_basic_signing_context
*data
;
978 if (!srv_sign_info
.doing_signing
)
981 data
= (struct smb_basic_signing_context
*)srv_sign_info
.signing_context
;
985 data
->trans_info
= smb_xmalloc(sizeof(struct trans_info_context
));
986 ZERO_STRUCTP(data
->trans_info
);
988 data
->trans_info
->reply_seq_num
= data
->send_seq_num
-1;
989 data
->trans_info
->mid
= mid
;
990 data
->trans_info
->send_seq_num
= data
->send_seq_num
;
992 DEBUG(10,("srv_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \
993 data->send_seq_num = %u\n",
995 (unsigned int)data
->trans_info
->reply_seq_num
,
996 (unsigned int)data
->trans_info
->send_seq_num
,
997 (unsigned int)data
->send_seq_num
));
1000 /***********************************************************
1001 Tell server code we are out of a multiple trans reply state.
1002 ************************************************************/
1004 void srv_signing_trans_stop(void)
1006 struct smb_basic_signing_context
*data
;
1008 if (!srv_sign_info
.doing_signing
)
1011 data
= (struct smb_basic_signing_context
*)srv_sign_info
.signing_context
;
1012 if (!data
|| !data
->trans_info
)
1015 DEBUG(10,("srv_signing_trans_stop: removing mid = %u, reply_seq_num = %u, send_seq_num = %u \
1016 data->send_seq_num = %u\n",
1017 (unsigned int)data
->trans_info
->mid
,
1018 (unsigned int)data
->trans_info
->reply_seq_num
,
1019 (unsigned int)data
->trans_info
->send_seq_num
,
1020 (unsigned int)data
->send_seq_num
));
1022 SAFE_FREE(data
->trans_info
);
1023 data
->trans_info
= NULL
;
1026 /***********************************************************
1027 Turn on signing from this packet onwards.
1028 ************************************************************/
1030 void srv_set_signing(const DATA_BLOB user_session_key
, const DATA_BLOB response
)
1032 struct smb_basic_signing_context
*data
;
1034 if (!user_session_key
.length
)
1037 if (!srv_sign_info
.negotiated_smb_signing
&& !srv_sign_info
.mandatory_signing
) {
1038 DEBUG(5,("srv_set_signing: signing negotiated = %u, mandatory_signing = %u. Not allowing smb signing.\n",
1039 (unsigned int)srv_sign_info
.negotiated_smb_signing
,
1040 (unsigned int)srv_sign_info
.mandatory_signing
));
1044 /* Once we've turned on, ignore any more sessionsetups. */
1045 if (srv_sign_info
.doing_signing
) {
1049 if (srv_sign_info
.free_signing_context
)
1050 srv_sign_info
.free_signing_context(&srv_sign_info
);
1052 srv_sign_info
.doing_signing
= True
;
1054 data
= smb_xmalloc(sizeof(*data
));
1055 memset(data
, '\0', sizeof(*data
));
1057 srv_sign_info
.signing_context
= data
;
1059 data
->mac_key
= data_blob(NULL
, response
.length
+ user_session_key
.length
);
1061 memcpy(&data
->mac_key
.data
[0], user_session_key
.data
, user_session_key
.length
);
1062 if (response
.length
)
1063 memcpy(&data
->mac_key
.data
[user_session_key
.length
],response
.data
, response
.length
);
1065 dump_data_pw("MAC ssession key is:\n", data
->mac_key
.data
, data
->mac_key
.length
);
1067 DEBUG(3,("srv_set_signing: turning on SMB signing: signing negotiated = %s, mandatory_signing = %s.\n",
1068 BOOLSTR(srv_sign_info
.negotiated_smb_signing
),
1069 BOOLSTR(srv_sign_info
.mandatory_signing
) ));
1071 /* Initialise the sequence number */
1072 data
->send_seq_num
= 0;
1074 /* Initialise the list of outstanding packets */
1075 data
->outstanding_packet_list
= NULL
;
1077 srv_sign_info
.sign_outgoing_message
= srv_sign_outgoing_message
;
1078 srv_sign_info
.check_incoming_message
= srv_check_incoming_message
;
1079 srv_sign_info
.free_signing_context
= simple_free_signing_context
;