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
;
49 struct outstanding_packet_lookup
*tmp
;
51 t
= smb_xmalloc(sizeof(*t
));
54 DLIST_ADD_END(*list
, t
, tmp
);
56 t
->reply_seq_num
= reply_seq_num
;
57 DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n",
58 (unsigned int)reply_seq_num
, (unsigned int)mid
));
61 static BOOL
get_sequence_for_reply(struct outstanding_packet_lookup
**list
,
62 uint16 mid
, uint32
*reply_seq_num
)
64 struct outstanding_packet_lookup
*t
;
66 for (t
= *list
; t
; t
= t
->next
) {
68 *reply_seq_num
= t
->reply_seq_num
;
69 DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n",
70 (unsigned int)t
->reply_seq_num
, (unsigned int)t
->mid
));
71 DLIST_REMOVE(*list
, t
);
79 /***********************************************************
80 SMB signing - Common code before we set a new signing implementation
81 ************************************************************/
83 static BOOL
cli_set_smb_signing_common(struct cli_state
*cli
)
85 if (!cli
->sign_info
.negotiated_smb_signing
86 && !cli
->sign_info
.mandatory_signing
) {
90 if (cli
->sign_info
.doing_signing
) {
94 if (cli
->sign_info
.free_signing_context
)
95 cli
->sign_info
.free_signing_context(&cli
->sign_info
);
97 /* These calls are INCOMPATIBLE with SMB signing */
98 cli
->readbraw_supported
= False
;
99 cli
->writebraw_supported
= False
;
104 /***********************************************************
105 SMB signing - Common code for 'real' implementations
106 ************************************************************/
108 static BOOL
set_smb_signing_real_common(struct smb_sign_info
*si
)
110 if (si
->mandatory_signing
) {
111 DEBUG(5, ("Mandatory SMB signing enabled!\n"));
114 si
->doing_signing
= True
;
115 DEBUG(5, ("SMB signing enabled!\n"));
120 static void mark_packet_signed(char *outbuf
)
123 flags2
= SVAL(outbuf
,smb_flg2
);
124 flags2
|= FLAGS2_SMB_SECURITY_SIGNATURES
;
125 SSVAL(outbuf
,smb_flg2
, flags2
);
128 /***********************************************************
129 SMB signing - NULL implementation - calculate a MAC to send.
130 ************************************************************/
132 static void null_sign_outgoing_message(char *outbuf
, struct smb_sign_info
*si
)
134 /* we can't zero out the sig, as we might be trying to send a
135 session request - which is NBT-level, not SMB level and doesn't
140 /***********************************************************
141 SMB signing - NULL implementation - check a MAC sent by server.
142 ************************************************************/
144 static BOOL
null_check_incoming_message(char *inbuf
, struct smb_sign_info
*si
)
149 /***********************************************************
150 SMB signing - NULL implementation - free signing context
151 ************************************************************/
153 static void null_free_signing_context(struct smb_sign_info
*si
)
159 SMB signing - NULL implementation - setup the MAC key.
161 @note Used as an initialisation only - it will not correctly
162 shut down a real signing mechanism
165 static BOOL
null_set_signing(struct smb_sign_info
*si
)
167 si
->signing_context
= NULL
;
169 si
->sign_outgoing_message
= null_sign_outgoing_message
;
170 si
->check_incoming_message
= null_check_incoming_message
;
171 si
->free_signing_context
= null_free_signing_context
;
177 * Free the signing context
180 static void free_signing_context(struct smb_sign_info
*si
)
182 if (si
->free_signing_context
) {
183 si
->free_signing_context(si
);
184 si
->signing_context
= NULL
;
187 null_set_signing(si
);
191 static BOOL
signing_good(char *inbuf
, struct smb_sign_info
*si
, BOOL good
)
193 if (good
&& !si
->doing_signing
) {
194 si
->doing_signing
= True
;
198 if (si
->doing_signing
) {
199 struct smb_basic_signing_context
*data
= si
->signing_context
;
201 /* W2K sends a bad first signature but the sign engine is on.... JRA. */
202 if (data
->send_seq_num
> 1)
203 DEBUG(1, ("signing_good: SMB signature check failed!\n"));
207 DEBUG(3, ("signing_good: Peer did not sign reply correctly\n"));
208 free_signing_context(si
);
215 /***********************************************************
216 SMB signing - Simple implementation - calculate a MAC on the packet
217 ************************************************************/
219 static void simple_packet_signature(struct smb_basic_signing_context
*data
,
220 const uchar
*buf
, uint32 seq_number
,
221 unsigned char calc_md5_mac
[16])
223 const size_t offset_end_of_sig
= (smb_ss_field
+ 8);
224 unsigned char sequence_buf
[8];
225 struct MD5Context md5_ctx
;
228 * Firstly put the sequence number into the first 4 bytes.
229 * and zero out the next 4 bytes.
231 * We do this here, to avoid modifying the packet.
234 DEBUG(10,("simple_packet_signature: sequence number %u\n", seq_number
));
236 SIVAL(sequence_buf
, 0, seq_number
);
237 SIVAL(sequence_buf
, 4, 0);
239 /* Calculate the 16 byte MAC - but don't alter the data in the
242 This makes for a bit of fussing about, but it's not too bad.
246 /* intialise with the key */
247 MD5Update(&md5_ctx
, data
->mac_key
.data
,
248 data
->mac_key
.length
);
250 /* copy in the first bit of the SMB header */
251 MD5Update(&md5_ctx
, buf
+ 4, smb_ss_field
- 4);
253 /* copy in the sequence number, instead of the signature */
254 MD5Update(&md5_ctx
, sequence_buf
, sizeof(sequence_buf
));
256 /* copy in the rest of the packet in, skipping the signature */
257 MD5Update(&md5_ctx
, buf
+ offset_end_of_sig
,
258 smb_len(buf
) - (offset_end_of_sig
- 4));
260 /* calculate the MD5 sig */
261 MD5Final(calc_md5_mac
, &md5_ctx
);
265 /***********************************************************
266 SMB signing - Client implementation - send the MAC.
267 ************************************************************/
269 static void client_sign_outgoing_message(char *outbuf
, struct smb_sign_info
*si
)
271 unsigned char calc_md5_mac
[16];
272 struct smb_basic_signing_context
*data
= si
->signing_context
;
275 if (!si
->doing_signing
)
278 /* JRA Paranioa test - we should be able to get rid of this... */
279 if (smb_len(outbuf
) < (smb_ss_field
+ 8 - 4)) {
280 DEBUG(1, ("client_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n",
285 /* mark the packet as signed - BEFORE we sign it...*/
286 mark_packet_signed(outbuf
);
288 if (data
->trans_info
)
289 send_seq_num
= data
->trans_info
->send_seq_num
;
291 send_seq_num
= data
->send_seq_num
;
293 simple_packet_signature(data
, outbuf
, send_seq_num
, calc_md5_mac
);
295 DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n"));
296 dump_data(10, calc_md5_mac
, 8);
298 memcpy(&outbuf
[smb_ss_field
], calc_md5_mac
, 8);
300 /* cli->outbuf[smb_ss_field+2]=0;
301 Uncomment this to test if the remote server actually verifies signatures...*/
303 if (data
->trans_info
)
306 data
->send_seq_num
++;
307 store_sequence_for_reply(&data
->outstanding_packet_list
,
308 SVAL(outbuf
,smb_mid
),
310 data
->send_seq_num
++;
313 /***********************************************************
314 SMB signing - Client implementation - check a MAC sent by server.
315 ************************************************************/
317 static BOOL
client_check_incoming_message(char *inbuf
, struct smb_sign_info
*si
)
320 uint32 reply_seq_number
;
321 unsigned char calc_md5_mac
[16];
322 unsigned char *server_sent_mac
;
324 struct smb_basic_signing_context
*data
= si
->signing_context
;
326 if (!si
->doing_signing
)
329 if (smb_len(inbuf
) < (smb_ss_field
+ 8 - 4)) {
330 DEBUG(1, ("client_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf
)));
334 if (data
->trans_info
) {
335 reply_seq_number
= data
->trans_info
->reply_seq_num
;
336 } else if (!get_sequence_for_reply(&data
->outstanding_packet_list
,
337 SVAL(inbuf
, smb_mid
),
338 &reply_seq_number
)) {
339 DEBUG(1, ("client_check_incoming_message: failed to get sequence number %u for reply.\n",
340 (unsigned int) SVAL(inbuf
, smb_mid
) ));
344 simple_packet_signature(data
, inbuf
, reply_seq_number
, calc_md5_mac
);
346 server_sent_mac
= &inbuf
[smb_ss_field
];
347 good
= (memcmp(server_sent_mac
, calc_md5_mac
, 8) == 0);
350 DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n"));
351 dump_data(5, calc_md5_mac
, 8);
353 DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n"));
354 dump_data(5, server_sent_mac
, 8);
358 reply_seq_number
-= 5;
359 for (i
= 0; i
< 10; i
++, reply_seq_number
++) {
360 simple_packet_signature(data
, inbuf
, reply_seq_number
, calc_md5_mac
);
361 if (memcmp(server_sent_mac
, calc_md5_mac
, 8) == 0) {
362 DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches.\n",
371 DEBUG(10, ("client_check_incoming_message:: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number
));
372 dump_data(10, server_sent_mac
, 8);
374 return signing_good(inbuf
, si
, good
);
377 /***********************************************************
378 SMB signing - Simple implementation - free signing context
379 ************************************************************/
381 static void simple_free_signing_context(struct smb_sign_info
*si
)
383 struct smb_basic_signing_context
*data
= si
->signing_context
;
384 struct outstanding_packet_lookup
*list
= data
->outstanding_packet_list
;
387 struct outstanding_packet_lookup
*old_head
= list
;
388 DLIST_REMOVE(list
, list
);
392 data_blob_free(&data
->mac_key
);
394 if (data
->trans_info
)
395 SAFE_FREE(data
->trans_info
);
397 SAFE_FREE(si
->signing_context
);
402 /***********************************************************
403 SMB signing - Simple implementation - setup the MAC key.
404 ************************************************************/
406 BOOL
cli_simple_set_signing(struct cli_state
*cli
, const uchar user_session_key
[16], const DATA_BLOB response
)
408 struct smb_basic_signing_context
*data
;
410 if (!user_session_key
)
413 if (!cli_set_smb_signing_common(cli
)) {
417 if (!set_smb_signing_real_common(&cli
->sign_info
)) {
421 data
= smb_xmalloc(sizeof(*data
));
422 memset(data
, '\0', sizeof(*data
));
424 cli
->sign_info
.signing_context
= data
;
426 data
->mac_key
= data_blob(NULL
, response
.length
+ 16);
428 memcpy(&data
->mac_key
.data
[0], user_session_key
, 16);
430 DEBUG(10, ("cli_simple_set_signing: user_session_key\n"));
431 dump_data(10, user_session_key
, 16);
433 if (response
.length
) {
434 memcpy(&data
->mac_key
.data
[16],response
.data
, response
.length
);
435 DEBUG(10, ("cli_simple_set_signing: response_data\n"));
436 dump_data(10, response
.data
, response
.length
);
438 DEBUG(10, ("cli_simple_set_signing: NULL response_data\n"));
441 /* Initialise the sequence number */
442 data
->send_seq_num
= 0;
444 /* Initialise the list of outstanding packets */
445 data
->outstanding_packet_list
= NULL
;
447 cli
->sign_info
.sign_outgoing_message
= client_sign_outgoing_message
;
448 cli
->sign_info
.check_incoming_message
= client_check_incoming_message
;
449 cli
->sign_info
.free_signing_context
= simple_free_signing_context
;
454 /***********************************************************
455 Tell client code we are in a multiple trans reply state.
456 ************************************************************/
458 void cli_signing_trans_start(struct cli_state
*cli
)
460 struct smb_basic_signing_context
*data
= cli
->sign_info
.signing_context
;
462 if (!cli
->sign_info
.doing_signing
|| !data
)
465 data
->trans_info
= smb_xmalloc(sizeof(struct trans_info_context
));
466 ZERO_STRUCTP(data
->trans_info
);
468 data
->trans_info
->send_seq_num
= data
->send_seq_num
;
469 data
->trans_info
->mid
= SVAL(cli
->outbuf
,smb_mid
);
470 data
->trans_info
->reply_seq_num
= data
->send_seq_num
+1;
472 DEBUG(10,("cli_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \
473 data->send_seq_num = %u\n",
474 (unsigned int)data
->trans_info
->mid
,
475 (unsigned int)data
->trans_info
->reply_seq_num
,
476 (unsigned int)data
->trans_info
->send_seq_num
,
477 (unsigned int)data
->send_seq_num
));
480 /***********************************************************
481 Tell client code we are out of a multiple trans reply state.
482 ************************************************************/
484 void cli_signing_trans_stop(struct cli_state
*cli
)
486 struct smb_basic_signing_context
*data
= cli
->sign_info
.signing_context
;
488 if (!cli
->sign_info
.doing_signing
|| !data
)
491 SAFE_FREE(data
->trans_info
);
492 data
->trans_info
= NULL
;
494 data
->send_seq_num
+= 2;
497 /***********************************************************
498 SMB signing - TEMP implementation - calculate a MAC to send.
499 ************************************************************/
501 static void temp_sign_outgoing_message(char *outbuf
, struct smb_sign_info
*si
)
503 /* mark the packet as signed - BEFORE we sign it...*/
504 mark_packet_signed(outbuf
);
506 /* I wonder what BSRSPYL stands for - but this is what MS
508 memcpy(&outbuf
[smb_ss_field
], "BSRSPYL ", 8);
512 /***********************************************************
513 SMB signing - TEMP implementation - check a MAC sent by server.
514 ************************************************************/
516 static BOOL
temp_check_incoming_message(char *inbuf
, struct smb_sign_info
*si
)
521 /***********************************************************
522 SMB signing - TEMP implementation - free signing context
523 ************************************************************/
525 static void temp_free_signing_context(struct smb_sign_info
*si
)
530 /***********************************************************
531 SMB signing - NULL implementation - setup the MAC key.
532 ************************************************************/
534 BOOL
cli_null_set_signing(struct cli_state
*cli
)
536 return null_set_signing(&cli
->sign_info
);
539 /***********************************************************
540 SMB signing - temp implementation - setup the MAC key.
541 ************************************************************/
543 BOOL
cli_temp_set_signing(struct cli_state
*cli
)
545 if (!cli_set_smb_signing_common(cli
)) {
549 cli
->sign_info
.signing_context
= NULL
;
551 cli
->sign_info
.sign_outgoing_message
= temp_sign_outgoing_message
;
552 cli
->sign_info
.check_incoming_message
= temp_check_incoming_message
;
553 cli
->sign_info
.free_signing_context
= temp_free_signing_context
;
558 void cli_free_signing_context(struct cli_state
*cli
)
560 free_signing_context(&cli
->sign_info
);
564 * Sign a packet with the current mechanism
567 void cli_calculate_sign_mac(struct cli_state
*cli
)
569 cli
->sign_info
.sign_outgoing_message(cli
->outbuf
, &cli
->sign_info
);
573 * Check a packet with the current mechanism
574 * @return False if we had an established signing connection
575 * which had a bad checksum, True otherwise.
578 BOOL
cli_check_sign_mac(struct cli_state
*cli
)
580 if (!cli
->sign_info
.check_incoming_message(cli
->inbuf
, &cli
->sign_info
)) {
581 free_signing_context(&cli
->sign_info
);
587 static BOOL
packet_is_oplock_break(char *buf
)
589 if (CVAL(buf
,smb_com
) != SMBlockingX
)
592 if (CVAL(buf
,smb_vwv3
) != LOCKING_ANDX_OPLOCK_RELEASE
)
598 /***********************************************************
599 SMB signing - Server implementation - send the MAC.
600 ************************************************************/
602 static void srv_sign_outgoing_message(char *outbuf
, struct smb_sign_info
*si
)
604 unsigned char calc_md5_mac
[16];
605 struct smb_basic_signing_context
*data
= si
->signing_context
;
606 uint32 send_seq_number
= data
->send_seq_num
;
607 BOOL was_deferred_packet
= False
;
610 if (!si
->doing_signing
) {
611 if (si
->allow_smb_signing
&& si
->negotiated_smb_signing
) {
612 mid
= SVAL(outbuf
, smb_mid
);
614 was_deferred_packet
= get_sequence_for_reply(&data
->outstanding_packet_list
,
615 mid
, &send_seq_number
);
616 if (!was_deferred_packet
) {
618 * Is this an outgoing oplock break ? If so, store the
619 * mid in the outstanding list.
622 if (packet_is_oplock_break(outbuf
)) {
623 store_sequence_for_reply(&data
->outstanding_packet_list
,
624 mid
, data
->send_seq_num
);
627 data
->send_seq_num
++;
633 /* JRA Paranioa test - we should be able to get rid of this... */
634 if (smb_len(outbuf
) < (smb_ss_field
+ 8 - 4)) {
635 DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't send signature on short packet! smb_len = %u\n",
640 /* mark the packet as signed - BEFORE we sign it...*/
641 mark_packet_signed(outbuf
);
643 mid
= SVAL(outbuf
, smb_mid
);
645 /* See if this is a reply for a deferred packet. */
646 was_deferred_packet
= get_sequence_for_reply(&data
->outstanding_packet_list
, mid
, &send_seq_number
);
648 if (data
->trans_info
&& (data
->trans_info
->mid
== mid
)) {
649 /* This is a reply in a trans stream. Use the sequence
650 * number associated with the stream mid. */
651 send_seq_number
= data
->trans_info
->send_seq_num
;
654 simple_packet_signature(data
, outbuf
, send_seq_number
, calc_md5_mac
);
656 DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number
));
657 dump_data(10, calc_md5_mac
, 8);
659 memcpy(&outbuf
[smb_ss_field
], calc_md5_mac
, 8);
661 /* cli->outbuf[smb_ss_field+2]=0;
662 Uncomment this to test if the remote server actually verifies signatures...*/
664 if (!was_deferred_packet
) {
665 if (!data
->trans_info
) {
666 /* Always increment if not in a trans stream. */
667 data
->send_seq_num
++;
668 } else if ((data
->trans_info
->send_seq_num
== data
->send_seq_num
) || (data
->trans_info
->mid
!= mid
)) {
669 /* Increment if this is the first reply in a trans stream or a
670 * packet that doesn't belong to this stream (different mid). */
671 data
->send_seq_num
++;
676 /***********************************************************
677 SMB signing - Server implementation - check a MAC sent by server.
678 ************************************************************/
680 static BOOL
srv_check_incoming_message(char *inbuf
, struct smb_sign_info
*si
)
683 struct smb_basic_signing_context
*data
= si
->signing_context
;
684 uint32 reply_seq_number
= data
->send_seq_num
;
685 unsigned char calc_md5_mac
[16];
686 unsigned char *server_sent_mac
;
689 if (!si
->doing_signing
)
692 if (smb_len(inbuf
) < (smb_ss_field
+ 8 - 4)) {
693 DEBUG(1, ("srv_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf
)));
697 mid
= SVAL(inbuf
, smb_mid
);
699 /* Is this part of a trans stream ? */
700 if (data
->trans_info
&& (data
->trans_info
->mid
== mid
)) {
701 /* If so we don't increment the sequence. */
702 reply_seq_number
= data
->trans_info
->reply_seq_num
;
704 /* We always increment the sequence number. */
705 data
->send_seq_num
++;
706 /* Oplock break requests store an outgoing mid in the packet list. */
707 if (packet_is_oplock_break(inbuf
))
708 get_sequence_for_reply(&data
->outstanding_packet_list
, mid
, &reply_seq_number
);
711 simple_packet_signature(data
, inbuf
, reply_seq_number
, calc_md5_mac
);
713 server_sent_mac
= &inbuf
[smb_ss_field
];
714 good
= (memcmp(server_sent_mac
, calc_md5_mac
, 8) == 0);
718 DEBUG(5, ("srv_check_incoming_message: BAD SIG: wanted SMB signature of\n"));
719 dump_data(5, calc_md5_mac
, 8);
721 DEBUG(5, ("srv_check_incoming_message: BAD SIG: got SMB signature of\n"));
722 dump_data(5, server_sent_mac
, 8);
727 reply_seq_number
-= 5;
728 for (i
= 0; i
< 10; i
++, reply_seq_number
++) {
729 simple_packet_signature(data
, inbuf
, reply_seq_number
, calc_md5_mac
);
730 if (memcmp(server_sent_mac
, calc_md5_mac
, 8) == 0) {
731 DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches.\n",
740 DEBUG(10, ("srv_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number
));
741 dump_data(10, server_sent_mac
, 8);
743 return signing_good(inbuf
, si
, good
);
746 /***********************************************************
747 SMB signing - server API's.
748 ************************************************************/
750 static struct smb_sign_info srv_sign_info
= {
751 null_sign_outgoing_message
,
752 null_check_incoming_message
,
753 null_free_signing_context
,
761 /***********************************************************
762 Turn signing off or on for oplock break code.
763 ************************************************************/
765 BOOL
srv_oplock_set_signing(BOOL onoff
)
767 BOOL ret
= srv_sign_info
.doing_signing
;
768 srv_sign_info
.doing_signing
= onoff
;
772 /***********************************************************
773 Called to validate an incoming packet from the client.
774 ************************************************************/
776 BOOL
srv_check_sign_mac(char *inbuf
)
778 /* Check if it's a session keepalive. */
779 if(CVAL(inbuf
,0) == SMBkeepalive
)
782 return srv_sign_info
.check_incoming_message(inbuf
, &srv_sign_info
);
785 /***********************************************************
786 Called to sign an outgoing packet to the client.
787 ************************************************************/
789 void srv_calculate_sign_mac(char *outbuf
)
791 /* Check if it's a session keepalive. */
792 /* JRA Paranioa test - do we ever generate these in the server ? */
793 if(CVAL(outbuf
,0) == SMBkeepalive
)
796 srv_sign_info
.sign_outgoing_message(outbuf
, &srv_sign_info
);
799 /***********************************************************
800 Called by server to defer an outgoing packet.
801 ************************************************************/
803 void srv_defer_sign_response(uint16 mid
)
805 struct smb_basic_signing_context
*data
;
807 if (!srv_sign_info
.doing_signing
)
810 data
= (struct smb_basic_signing_context
*)srv_sign_info
.signing_context
;
815 store_sequence_for_reply(&data
->outstanding_packet_list
,
816 mid
, data
->send_seq_num
);
817 data
->send_seq_num
++;
820 /***********************************************************
821 Called to remove sequence records when a deferred packet is
822 cancelled by mid. This should never find one....
823 ************************************************************/
825 void srv_cancel_sign_response(uint16 mid
)
827 struct smb_basic_signing_context
*data
;
830 if (!srv_sign_info
.doing_signing
)
833 data
= (struct smb_basic_signing_context
*)srv_sign_info
.signing_context
;
838 DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid
));
840 while (get_sequence_for_reply(&data
->outstanding_packet_list
, mid
, &dummy_seq
))
844 /***********************************************************
845 Called by server negprot when signing has been negotiated.
846 ************************************************************/
848 void srv_set_signing_negotiated(void)
850 srv_sign_info
.allow_smb_signing
= True
;
851 srv_sign_info
.negotiated_smb_signing
= True
;
852 if (lp_server_signing() == Required
)
853 srv_sign_info
.mandatory_signing
= True
;
855 srv_sign_info
.sign_outgoing_message
= temp_sign_outgoing_message
;
856 srv_sign_info
.check_incoming_message
= temp_check_incoming_message
;
857 srv_sign_info
.free_signing_context
= temp_free_signing_context
;
860 /***********************************************************
861 Returns whether signing is active. We can't use sendfile or raw
862 reads/writes if it is.
863 ************************************************************/
865 BOOL
srv_is_signing_active(void)
867 return srv_sign_info
.doing_signing
;
870 /***********************************************************
871 Tell server code we are in a multiple trans reply state.
872 ************************************************************/
874 void srv_signing_trans_start(uint16 mid
)
876 struct smb_basic_signing_context
*data
;
878 if (!srv_sign_info
.doing_signing
)
881 data
= (struct smb_basic_signing_context
*)srv_sign_info
.signing_context
;
885 data
->trans_info
= smb_xmalloc(sizeof(struct trans_info_context
));
886 ZERO_STRUCTP(data
->trans_info
);
888 data
->trans_info
->reply_seq_num
= data
->send_seq_num
-1;
889 data
->trans_info
->mid
= mid
;
890 data
->trans_info
->send_seq_num
= data
->send_seq_num
;
892 DEBUG(10,("srv_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \
893 data->send_seq_num = %u\n",
895 (unsigned int)data
->trans_info
->reply_seq_num
,
896 (unsigned int)data
->trans_info
->send_seq_num
,
897 (unsigned int)data
->send_seq_num
));
900 /***********************************************************
901 Tell server code we are out of a multiple trans reply state.
902 ************************************************************/
904 void srv_signing_trans_stop(void)
906 struct smb_basic_signing_context
*data
;
908 if (!srv_sign_info
.doing_signing
)
911 data
= (struct smb_basic_signing_context
*)srv_sign_info
.signing_context
;
912 if (!data
|| !data
->trans_info
)
915 DEBUG(10,("srv_signing_trans_stop: removing mid = %u, reply_seq_num = %u, send_seq_num = %u \
916 data->send_seq_num = %u\n",
917 (unsigned int)data
->trans_info
->mid
,
918 (unsigned int)data
->trans_info
->reply_seq_num
,
919 (unsigned int)data
->trans_info
->send_seq_num
,
920 (unsigned int)data
->send_seq_num
));
922 SAFE_FREE(data
->trans_info
);
923 data
->trans_info
= NULL
;
926 /***********************************************************
927 Turn on signing from this packet onwards.
928 ************************************************************/
930 void srv_set_signing(const uchar user_session_key
[16], const DATA_BLOB response
)
932 struct smb_basic_signing_context
*data
;
934 if (!user_session_key
)
937 if (!srv_sign_info
.negotiated_smb_signing
&& !srv_sign_info
.mandatory_signing
) {
938 DEBUG(5,("srv_set_signing: signing negotiated = %u, mandatory_signing = %u. Not allowing smb signing.\n",
939 (unsigned int)srv_sign_info
.negotiated_smb_signing
,
940 (unsigned int)srv_sign_info
.mandatory_signing
));
944 /* Once we've turned on, ignore any more sessionsetups. */
945 if (srv_sign_info
.doing_signing
) {
949 if (srv_sign_info
.free_signing_context
)
950 srv_sign_info
.free_signing_context(&srv_sign_info
);
952 srv_sign_info
.doing_signing
= True
;
954 data
= smb_xmalloc(sizeof(*data
));
955 memset(data
, '\0', sizeof(*data
));
957 srv_sign_info
.signing_context
= data
;
959 data
->mac_key
= data_blob(NULL
, response
.length
+ 16);
961 memcpy(&data
->mac_key
.data
[0], user_session_key
, 16);
963 memcpy(&data
->mac_key
.data
[16],response
.data
, response
.length
);
965 /* Initialise the sequence number */
966 data
->send_seq_num
= 0;
968 /* Initialise the list of outstanding packets */
969 data
->outstanding_packet_list
= NULL
;
971 srv_sign_info
.sign_outgoing_message
= srv_sign_outgoing_message
;
972 srv_sign_info
.check_incoming_message
= srv_check_incoming_message
;
973 srv_sign_info
.free_signing_context
= simple_free_signing_context
;