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 void store_sequence_for_reply(struct outstanding_packet_lookup
**list
,
46 uint16 mid
, uint32 reply_seq_num
)
48 struct outstanding_packet_lookup
*t
;
50 t
= smb_xmalloc(sizeof(*t
));
54 t
->reply_seq_num
= reply_seq_num
;
57 * Add to the *start* of the list not the end of the list.
58 * This ensures that the *last* send sequence with this mid
59 * is returned by preference.
60 * This can happen if the mid wraps and one of the early
61 * mid numbers didn't get a reply and is still lurking on
62 * the list. JRA. Found by Fran Fabrizio <fran@cis.uab.edu>.
66 DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n",
67 (unsigned int)reply_seq_num
, (unsigned int)mid
));
70 static BOOL
get_sequence_for_reply(struct outstanding_packet_lookup
**list
,
71 uint16 mid
, uint32
*reply_seq_num
)
73 struct outstanding_packet_lookup
*t
;
75 for (t
= *list
; t
; t
= t
->next
) {
77 *reply_seq_num
= t
->reply_seq_num
;
78 DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n",
79 (unsigned int)t
->reply_seq_num
, (unsigned int)t
->mid
));
80 DLIST_REMOVE(*list
, t
);
88 /***********************************************************
89 SMB signing - Common code before we set a new signing implementation
90 ************************************************************/
92 static BOOL
cli_set_smb_signing_common(struct cli_state
*cli
)
94 if (!cli
->sign_info
.negotiated_smb_signing
95 && !cli
->sign_info
.mandatory_signing
) {
99 if (cli
->sign_info
.doing_signing
) {
103 if (cli
->sign_info
.free_signing_context
)
104 cli
->sign_info
.free_signing_context(&cli
->sign_info
);
106 /* These calls are INCOMPATIBLE with SMB signing */
107 cli
->readbraw_supported
= False
;
108 cli
->writebraw_supported
= False
;
113 /***********************************************************
114 SMB signing - Common code for 'real' implementations
115 ************************************************************/
117 static BOOL
set_smb_signing_real_common(struct smb_sign_info
*si
)
119 if (si
->mandatory_signing
) {
120 DEBUG(5, ("Mandatory SMB signing enabled!\n"));
123 si
->doing_signing
= True
;
124 DEBUG(5, ("SMB signing enabled!\n"));
129 static void mark_packet_signed(char *outbuf
)
132 flags2
= SVAL(outbuf
,smb_flg2
);
133 flags2
|= FLAGS2_SMB_SECURITY_SIGNATURES
;
134 SSVAL(outbuf
,smb_flg2
, flags2
);
137 /***********************************************************
138 SMB signing - NULL implementation - calculate a MAC to send.
139 ************************************************************/
141 static void null_sign_outgoing_message(char *outbuf
, struct smb_sign_info
*si
)
143 /* we can't zero out the sig, as we might be trying to send a
144 session request - which is NBT-level, not SMB level and doesn't
149 /***********************************************************
150 SMB signing - NULL implementation - check a MAC sent by server.
151 ************************************************************/
153 static BOOL
null_check_incoming_message(char *inbuf
, struct smb_sign_info
*si
, BOOL must_be_ok
)
158 /***********************************************************
159 SMB signing - NULL implementation - free signing context
160 ************************************************************/
162 static void null_free_signing_context(struct smb_sign_info
*si
)
168 SMB signing - NULL implementation - setup the MAC key.
170 @note Used as an initialisation only - it will not correctly
171 shut down a real signing mechanism
174 static BOOL
null_set_signing(struct smb_sign_info
*si
)
176 si
->signing_context
= NULL
;
178 si
->sign_outgoing_message
= null_sign_outgoing_message
;
179 si
->check_incoming_message
= null_check_incoming_message
;
180 si
->free_signing_context
= null_free_signing_context
;
186 * Free the signing context
189 static void free_signing_context(struct smb_sign_info
*si
)
191 if (si
->free_signing_context
) {
192 si
->free_signing_context(si
);
193 si
->signing_context
= NULL
;
196 null_set_signing(si
);
200 static BOOL
signing_good(char *inbuf
, struct smb_sign_info
*si
, BOOL good
, uint32 seq
, BOOL must_be_ok
)
204 if (!si
->doing_signing
) {
205 si
->doing_signing
= True
;
208 if (!si
->seen_valid
) {
209 si
->seen_valid
= True
;
213 if (!si
->mandatory_signing
&& !si
->seen_valid
) {
218 /* Non-mandatory signing - just turn off if this is the first bad packet.. */
219 DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and peer\n"
220 "isn't sending correct signatures. Turning off.\n"));
221 si
->negotiated_smb_signing
= False
;
222 si
->allow_smb_signing
= False
;
223 si
->doing_signing
= False
;
224 free_signing_context(si
);
226 } else if (!must_be_ok
) {
227 /* This packet is known to be unsigned */
230 /* Mandatory signing or bad packet after signing started - fail and disconnect. */
232 DEBUG(0, ("signing_good: BAD SIG: seq %u\n", (unsigned int)seq
));
239 /***********************************************************
240 SMB signing - Simple implementation - calculate a MAC on the packet
241 ************************************************************/
243 static void simple_packet_signature(struct smb_basic_signing_context
*data
,
244 const uchar
*buf
, uint32 seq_number
,
245 unsigned char calc_md5_mac
[16])
247 const size_t offset_end_of_sig
= (smb_ss_field
+ 8);
248 unsigned char sequence_buf
[8];
249 struct MD5Context md5_ctx
;
252 * Firstly put the sequence number into the first 4 bytes.
253 * and zero out the next 4 bytes.
255 * We do this here, to avoid modifying the packet.
258 DEBUG(10,("simple_packet_signature: sequence number %u\n", seq_number
));
260 SIVAL(sequence_buf
, 0, seq_number
);
261 SIVAL(sequence_buf
, 4, 0);
263 /* Calculate the 16 byte MAC - but don't alter the data in the
266 This makes for a bit of fussing about, but it's not too bad.
270 /* intialise with the key */
271 MD5Update(&md5_ctx
, data
->mac_key
.data
,
272 data
->mac_key
.length
);
274 /* copy in the first bit of the SMB header */
275 MD5Update(&md5_ctx
, buf
+ 4, smb_ss_field
- 4);
277 /* copy in the sequence number, instead of the signature */
278 MD5Update(&md5_ctx
, sequence_buf
, sizeof(sequence_buf
));
280 /* copy in the rest of the packet in, skipping the signature */
281 MD5Update(&md5_ctx
, buf
+ offset_end_of_sig
,
282 smb_len(buf
) - (offset_end_of_sig
- 4));
284 /* calculate the MD5 sig */
285 MD5Final(calc_md5_mac
, &md5_ctx
);
289 /***********************************************************
290 SMB signing - Client implementation - send the MAC.
291 ************************************************************/
293 static void client_sign_outgoing_message(char *outbuf
, struct smb_sign_info
*si
)
295 unsigned char calc_md5_mac
[16];
296 struct smb_basic_signing_context
*data
= si
->signing_context
;
299 if (!si
->doing_signing
)
302 /* JRA Paranioa test - we should be able to get rid of this... */
303 if (smb_len(outbuf
) < (smb_ss_field
+ 8 - 4)) {
304 DEBUG(1, ("client_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n",
309 /* mark the packet as signed - BEFORE we sign it...*/
310 mark_packet_signed(outbuf
);
312 if (data
->trans_info
)
313 send_seq_num
= data
->trans_info
->send_seq_num
;
315 send_seq_num
= data
->send_seq_num
;
317 simple_packet_signature(data
, (const unsigned char *)outbuf
, send_seq_num
, calc_md5_mac
);
319 DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n"));
320 dump_data(10, (const char *)calc_md5_mac
, 8);
322 memcpy(&outbuf
[smb_ss_field
], calc_md5_mac
, 8);
324 /* cli->outbuf[smb_ss_field+2]=0;
325 Uncomment this to test if the remote server actually verifies signatures...*/
327 if (data
->trans_info
)
330 data
->send_seq_num
++;
331 store_sequence_for_reply(&data
->outstanding_packet_list
,
332 SVAL(outbuf
,smb_mid
), data
->send_seq_num
);
333 data
->send_seq_num
++;
336 /***********************************************************
337 SMB signing - Client implementation - check a MAC sent by server.
338 ************************************************************/
340 static BOOL
client_check_incoming_message(char *inbuf
, struct smb_sign_info
*si
, BOOL must_be_ok
)
343 uint32 reply_seq_number
;
345 unsigned char calc_md5_mac
[16];
346 unsigned char *server_sent_mac
;
348 struct smb_basic_signing_context
*data
= si
->signing_context
;
350 if (!si
->doing_signing
)
353 if (smb_len(inbuf
) < (smb_ss_field
+ 8 - 4)) {
354 DEBUG(1, ("client_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf
)));
358 if (data
->trans_info
) {
359 reply_seq_number
= data
->trans_info
->reply_seq_num
;
360 } else if (!get_sequence_for_reply(&data
->outstanding_packet_list
,
361 SVAL(inbuf
, smb_mid
), &reply_seq_number
)) {
362 DEBUG(1, ("client_check_incoming_message: failed to get sequence number %u for reply.\n",
363 (unsigned int) SVAL(inbuf
, smb_mid
) ));
367 saved_seq
= reply_seq_number
;
368 simple_packet_signature(data
, (const unsigned char *)inbuf
, reply_seq_number
, calc_md5_mac
);
370 server_sent_mac
= (unsigned char *)&inbuf
[smb_ss_field
];
371 good
= (memcmp(server_sent_mac
, calc_md5_mac
, 8) == 0);
374 DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n"));
375 dump_data(5, (const char *)calc_md5_mac
, 8);
377 DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n"));
378 dump_data(5, (const char *)server_sent_mac
, 8);
382 reply_seq_number
-= 5;
383 for (i
= 0; i
< 10; i
++, reply_seq_number
++) {
384 simple_packet_signature(data
, (const unsigned char *)inbuf
, reply_seq_number
, calc_md5_mac
);
385 if (memcmp(server_sent_mac
, calc_md5_mac
, 8) == 0) {
386 DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches. \
387 We were expecting seq %u\n", reply_seq_number
, saved_seq
));
395 DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number
));
396 dump_data(10, (const char *)server_sent_mac
, 8);
398 return signing_good(inbuf
, si
, good
, saved_seq
, must_be_ok
);
401 /***********************************************************
402 SMB signing - Simple implementation - free signing context
403 ************************************************************/
405 static void simple_free_signing_context(struct smb_sign_info
*si
)
407 struct smb_basic_signing_context
*data
= si
->signing_context
;
408 struct outstanding_packet_lookup
*list
= data
->outstanding_packet_list
;
411 struct outstanding_packet_lookup
*old_head
= list
;
412 DLIST_REMOVE(list
, list
);
416 data_blob_free(&data
->mac_key
);
418 if (data
->trans_info
)
419 SAFE_FREE(data
->trans_info
);
421 SAFE_FREE(si
->signing_context
);
426 /***********************************************************
427 SMB signing - Simple implementation - setup the MAC key.
428 ************************************************************/
430 BOOL
cli_simple_set_signing(struct cli_state
*cli
,
431 const DATA_BLOB user_session_key
,
432 const DATA_BLOB response
)
434 struct smb_basic_signing_context
*data
;
436 if (!user_session_key
.length
)
439 if (!cli_set_smb_signing_common(cli
)) {
443 if (!set_smb_signing_real_common(&cli
->sign_info
)) {
447 data
= smb_xmalloc(sizeof(*data
));
448 memset(data
, '\0', sizeof(*data
));
450 cli
->sign_info
.signing_context
= data
;
452 data
->mac_key
= data_blob(NULL
, response
.length
+ user_session_key
.length
);
454 memcpy(&data
->mac_key
.data
[0], user_session_key
.data
, user_session_key
.length
);
456 DEBUG(10, ("cli_simple_set_signing: user_session_key\n"));
457 dump_data(10, (const char *)user_session_key
.data
, user_session_key
.length
);
459 if (response
.length
) {
460 memcpy(&data
->mac_key
.data
[user_session_key
.length
],response
.data
, response
.length
);
461 DEBUG(10, ("cli_simple_set_signing: response_data\n"));
462 dump_data(10, (const char *)response
.data
, response
.length
);
464 DEBUG(10, ("cli_simple_set_signing: NULL response_data\n"));
467 dump_data_pw("MAC ssession key is:\n", data
->mac_key
.data
, data
->mac_key
.length
);
469 /* Initialise the sequence number */
470 data
->send_seq_num
= 0;
472 /* Initialise the list of outstanding packets */
473 data
->outstanding_packet_list
= NULL
;
475 cli
->sign_info
.sign_outgoing_message
= client_sign_outgoing_message
;
476 cli
->sign_info
.check_incoming_message
= client_check_incoming_message
;
477 cli
->sign_info
.free_signing_context
= simple_free_signing_context
;
482 /***********************************************************
483 Tell client code we are in a multiple trans reply state.
484 We call this after the last outgoing trans2 packet (which
485 has incremented the sequence numbers), so we must save the
486 current mid and sequence number -2.
487 ************************************************************/
489 void cli_signing_trans_start(struct cli_state
*cli
, uint16 mid
)
491 struct smb_basic_signing_context
*data
= cli
->sign_info
.signing_context
;
493 if (!cli
->sign_info
.doing_signing
|| !data
)
496 data
->trans_info
= smb_xmalloc(sizeof(struct trans_info_context
));
497 ZERO_STRUCTP(data
->trans_info
);
499 data
->trans_info
->send_seq_num
= data
->send_seq_num
-2;
500 data
->trans_info
->mid
= mid
;
501 data
->trans_info
->reply_seq_num
= data
->send_seq_num
-1;
503 DEBUG(10,("cli_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \
504 data->send_seq_num = %u\n",
505 (unsigned int)data
->trans_info
->mid
,
506 (unsigned int)data
->trans_info
->reply_seq_num
,
507 (unsigned int)data
->trans_info
->send_seq_num
,
508 (unsigned int)data
->send_seq_num
));
511 /***********************************************************
512 Tell client code we are out of a multiple trans reply state.
513 ************************************************************/
515 void cli_signing_trans_stop(struct cli_state
*cli
)
517 struct smb_basic_signing_context
*data
= cli
->sign_info
.signing_context
;
519 if (!cli
->sign_info
.doing_signing
|| !data
)
522 DEBUG(10,("cli_signing_trans_stop: freeing mid = %u, reply_seq_num = %u, send_seq_num = %u \
523 data->send_seq_num = %u\n",
524 (unsigned int)data
->trans_info
->mid
,
525 (unsigned int)data
->trans_info
->reply_seq_num
,
526 (unsigned int)data
->trans_info
->send_seq_num
,
527 (unsigned int)data
->send_seq_num
));
529 SAFE_FREE(data
->trans_info
);
530 data
->trans_info
= NULL
;
533 /***********************************************************
534 SMB signing - TEMP implementation - calculate a MAC to send.
535 ************************************************************/
537 static void temp_sign_outgoing_message(char *outbuf
, struct smb_sign_info
*si
)
539 /* mark the packet as signed - BEFORE we sign it...*/
540 mark_packet_signed(outbuf
);
542 /* I wonder what BSRSPYL stands for - but this is what MS
544 memcpy(&outbuf
[smb_ss_field
], "BSRSPYL ", 8);
548 /***********************************************************
549 SMB signing - TEMP implementation - check a MAC sent by server.
550 ************************************************************/
552 static BOOL
temp_check_incoming_message(char *inbuf
, struct smb_sign_info
*si
, BOOL foo
)
557 /***********************************************************
558 SMB signing - TEMP implementation - free signing context
559 ************************************************************/
561 static void temp_free_signing_context(struct smb_sign_info
*si
)
566 /***********************************************************
567 SMB signing - NULL implementation - setup the MAC key.
568 ************************************************************/
570 BOOL
cli_null_set_signing(struct cli_state
*cli
)
572 return null_set_signing(&cli
->sign_info
);
575 /***********************************************************
576 SMB signing - temp implementation - setup the MAC key.
577 ************************************************************/
579 BOOL
cli_temp_set_signing(struct cli_state
*cli
)
581 if (!cli_set_smb_signing_common(cli
)) {
585 cli
->sign_info
.signing_context
= NULL
;
587 cli
->sign_info
.sign_outgoing_message
= temp_sign_outgoing_message
;
588 cli
->sign_info
.check_incoming_message
= temp_check_incoming_message
;
589 cli
->sign_info
.free_signing_context
= temp_free_signing_context
;
594 void cli_free_signing_context(struct cli_state
*cli
)
596 free_signing_context(&cli
->sign_info
);
600 * Sign a packet with the current mechanism
603 void cli_calculate_sign_mac(struct cli_state
*cli
)
605 cli
->sign_info
.sign_outgoing_message(cli
->outbuf
, &cli
->sign_info
);
609 * Check a packet with the current mechanism
610 * @return False if we had an established signing connection
611 * which had a bad checksum, True otherwise.
614 BOOL
cli_check_sign_mac(struct cli_state
*cli
, BOOL must_be_ok
)
616 if (!cli
->sign_info
.check_incoming_message(cli
->inbuf
, &cli
->sign_info
, must_be_ok
)) {
617 free_signing_context(&cli
->sign_info
);
623 /***********************************************************
624 SMB signing - Server implementation - send the MAC.
625 ************************************************************/
627 static void srv_sign_outgoing_message(char *outbuf
, struct smb_sign_info
*si
)
629 unsigned char calc_md5_mac
[16];
630 struct smb_basic_signing_context
*data
= si
->signing_context
;
631 uint32 send_seq_number
= data
->send_seq_num
;
632 BOOL was_deferred_packet
= False
;
635 if (!si
->doing_signing
) {
639 /* JRA Paranioa test - we should be able to get rid of this... */
640 if (smb_len(outbuf
) < (smb_ss_field
+ 8 - 4)) {
641 DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't send signature on short packet! smb_len = %u\n",
646 /* mark the packet as signed - BEFORE we sign it...*/
647 mark_packet_signed(outbuf
);
649 mid
= SVAL(outbuf
, smb_mid
);
651 /* See if this is a reply for a deferred packet. */
652 was_deferred_packet
= get_sequence_for_reply(&data
->outstanding_packet_list
, mid
, &send_seq_number
);
654 if (data
->trans_info
&& (data
->trans_info
->mid
== mid
)) {
655 /* This is a reply in a trans stream. Use the sequence
656 * number associated with the stream mid. */
657 send_seq_number
= data
->trans_info
->send_seq_num
;
660 simple_packet_signature(data
, (const unsigned char *)outbuf
, send_seq_number
, calc_md5_mac
);
662 DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number
));
663 dump_data(10, (const char *)calc_md5_mac
, 8);
665 memcpy(&outbuf
[smb_ss_field
], calc_md5_mac
, 8);
667 /* cli->outbuf[smb_ss_field+2]=0;
668 Uncomment this to test if the remote client actually verifies signatures...*/
670 /* Don't mess with the sequence number for a deferred packet. */
671 if (was_deferred_packet
) {
675 if (!data
->trans_info
) {
676 /* Always increment if not in a trans stream. */
677 data
->send_seq_num
++;
678 } else if ((data
->trans_info
->send_seq_num
== data
->send_seq_num
) || (data
->trans_info
->mid
!= mid
)) {
679 /* Increment if this is the first reply in a trans stream or a
680 * packet that doesn't belong to this stream (different mid). */
681 data
->send_seq_num
++;
685 /***********************************************************
686 Is an incoming packet an oplock break reply ?
687 ************************************************************/
689 static BOOL
is_oplock_break(char *inbuf
)
691 if (CVAL(inbuf
,smb_com
) != SMBlockingX
)
694 if (!(CVAL(inbuf
,smb_vwv3
) & LOCKING_ANDX_OPLOCK_RELEASE
))
697 DEBUG(10,("is_oplock_break: Packet is oplock break\n"));
701 /***********************************************************
702 SMB signing - Server implementation - check a MAC sent by server.
703 ************************************************************/
705 static BOOL
srv_check_incoming_message(char *inbuf
, struct smb_sign_info
*si
, BOOL must_be_ok
)
708 struct smb_basic_signing_context
*data
= si
->signing_context
;
709 uint32 reply_seq_number
= data
->send_seq_num
;
711 unsigned char calc_md5_mac
[16];
712 unsigned char *server_sent_mac
;
715 if (!si
->doing_signing
)
718 if (smb_len(inbuf
) < (smb_ss_field
+ 8 - 4)) {
719 DEBUG(1, ("srv_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf
)));
723 mid
= SVAL(inbuf
, smb_mid
);
725 /* Is this part of a trans stream ? */
726 if (data
->trans_info
&& (data
->trans_info
->mid
== mid
)) {
727 /* If so we don't increment the sequence. */
728 reply_seq_number
= data
->trans_info
->reply_seq_num
;
730 /* We always increment the sequence number. */
731 data
->send_seq_num
++;
733 /* If we get an asynchronous oplock break reply and there
734 * isn't a reply pending we need to re-sync the sequence
737 if (is_oplock_break(inbuf
)) {
738 DEBUG(10,("srv_check_incoming_message: oplock break at seq num %u\n", data
->send_seq_num
));
739 data
->send_seq_num
++;
743 saved_seq
= reply_seq_number
;
744 simple_packet_signature(data
, (const unsigned char *)inbuf
, reply_seq_number
, calc_md5_mac
);
746 server_sent_mac
= (unsigned char *)&inbuf
[smb_ss_field
];
747 good
= (memcmp(server_sent_mac
, calc_md5_mac
, 8) == 0);
751 DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n",
752 (unsigned int)saved_seq
));
753 dump_data(5, (const char *)calc_md5_mac
, 8);
755 DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n",
756 (unsigned int)saved_seq
));
757 dump_data(5, (const char *)server_sent_mac
, 8);
762 reply_seq_number
-= 5;
763 for (i
= 0; i
< 10; i
++, reply_seq_number
++) {
764 simple_packet_signature(data
, (const unsigned char *)inbuf
, reply_seq_number
, calc_md5_mac
);
765 if (memcmp(server_sent_mac
, calc_md5_mac
, 8) == 0) {
766 DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches. \
767 We were expecting seq %u\n", reply_seq_number
, saved_seq
));
775 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
));
776 dump_data(10, (const char *)server_sent_mac
, 8);
779 return (signing_good(inbuf
, si
, good
, saved_seq
, must_be_ok
));
782 /***********************************************************
783 SMB signing - server API's.
784 ************************************************************/
786 static struct smb_sign_info srv_sign_info
= {
787 null_sign_outgoing_message
,
788 null_check_incoming_message
,
789 null_free_signing_context
,
797 /***********************************************************
798 Turn signing off or on for oplock break code.
799 ************************************************************/
801 BOOL
srv_oplock_set_signing(BOOL onoff
)
803 BOOL ret
= srv_sign_info
.doing_signing
;
804 srv_sign_info
.doing_signing
= onoff
;
808 /***********************************************************
809 Called to validate an incoming packet from the client.
810 ************************************************************/
812 BOOL
srv_check_sign_mac(char *inbuf
, BOOL must_be_ok
)
814 /* Check if it's a session keepalive. */
815 if(CVAL(inbuf
,0) == SMBkeepalive
)
818 return srv_sign_info
.check_incoming_message(inbuf
, &srv_sign_info
, must_be_ok
);
821 /***********************************************************
822 Called to sign an outgoing packet to the client.
823 ************************************************************/
825 void srv_calculate_sign_mac(char *outbuf
)
827 /* Check if it's a session keepalive. */
828 /* JRA Paranioa test - do we ever generate these in the server ? */
829 if(CVAL(outbuf
,0) == SMBkeepalive
)
832 srv_sign_info
.sign_outgoing_message(outbuf
, &srv_sign_info
);
835 /***********************************************************
836 Called by server to defer an outgoing packet.
837 ************************************************************/
839 void srv_defer_sign_response(uint16 mid
)
841 struct smb_basic_signing_context
*data
;
843 if (!srv_sign_info
.doing_signing
)
846 data
= (struct smb_basic_signing_context
*)srv_sign_info
.signing_context
;
851 store_sequence_for_reply(&data
->outstanding_packet_list
,
852 mid
, data
->send_seq_num
);
853 data
->send_seq_num
++;
856 /***********************************************************
857 Called to remove sequence records when a deferred packet is
858 cancelled by mid. This should never find one....
859 ************************************************************/
861 void srv_cancel_sign_response(uint16 mid
)
863 struct smb_basic_signing_context
*data
;
866 if (!srv_sign_info
.doing_signing
)
869 data
= (struct smb_basic_signing_context
*)srv_sign_info
.signing_context
;
874 DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid
));
876 while (get_sequence_for_reply(&data
->outstanding_packet_list
, mid
, &dummy_seq
))
880 /***********************************************************
881 Called by server negprot when signing has been negotiated.
882 ************************************************************/
884 void srv_set_signing_negotiated(void)
886 srv_sign_info
.allow_smb_signing
= True
;
887 srv_sign_info
.negotiated_smb_signing
= True
;
888 if (lp_server_signing() == Required
)
889 srv_sign_info
.mandatory_signing
= True
;
891 srv_sign_info
.sign_outgoing_message
= temp_sign_outgoing_message
;
892 srv_sign_info
.check_incoming_message
= temp_check_incoming_message
;
893 srv_sign_info
.free_signing_context
= temp_free_signing_context
;
896 /***********************************************************
897 Returns whether signing is active. We can't use sendfile or raw
898 reads/writes if it is.
899 ************************************************************/
901 BOOL
srv_is_signing_active(void)
903 return srv_sign_info
.doing_signing
;
907 /***********************************************************
908 Returns whether signing is negotiated. We can't use it unless it was
910 ************************************************************/
912 BOOL
srv_is_signing_negotiated(void)
914 return srv_sign_info
.negotiated_smb_signing
;
917 /***********************************************************
918 Returns whether signing is actually happening
919 ************************************************************/
921 BOOL
srv_signing_started(void)
923 struct smb_basic_signing_context
*data
;
925 if (!srv_sign_info
.doing_signing
) {
929 data
= (struct smb_basic_signing_context
*)srv_sign_info
.signing_context
;
933 if (data
->send_seq_num
== 0) {
941 /***********************************************************
942 Tell server code we are in a multiple trans reply state.
943 ************************************************************/
945 void srv_signing_trans_start(uint16 mid
)
947 struct smb_basic_signing_context
*data
;
949 if (!srv_sign_info
.doing_signing
)
952 data
= (struct smb_basic_signing_context
*)srv_sign_info
.signing_context
;
956 data
->trans_info
= smb_xmalloc(sizeof(struct trans_info_context
));
957 ZERO_STRUCTP(data
->trans_info
);
959 data
->trans_info
->reply_seq_num
= data
->send_seq_num
-1;
960 data
->trans_info
->mid
= mid
;
961 data
->trans_info
->send_seq_num
= data
->send_seq_num
;
963 DEBUG(10,("srv_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \
964 data->send_seq_num = %u\n",
966 (unsigned int)data
->trans_info
->reply_seq_num
,
967 (unsigned int)data
->trans_info
->send_seq_num
,
968 (unsigned int)data
->send_seq_num
));
971 /***********************************************************
972 Tell server code we are out of a multiple trans reply state.
973 ************************************************************/
975 void srv_signing_trans_stop(void)
977 struct smb_basic_signing_context
*data
;
979 if (!srv_sign_info
.doing_signing
)
982 data
= (struct smb_basic_signing_context
*)srv_sign_info
.signing_context
;
983 if (!data
|| !data
->trans_info
)
986 DEBUG(10,("srv_signing_trans_stop: removing mid = %u, reply_seq_num = %u, send_seq_num = %u \
987 data->send_seq_num = %u\n",
988 (unsigned int)data
->trans_info
->mid
,
989 (unsigned int)data
->trans_info
->reply_seq_num
,
990 (unsigned int)data
->trans_info
->send_seq_num
,
991 (unsigned int)data
->send_seq_num
));
993 SAFE_FREE(data
->trans_info
);
994 data
->trans_info
= NULL
;
997 /***********************************************************
998 Turn on signing from this packet onwards.
999 ************************************************************/
1001 void srv_set_signing(const DATA_BLOB user_session_key
, const DATA_BLOB response
)
1003 struct smb_basic_signing_context
*data
;
1005 if (!user_session_key
.length
)
1008 if (!srv_sign_info
.negotiated_smb_signing
&& !srv_sign_info
.mandatory_signing
) {
1009 DEBUG(5,("srv_set_signing: signing negotiated = %u, mandatory_signing = %u. Not allowing smb signing.\n",
1010 (unsigned int)srv_sign_info
.negotiated_smb_signing
,
1011 (unsigned int)srv_sign_info
.mandatory_signing
));
1015 /* Once we've turned on, ignore any more sessionsetups. */
1016 if (srv_sign_info
.doing_signing
) {
1020 if (srv_sign_info
.free_signing_context
)
1021 srv_sign_info
.free_signing_context(&srv_sign_info
);
1023 srv_sign_info
.doing_signing
= True
;
1025 data
= smb_xmalloc(sizeof(*data
));
1026 memset(data
, '\0', sizeof(*data
));
1028 srv_sign_info
.signing_context
= data
;
1030 data
->mac_key
= data_blob(NULL
, response
.length
+ user_session_key
.length
);
1032 memcpy(&data
->mac_key
.data
[0], user_session_key
.data
, user_session_key
.length
);
1033 if (response
.length
)
1034 memcpy(&data
->mac_key
.data
[user_session_key
.length
],response
.data
, response
.length
);
1036 dump_data_pw("MAC ssession key is:\n", data
->mac_key
.data
, data
->mac_key
.length
);
1038 DEBUG(3,("srv_set_signing: turning on SMB signing: signing negotiated = %s, mandatory_signing = %s.\n",
1039 BOOLSTR(srv_sign_info
.negotiated_smb_signing
),
1040 BOOLSTR(srv_sign_info
.mandatory_signing
) ));
1042 /* Initialise the sequence number */
1043 data
->send_seq_num
= 0;
1045 /* Initialise the list of outstanding packets */
1046 data
->outstanding_packet_list
= NULL
;
1048 srv_sign_info
.sign_outgoing_message
= srv_sign_outgoing_message
;
1049 srv_sign_info
.check_incoming_message
= srv_check_incoming_message
;
1050 srv_sign_info
.free_signing_context
= simple_free_signing_context
;