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_P(struct outstanding_packet_lookup
);
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
;
259 /* JRA - apparently this is incorrect. */
260 unsigned char key_buf
[16];
264 * Firstly put the sequence number into the first 4 bytes.
265 * and zero out the next 4 bytes.
267 * We do this here, to avoid modifying the packet.
270 DEBUG(10,("simple_packet_signature: sequence number %u\n", seq_number
));
272 SIVAL(sequence_buf
, 0, seq_number
);
273 SIVAL(sequence_buf
, 4, 0);
275 /* Calculate the 16 byte MAC - but don't alter the data in the
278 This makes for a bit of fussing about, but it's not too bad.
282 /* intialise with the key */
283 MD5Update(&md5_ctx
, data
->mac_key
.data
, data
->mac_key
.length
);
285 /* JRA - apparently this is incorrect. */
286 /* NB. When making and verifying SMB signatures, Windows apparently
287 zero-pads the key to 128 bits if it isn't long enough.
288 From Nalin Dahyabhai <nalin@redhat.com> */
289 if (data
->mac_key
.length
< sizeof(key_buf
)) {
290 memset(key_buf
, 0, sizeof(key_buf
));
291 MD5Update(&md5_ctx
, key_buf
, sizeof(key_buf
) - data
->mac_key
.length
);
295 /* copy in the first bit of the SMB header */
296 MD5Update(&md5_ctx
, buf
+ 4, smb_ss_field
- 4);
298 /* copy in the sequence number, instead of the signature */
299 MD5Update(&md5_ctx
, sequence_buf
, sizeof(sequence_buf
));
301 /* copy in the rest of the packet in, skipping the signature */
302 MD5Update(&md5_ctx
, buf
+ offset_end_of_sig
,
303 smb_len(buf
) - (offset_end_of_sig
- 4));
305 /* calculate the MD5 sig */
306 MD5Final(calc_md5_mac
, &md5_ctx
);
310 /***********************************************************
311 SMB signing - Client implementation - send the MAC.
312 ************************************************************/
314 static void client_sign_outgoing_message(char *outbuf
, struct smb_sign_info
*si
)
316 unsigned char calc_md5_mac
[16];
317 struct smb_basic_signing_context
*data
= si
->signing_context
;
320 if (!si
->doing_signing
)
323 /* JRA Paranioa test - we should be able to get rid of this... */
324 if (smb_len(outbuf
) < (smb_ss_field
+ 8 - 4)) {
325 DEBUG(1, ("client_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n",
330 /* mark the packet as signed - BEFORE we sign it...*/
331 mark_packet_signed(outbuf
);
333 if (data
->trans_info
)
334 send_seq_num
= data
->trans_info
->send_seq_num
;
336 send_seq_num
= data
->send_seq_num
;
338 simple_packet_signature(data
, (const unsigned char *)outbuf
, send_seq_num
, calc_md5_mac
);
340 DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n"));
341 dump_data(10, (const char *)calc_md5_mac
, 8);
343 memcpy(&outbuf
[smb_ss_field
], calc_md5_mac
, 8);
345 /* cli->outbuf[smb_ss_field+2]=0;
346 Uncomment this to test if the remote server actually verifies signatures...*/
348 if (data
->trans_info
)
351 data
->send_seq_num
++;
352 store_sequence_for_reply(&data
->outstanding_packet_list
,
353 SVAL(outbuf
,smb_mid
), data
->send_seq_num
);
354 data
->send_seq_num
++;
357 /***********************************************************
358 SMB signing - Client implementation - check a MAC sent by server.
359 ************************************************************/
361 static BOOL
client_check_incoming_message(char *inbuf
, struct smb_sign_info
*si
, BOOL must_be_ok
)
364 uint32 reply_seq_number
;
366 unsigned char calc_md5_mac
[16];
367 unsigned char *server_sent_mac
;
369 struct smb_basic_signing_context
*data
= si
->signing_context
;
371 if (!si
->doing_signing
)
374 if (smb_len(inbuf
) < (smb_ss_field
+ 8 - 4)) {
375 DEBUG(1, ("client_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf
)));
379 if (data
->trans_info
) {
380 reply_seq_number
= data
->trans_info
->reply_seq_num
;
381 } else if (!get_sequence_for_reply(&data
->outstanding_packet_list
,
382 SVAL(inbuf
, smb_mid
), &reply_seq_number
)) {
383 DEBUG(1, ("client_check_incoming_message: failed to get sequence number %u for reply.\n",
384 (unsigned int) SVAL(inbuf
, smb_mid
) ));
388 saved_seq
= reply_seq_number
;
389 simple_packet_signature(data
, (const unsigned char *)inbuf
, reply_seq_number
, calc_md5_mac
);
391 server_sent_mac
= (unsigned char *)&inbuf
[smb_ss_field
];
392 good
= (memcmp(server_sent_mac
, calc_md5_mac
, 8) == 0);
395 DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n"));
396 dump_data(5, (const char *)calc_md5_mac
, 8);
398 DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n"));
399 dump_data(5, (const char *)server_sent_mac
, 8);
403 reply_seq_number
-= 5;
404 for (i
= 0; i
< 10; i
++, reply_seq_number
++) {
405 simple_packet_signature(data
, (const unsigned char *)inbuf
, reply_seq_number
, calc_md5_mac
);
406 if (memcmp(server_sent_mac
, calc_md5_mac
, 8) == 0) {
407 DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches. \
408 We were expecting seq %u\n", reply_seq_number
, saved_seq
));
416 DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number
));
417 dump_data(10, (const char *)server_sent_mac
, 8);
419 return signing_good(inbuf
, si
, good
, saved_seq
, must_be_ok
);
422 /***********************************************************
423 SMB signing - Simple implementation - free signing context
424 ************************************************************/
426 static void simple_free_signing_context(struct smb_sign_info
*si
)
428 struct smb_basic_signing_context
*data
= si
->signing_context
;
429 struct outstanding_packet_lookup
*list
= data
->outstanding_packet_list
;
432 struct outstanding_packet_lookup
*old_head
= list
;
433 DLIST_REMOVE(list
, list
);
437 data_blob_free(&data
->mac_key
);
439 if (data
->trans_info
)
440 SAFE_FREE(data
->trans_info
);
442 SAFE_FREE(si
->signing_context
);
447 /***********************************************************
448 SMB signing - Simple implementation - setup the MAC key.
449 ************************************************************/
451 BOOL
cli_simple_set_signing(struct cli_state
*cli
,
452 const DATA_BLOB user_session_key
,
453 const DATA_BLOB response
)
455 struct smb_basic_signing_context
*data
;
457 if (!user_session_key
.length
)
460 if (!cli_set_smb_signing_common(cli
)) {
464 if (!set_smb_signing_real_common(&cli
->sign_info
)) {
468 data
= SMB_XMALLOC_P(struct smb_basic_signing_context
);
469 memset(data
, '\0', sizeof(*data
));
471 cli
->sign_info
.signing_context
= data
;
473 data
->mac_key
= data_blob(NULL
, response
.length
+ user_session_key
.length
);
475 memcpy(&data
->mac_key
.data
[0], user_session_key
.data
, user_session_key
.length
);
477 DEBUG(10, ("cli_simple_set_signing: user_session_key\n"));
478 dump_data(10, (const char *)user_session_key
.data
, user_session_key
.length
);
480 if (response
.length
) {
481 memcpy(&data
->mac_key
.data
[user_session_key
.length
],response
.data
, response
.length
);
482 DEBUG(10, ("cli_simple_set_signing: response_data\n"));
483 dump_data(10, (const char *)response
.data
, response
.length
);
485 DEBUG(10, ("cli_simple_set_signing: NULL response_data\n"));
488 dump_data_pw("MAC ssession key is:\n", data
->mac_key
.data
, data
->mac_key
.length
);
490 /* Initialise the sequence number */
491 data
->send_seq_num
= 0;
493 /* Initialise the list of outstanding packets */
494 data
->outstanding_packet_list
= NULL
;
496 cli
->sign_info
.sign_outgoing_message
= client_sign_outgoing_message
;
497 cli
->sign_info
.check_incoming_message
= client_check_incoming_message
;
498 cli
->sign_info
.free_signing_context
= simple_free_signing_context
;
503 /***********************************************************
504 Tell client code we are in a multiple trans reply state.
505 We call this after the last outgoing trans2 packet (which
506 has incremented the sequence numbers), so we must save the
507 current mid and sequence number -2.
508 ************************************************************/
510 void cli_signing_trans_start(struct cli_state
*cli
, uint16 mid
)
512 struct smb_basic_signing_context
*data
= cli
->sign_info
.signing_context
;
513 uint32 reply_seq_num
;
515 if (!cli
->sign_info
.doing_signing
|| !data
)
518 data
->trans_info
= SMB_XMALLOC_P(struct trans_info_context
);
519 ZERO_STRUCTP(data
->trans_info
);
521 /* This ensures the sequence is pulled off the outstanding packet list */
522 if (!get_sequence_for_reply(&data
->outstanding_packet_list
,
523 mid
, &reply_seq_num
)) {
524 DEBUG(1, ("get_sequence_for_reply failed - did we enter the trans signing state without sending a packet?\n"));
528 data
->trans_info
->send_seq_num
= reply_seq_num
- 1;
529 data
->trans_info
->mid
= mid
;
530 data
->trans_info
->reply_seq_num
= reply_seq_num
;
532 DEBUG(10,("cli_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \
533 data->send_seq_num = %u\n",
534 (unsigned int)data
->trans_info
->mid
,
535 (unsigned int)data
->trans_info
->reply_seq_num
,
536 (unsigned int)data
->trans_info
->send_seq_num
,
537 (unsigned int)data
->send_seq_num
));
540 /***********************************************************
541 Tell client code we are out of a multiple trans reply state.
542 ************************************************************/
544 void cli_signing_trans_stop(struct cli_state
*cli
)
546 struct smb_basic_signing_context
*data
= cli
->sign_info
.signing_context
;
548 if (!cli
->sign_info
.doing_signing
|| !data
)
551 DEBUG(10,("cli_signing_trans_stop: freeing mid = %u, reply_seq_num = %u, send_seq_num = %u \
552 data->send_seq_num = %u\n",
553 (unsigned int)data
->trans_info
->mid
,
554 (unsigned int)data
->trans_info
->reply_seq_num
,
555 (unsigned int)data
->trans_info
->send_seq_num
,
556 (unsigned int)data
->send_seq_num
));
558 SAFE_FREE(data
->trans_info
);
559 data
->trans_info
= NULL
;
562 /***********************************************************
563 SMB signing - TEMP implementation - calculate a MAC to send.
564 ************************************************************/
566 static void temp_sign_outgoing_message(char *outbuf
, struct smb_sign_info
*si
)
568 /* mark the packet as signed - BEFORE we sign it...*/
569 mark_packet_signed(outbuf
);
571 /* I wonder what BSRSPYL stands for - but this is what MS
573 memcpy(&outbuf
[smb_ss_field
], "BSRSPYL ", 8);
577 /***********************************************************
578 SMB signing - TEMP implementation - check a MAC sent by server.
579 ************************************************************/
581 static BOOL
temp_check_incoming_message(char *inbuf
, struct smb_sign_info
*si
, BOOL foo
)
586 /***********************************************************
587 SMB signing - TEMP implementation - free signing context
588 ************************************************************/
590 static void temp_free_signing_context(struct smb_sign_info
*si
)
595 /***********************************************************
596 SMB signing - NULL implementation - setup the MAC key.
597 ************************************************************/
599 BOOL
cli_null_set_signing(struct cli_state
*cli
)
601 return null_set_signing(&cli
->sign_info
);
604 /***********************************************************
605 SMB signing - temp implementation - setup the MAC key.
606 ************************************************************/
608 BOOL
cli_temp_set_signing(struct cli_state
*cli
)
610 if (!cli_set_smb_signing_common(cli
)) {
614 cli
->sign_info
.signing_context
= NULL
;
616 cli
->sign_info
.sign_outgoing_message
= temp_sign_outgoing_message
;
617 cli
->sign_info
.check_incoming_message
= temp_check_incoming_message
;
618 cli
->sign_info
.free_signing_context
= temp_free_signing_context
;
623 void cli_free_signing_context(struct cli_state
*cli
)
625 free_signing_context(&cli
->sign_info
);
629 * Sign a packet with the current mechanism
632 void cli_calculate_sign_mac(struct cli_state
*cli
)
634 cli
->sign_info
.sign_outgoing_message(cli
->outbuf
, &cli
->sign_info
);
638 * Check a packet with the current mechanism
639 * @return False if we had an established signing connection
640 * which had a bad checksum, True otherwise.
643 BOOL
cli_check_sign_mac(struct cli_state
*cli
)
645 if (!cli
->sign_info
.check_incoming_message(cli
->inbuf
, &cli
->sign_info
, True
)) {
646 free_signing_context(&cli
->sign_info
);
652 /***********************************************************
653 SMB signing - Server implementation - send the MAC.
654 ************************************************************/
656 static void srv_sign_outgoing_message(char *outbuf
, struct smb_sign_info
*si
)
658 unsigned char calc_md5_mac
[16];
659 struct smb_basic_signing_context
*data
= si
->signing_context
;
660 uint32 send_seq_number
= data
->send_seq_num
;
661 BOOL was_deferred_packet
= False
;
664 if (!si
->doing_signing
) {
668 /* JRA Paranioa test - we should be able to get rid of this... */
669 if (smb_len(outbuf
) < (smb_ss_field
+ 8 - 4)) {
670 DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't send signature on short packet! smb_len = %u\n",
675 /* mark the packet as signed - BEFORE we sign it...*/
676 mark_packet_signed(outbuf
);
678 mid
= SVAL(outbuf
, smb_mid
);
680 /* See if this is a reply for a deferred packet. */
681 was_deferred_packet
= get_sequence_for_reply(&data
->outstanding_packet_list
, mid
, &send_seq_number
);
683 if (data
->trans_info
&& (data
->trans_info
->mid
== mid
)) {
684 /* This is a reply in a trans stream. Use the sequence
685 * number associated with the stream mid. */
686 send_seq_number
= data
->trans_info
->send_seq_num
;
689 simple_packet_signature(data
, (const unsigned char *)outbuf
, send_seq_number
, calc_md5_mac
);
691 DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number
));
692 dump_data(10, (const char *)calc_md5_mac
, 8);
694 memcpy(&outbuf
[smb_ss_field
], calc_md5_mac
, 8);
696 /* cli->outbuf[smb_ss_field+2]=0;
697 Uncomment this to test if the remote client actually verifies signatures...*/
699 /* Don't mess with the sequence number for a deferred packet. */
700 if (was_deferred_packet
) {
704 if (!data
->trans_info
) {
705 /* Always increment if not in a trans stream. */
706 data
->send_seq_num
++;
707 } else if ((data
->trans_info
->send_seq_num
== data
->send_seq_num
) || (data
->trans_info
->mid
!= mid
)) {
708 /* Increment if this is the first reply in a trans stream or a
709 * packet that doesn't belong to this stream (different mid). */
710 data
->send_seq_num
++;
714 /***********************************************************
715 Is an incoming packet an oplock break reply ?
716 ************************************************************/
718 static BOOL
is_oplock_break(char *inbuf
)
720 if (CVAL(inbuf
,smb_com
) != SMBlockingX
)
723 if (!(CVAL(inbuf
,smb_vwv3
) & LOCKING_ANDX_OPLOCK_RELEASE
))
726 DEBUG(10,("is_oplock_break: Packet is oplock break\n"));
730 /***********************************************************
731 SMB signing - Server implementation - check a MAC sent by server.
732 ************************************************************/
734 static BOOL
srv_check_incoming_message(char *inbuf
, struct smb_sign_info
*si
, BOOL must_be_ok
)
737 struct smb_basic_signing_context
*data
= si
->signing_context
;
738 uint32 reply_seq_number
= data
->send_seq_num
;
740 unsigned char calc_md5_mac
[16];
741 unsigned char *server_sent_mac
;
744 if (!si
->doing_signing
)
747 if (smb_len(inbuf
) < (smb_ss_field
+ 8 - 4)) {
748 DEBUG(1, ("srv_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf
)));
752 mid
= SVAL(inbuf
, smb_mid
);
754 /* Is this part of a trans stream ? */
755 if (data
->trans_info
&& (data
->trans_info
->mid
== mid
)) {
756 /* If so we don't increment the sequence. */
757 reply_seq_number
= data
->trans_info
->reply_seq_num
;
759 /* We always increment the sequence number. */
760 data
->send_seq_num
++;
762 /* If we get an asynchronous oplock break reply and there
763 * isn't a reply pending we need to re-sync the sequence
766 if (is_oplock_break(inbuf
)) {
767 DEBUG(10,("srv_check_incoming_message: oplock break at seq num %u\n", data
->send_seq_num
));
768 data
->send_seq_num
++;
772 saved_seq
= reply_seq_number
;
773 simple_packet_signature(data
, (const unsigned char *)inbuf
, reply_seq_number
, calc_md5_mac
);
775 server_sent_mac
= (unsigned char *)&inbuf
[smb_ss_field
];
776 good
= (memcmp(server_sent_mac
, calc_md5_mac
, 8) == 0);
781 DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n",
782 (unsigned int)saved_seq
));
783 dump_data(5, (const char *)calc_md5_mac
, 8);
785 DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n",
786 (unsigned int)reply_seq_number
));
787 dump_data(5, (const char *)server_sent_mac
, 8);
793 reply_seq_number
-= 5;
794 for (i
= 0; i
< 10; i
++, reply_seq_number
++) {
795 simple_packet_signature(data
, (const unsigned char *)inbuf
, reply_seq_number
, calc_md5_mac
);
796 if (memcmp(server_sent_mac
, calc_md5_mac
, 8) == 0) {
797 DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches. \
798 We were expecting seq %u\n", reply_seq_number
, saved_seq
));
806 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
));
807 dump_data(10, (const char *)server_sent_mac
, 8);
810 return (signing_good(inbuf
, si
, good
, saved_seq
, must_be_ok
));
813 /***********************************************************
814 SMB signing - server API's.
815 ************************************************************/
817 static struct smb_sign_info srv_sign_info
= {
818 null_sign_outgoing_message
,
819 null_check_incoming_message
,
820 null_free_signing_context
,
828 /***********************************************************
829 Turn signing off or on for oplock break code.
830 ************************************************************/
832 BOOL
srv_oplock_set_signing(BOOL onoff
)
834 BOOL ret
= srv_sign_info
.doing_signing
;
835 srv_sign_info
.doing_signing
= onoff
;
839 /***********************************************************
840 Called to validate an incoming packet from the client.
841 ************************************************************/
843 BOOL
srv_check_sign_mac(char *inbuf
, BOOL must_be_ok
)
845 /* Check if it's a session keepalive. */
846 if(CVAL(inbuf
,0) == SMBkeepalive
)
849 return srv_sign_info
.check_incoming_message(inbuf
, &srv_sign_info
, must_be_ok
);
852 /***********************************************************
853 Called to sign an outgoing packet to the client.
854 ************************************************************/
856 void srv_calculate_sign_mac(char *outbuf
)
858 /* Check if it's a session keepalive. */
859 /* JRA Paranioa test - do we ever generate these in the server ? */
860 if(CVAL(outbuf
,0) == SMBkeepalive
)
863 srv_sign_info
.sign_outgoing_message(outbuf
, &srv_sign_info
);
866 /***********************************************************
867 Called by server to defer an outgoing packet.
868 ************************************************************/
870 void srv_defer_sign_response(uint16 mid
)
872 struct smb_basic_signing_context
*data
;
874 if (!srv_sign_info
.doing_signing
)
877 data
= (struct smb_basic_signing_context
*)srv_sign_info
.signing_context
;
883 * Ensure we only store this mid reply once...
886 if (store_sequence_for_reply(&data
->outstanding_packet_list
, mid
, data
->send_seq_num
)) {
887 data
->send_seq_num
++;
891 /***********************************************************
892 Called to remove sequence records when a deferred packet is
893 cancelled by mid. This should never find one....
894 ************************************************************/
896 void srv_cancel_sign_response(uint16 mid
)
898 struct smb_basic_signing_context
*data
;
901 if (!srv_sign_info
.doing_signing
)
904 data
= (struct smb_basic_signing_context
*)srv_sign_info
.signing_context
;
909 DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid
));
911 while (get_sequence_for_reply(&data
->outstanding_packet_list
, mid
, &dummy_seq
))
915 /***********************************************************
916 Called by server negprot when signing has been negotiated.
917 ************************************************************/
919 void srv_set_signing_negotiated(void)
921 srv_sign_info
.allow_smb_signing
= True
;
922 srv_sign_info
.negotiated_smb_signing
= True
;
923 if (lp_server_signing() == Required
)
924 srv_sign_info
.mandatory_signing
= True
;
926 srv_sign_info
.sign_outgoing_message
= temp_sign_outgoing_message
;
927 srv_sign_info
.check_incoming_message
= temp_check_incoming_message
;
928 srv_sign_info
.free_signing_context
= temp_free_signing_context
;
931 /***********************************************************
932 Returns whether signing is active. We can't use sendfile or raw
933 reads/writes if it is.
934 ************************************************************/
936 BOOL
srv_is_signing_active(void)
938 return srv_sign_info
.doing_signing
;
942 /***********************************************************
943 Returns whether signing is negotiated. We can't use it unless it was
945 ************************************************************/
947 BOOL
srv_is_signing_negotiated(void)
949 return srv_sign_info
.negotiated_smb_signing
;
952 /***********************************************************
953 Returns whether signing is actually happening
954 ************************************************************/
956 BOOL
srv_signing_started(void)
958 struct smb_basic_signing_context
*data
;
960 if (!srv_sign_info
.doing_signing
) {
964 data
= (struct smb_basic_signing_context
*)srv_sign_info
.signing_context
;
968 if (data
->send_seq_num
== 0) {
976 /***********************************************************
977 Tell server code we are in a multiple trans reply state.
978 ************************************************************/
980 void srv_signing_trans_start(uint16 mid
)
982 struct smb_basic_signing_context
*data
;
984 if (!srv_sign_info
.doing_signing
)
987 data
= (struct smb_basic_signing_context
*)srv_sign_info
.signing_context
;
991 data
->trans_info
= SMB_XMALLOC_P(struct trans_info_context
);
992 ZERO_STRUCTP(data
->trans_info
);
994 data
->trans_info
->reply_seq_num
= data
->send_seq_num
-1;
995 data
->trans_info
->mid
= mid
;
996 data
->trans_info
->send_seq_num
= data
->send_seq_num
;
998 DEBUG(10,("srv_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \
999 data->send_seq_num = %u\n",
1001 (unsigned int)data
->trans_info
->reply_seq_num
,
1002 (unsigned int)data
->trans_info
->send_seq_num
,
1003 (unsigned int)data
->send_seq_num
));
1006 /***********************************************************
1007 Tell server code we are out of a multiple trans reply state.
1008 ************************************************************/
1010 void srv_signing_trans_stop(void)
1012 struct smb_basic_signing_context
*data
;
1014 if (!srv_sign_info
.doing_signing
)
1017 data
= (struct smb_basic_signing_context
*)srv_sign_info
.signing_context
;
1018 if (!data
|| !data
->trans_info
)
1021 DEBUG(10,("srv_signing_trans_stop: removing mid = %u, reply_seq_num = %u, send_seq_num = %u \
1022 data->send_seq_num = %u\n",
1023 (unsigned int)data
->trans_info
->mid
,
1024 (unsigned int)data
->trans_info
->reply_seq_num
,
1025 (unsigned int)data
->trans_info
->send_seq_num
,
1026 (unsigned int)data
->send_seq_num
));
1028 SAFE_FREE(data
->trans_info
);
1029 data
->trans_info
= NULL
;
1032 /***********************************************************
1033 Turn on signing from this packet onwards.
1034 ************************************************************/
1036 void srv_set_signing(const DATA_BLOB user_session_key
, const DATA_BLOB response
)
1038 struct smb_basic_signing_context
*data
;
1040 if (!user_session_key
.length
)
1043 if (!srv_sign_info
.negotiated_smb_signing
&& !srv_sign_info
.mandatory_signing
) {
1044 DEBUG(5,("srv_set_signing: signing negotiated = %u, mandatory_signing = %u. Not allowing smb signing.\n",
1045 (unsigned int)srv_sign_info
.negotiated_smb_signing
,
1046 (unsigned int)srv_sign_info
.mandatory_signing
));
1050 /* Once we've turned on, ignore any more sessionsetups. */
1051 if (srv_sign_info
.doing_signing
) {
1055 if (srv_sign_info
.free_signing_context
)
1056 srv_sign_info
.free_signing_context(&srv_sign_info
);
1058 srv_sign_info
.doing_signing
= True
;
1060 data
= SMB_XMALLOC_P(struct smb_basic_signing_context
);
1061 memset(data
, '\0', sizeof(*data
));
1063 srv_sign_info
.signing_context
= data
;
1065 data
->mac_key
= data_blob(NULL
, response
.length
+ user_session_key
.length
);
1067 memcpy(&data
->mac_key
.data
[0], user_session_key
.data
, user_session_key
.length
);
1068 if (response
.length
)
1069 memcpy(&data
->mac_key
.data
[user_session_key
.length
],response
.data
, response
.length
);
1071 dump_data_pw("MAC ssession key is:\n", data
->mac_key
.data
, data
->mac_key
.length
);
1073 DEBUG(3,("srv_set_signing: turning on SMB signing: signing negotiated = %s, mandatory_signing = %s.\n",
1074 BOOLSTR(srv_sign_info
.negotiated_smb_signing
),
1075 BOOLSTR(srv_sign_info
.mandatory_signing
) ));
1077 /* Initialise the sequence number */
1078 data
->send_seq_num
= 0;
1080 /* Initialise the list of outstanding packets */
1081 data
->outstanding_packet_list
= NULL
;
1083 srv_sign_info
.sign_outgoing_message
= srv_sign_outgoing_message
;
1084 srv_sign_info
.check_incoming_message
= srv_check_incoming_message
;
1085 srv_sign_info
.free_signing_context
= simple_free_signing_context
;