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;
58 DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n",
59 (unsigned int)reply_seq_num, (unsigned int)mid ));
62 static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list,
63 uint16 mid, uint32 *reply_seq_num)
65 struct outstanding_packet_lookup *t;
67 for (t = *list; t; t = t->next) {
69 *reply_seq_num = t->reply_seq_num;
70 DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n",
71 (unsigned int)t->reply_seq_num, (unsigned int)t->mid ));
72 DLIST_REMOVE(*list, t);
80 /***********************************************************
81 SMB signing - Common code before we set a new signing implementation
82 ************************************************************/
84 static BOOL cli_set_smb_signing_common(struct cli_state *cli)
86 if (!cli->sign_info.negotiated_smb_signing
87 && !cli->sign_info.mandatory_signing) {
91 if (cli->sign_info.doing_signing) {
95 if (cli->sign_info.free_signing_context)
96 cli->sign_info.free_signing_context(&cli->sign_info);
98 /* These calls are INCOMPATIBLE with SMB signing */
99 cli->readbraw_supported = False;
100 cli->writebraw_supported = False;
105 /***********************************************************
106 SMB signing - Common code for 'real' implementations
107 ************************************************************/
109 static BOOL set_smb_signing_real_common(struct smb_sign_info *si)
111 if (si->mandatory_signing) {
112 DEBUG(5, ("Mandatory SMB signing enabled!\n"));
115 si->doing_signing = True;
116 DEBUG(5, ("SMB signing enabled!\n"));
121 static void mark_packet_signed(char *outbuf)
124 flags2 = SVAL(outbuf,smb_flg2);
125 flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
126 SSVAL(outbuf,smb_flg2, flags2);
129 /***********************************************************
130 SMB signing - NULL implementation - calculate a MAC to send.
131 ************************************************************/
133 static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
135 /* we can't zero out the sig, as we might be trying to send a
136 session request - which is NBT-level, not SMB level and doesn't
141 /***********************************************************
142 SMB signing - NULL implementation - check a MAC sent by server.
143 ************************************************************/
145 static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si)
150 /***********************************************************
151 SMB signing - NULL implementation - free signing context
152 ************************************************************/
154 static void null_free_signing_context(struct smb_sign_info *si)
160 SMB signing - NULL implementation - setup the MAC key.
162 @note Used as an initialisation only - it will not correctly
163 shut down a real signing mechanism
166 static BOOL null_set_signing(struct smb_sign_info *si)
168 si->signing_context = NULL;
170 si->sign_outgoing_message = null_sign_outgoing_message;
171 si->check_incoming_message = null_check_incoming_message;
172 si->free_signing_context = null_free_signing_context;
178 * Free the signing context
181 static void free_signing_context(struct smb_sign_info *si)
183 if (si->free_signing_context) {
184 si->free_signing_context(si);
185 si->signing_context = NULL;
188 null_set_signing(si);
192 static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq)
194 if (good && !si->doing_signing) {
195 si->doing_signing = True;
199 if (si->doing_signing) {
200 struct smb_basic_signing_context *data = si->signing_context;
202 /* W2K sends a bad first signature but the sign engine is on.... JRA. */
203 if (data->send_seq_num > 1)
204 DEBUG(1, ("signing_good: SMB signature check failed on seq %u!\n",
205 (unsigned int)seq ));
209 DEBUG(3, ("signing_good: Peer did not sign reply correctly\n"));
210 free_signing_context(si);
217 /***********************************************************
218 SMB signing - Simple implementation - calculate a MAC on the packet
219 ************************************************************/
221 static void simple_packet_signature(struct smb_basic_signing_context *data,
222 const uchar *buf, uint32 seq_number,
223 unsigned char calc_md5_mac[16])
225 const size_t offset_end_of_sig = (smb_ss_field + 8);
226 unsigned char sequence_buf[8];
227 struct MD5Context md5_ctx;
230 * Firstly put the sequence number into the first 4 bytes.
231 * and zero out the next 4 bytes.
233 * We do this here, to avoid modifying the packet.
236 DEBUG(10,("simple_packet_signature: sequence number %u\n", seq_number ));
238 SIVAL(sequence_buf, 0, seq_number);
239 SIVAL(sequence_buf, 4, 0);
241 /* Calculate the 16 byte MAC - but don't alter the data in the
244 This makes for a bit of fussing about, but it's not too bad.
248 /* intialise with the key */
249 MD5Update(&md5_ctx, data->mac_key.data,
250 data->mac_key.length);
252 /* copy in the first bit of the SMB header */
253 MD5Update(&md5_ctx, buf + 4, smb_ss_field - 4);
255 /* copy in the sequence number, instead of the signature */
256 MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf));
258 /* copy in the rest of the packet in, skipping the signature */
259 MD5Update(&md5_ctx, buf + offset_end_of_sig,
260 smb_len(buf) - (offset_end_of_sig - 4));
262 /* calculate the MD5 sig */
263 MD5Final(calc_md5_mac, &md5_ctx);
267 /***********************************************************
268 SMB signing - Client implementation - send the MAC.
269 ************************************************************/
271 static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
273 unsigned char calc_md5_mac[16];
274 struct smb_basic_signing_context *data = si->signing_context;
277 if (!si->doing_signing)
280 /* JRA Paranioa test - we should be able to get rid of this... */
281 if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) {
282 DEBUG(1, ("client_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n",
287 /* mark the packet as signed - BEFORE we sign it...*/
288 mark_packet_signed(outbuf);
290 if (data->trans_info)
291 send_seq_num = data->trans_info->send_seq_num;
293 send_seq_num = data->send_seq_num;
295 simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_num, calc_md5_mac);
297 DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n"));
298 dump_data(10, (const char *)calc_md5_mac, 8);
300 memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8);
302 /* cli->outbuf[smb_ss_field+2]=0;
303 Uncomment this to test if the remote server actually verifies signatures...*/
305 if (data->trans_info)
308 data->send_seq_num++;
309 store_sequence_for_reply(&data->outstanding_packet_list,
310 SVAL(outbuf,smb_mid), data->send_seq_num);
311 data->send_seq_num++;
314 /***********************************************************
315 SMB signing - Client implementation - check a MAC sent by server.
316 ************************************************************/
318 static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si)
321 uint32 reply_seq_number;
323 unsigned char calc_md5_mac[16];
324 unsigned char *server_sent_mac;
326 struct smb_basic_signing_context *data = si->signing_context;
328 if (!si->doing_signing)
331 if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) {
332 DEBUG(1, ("client_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf)));
336 if (data->trans_info) {
337 reply_seq_number = data->trans_info->reply_seq_num;
338 } else if (!get_sequence_for_reply(&data->outstanding_packet_list,
339 SVAL(inbuf, smb_mid), &reply_seq_number)) {
340 DEBUG(1, ("client_check_incoming_message: failed to get sequence number %u for reply.\n",
341 (unsigned int) SVAL(inbuf, smb_mid) ));
345 saved_seq = reply_seq_number;
346 simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
348 server_sent_mac = (unsigned char *)&inbuf[smb_ss_field];
349 good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
352 DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n"));
353 dump_data(5, (const char *)calc_md5_mac, 8);
355 DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n"));
356 dump_data(5, (const char *)server_sent_mac, 8);
360 reply_seq_number -= 5;
361 for (i = 0; i < 10; i++, reply_seq_number++) {
362 simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
363 if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) {
364 DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches. \
365 We were expecting seq %u\n", reply_seq_number, saved_seq ));
373 DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number));
374 dump_data(10, (const char *)server_sent_mac, 8);
376 return signing_good(inbuf, si, good, saved_seq);
379 /***********************************************************
380 SMB signing - Simple implementation - free signing context
381 ************************************************************/
383 static void simple_free_signing_context(struct smb_sign_info *si)
385 struct smb_basic_signing_context *data = si->signing_context;
386 struct outstanding_packet_lookup *list = data->outstanding_packet_list;
389 struct outstanding_packet_lookup *old_head = list;
390 DLIST_REMOVE(list, list);
394 data_blob_free(&data->mac_key);
396 if (data->trans_info)
397 SAFE_FREE(data->trans_info);
399 SAFE_FREE(si->signing_context);
404 /***********************************************************
405 SMB signing - Simple implementation - setup the MAC key.
406 ************************************************************/
408 BOOL cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_key, const DATA_BLOB response)
410 struct smb_basic_signing_context *data;
412 if (!user_session_key.length)
415 if (!cli_set_smb_signing_common(cli)) {
419 if (!set_smb_signing_real_common(&cli->sign_info)) {
423 data = smb_xmalloc(sizeof(*data));
424 memset(data, '\0', sizeof(*data));
426 cli->sign_info.signing_context = data;
428 data->mac_key = data_blob(NULL, response.length + user_session_key.length);
430 memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length);
432 DEBUG(10, ("cli_simple_set_signing: user_session_key\n"));
433 dump_data(10, (const char *)user_session_key.data, user_session_key.length);
435 if (response.length) {
436 memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length);
437 DEBUG(10, ("cli_simple_set_signing: response_data\n"));
438 dump_data(10, (const char *)response.data, response.length);
440 DEBUG(10, ("cli_simple_set_signing: NULL response_data\n"));
443 dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length);
445 /* Initialise the sequence number */
446 data->send_seq_num = 0;
448 /* Initialise the list of outstanding packets */
449 data->outstanding_packet_list = NULL;
451 cli->sign_info.sign_outgoing_message = client_sign_outgoing_message;
452 cli->sign_info.check_incoming_message = client_check_incoming_message;
453 cli->sign_info.free_signing_context = simple_free_signing_context;
458 /***********************************************************
459 Tell client code we are in a multiple trans reply state.
460 We call this after the last outgoing trans2 packet (which
461 has incremented the sequence numbers), so we must save the
462 current mid and sequence number -2.
463 ************************************************************/
465 void cli_signing_trans_start(struct cli_state *cli, uint16 mid)
467 struct smb_basic_signing_context *data = cli->sign_info.signing_context;
469 if (!cli->sign_info.doing_signing || !data)
472 data->trans_info = smb_xmalloc(sizeof(struct trans_info_context));
473 ZERO_STRUCTP(data->trans_info);
475 data->trans_info->send_seq_num = data->send_seq_num-2;
476 data->trans_info->mid = mid;
477 data->trans_info->reply_seq_num = data->send_seq_num-1;
479 DEBUG(10,("cli_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \
480 data->send_seq_num = %u\n",
481 (unsigned int)data->trans_info->mid,
482 (unsigned int)data->trans_info->reply_seq_num,
483 (unsigned int)data->trans_info->send_seq_num,
484 (unsigned int)data->send_seq_num ));
487 /***********************************************************
488 Tell client code we are out of a multiple trans reply state.
489 ************************************************************/
491 void cli_signing_trans_stop(struct cli_state *cli)
493 struct smb_basic_signing_context *data = cli->sign_info.signing_context;
495 if (!cli->sign_info.doing_signing || !data)
498 DEBUG(10,("cli_signing_trans_stop: freeing mid = %u, reply_seq_num = %u, send_seq_num = %u \
499 data->send_seq_num = %u\n",
500 (unsigned int)data->trans_info->mid,
501 (unsigned int)data->trans_info->reply_seq_num,
502 (unsigned int)data->trans_info->send_seq_num,
503 (unsigned int)data->send_seq_num ));
505 SAFE_FREE(data->trans_info);
506 data->trans_info = NULL;
509 /***********************************************************
510 SMB signing - TEMP implementation - calculate a MAC to send.
511 ************************************************************/
513 static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
515 /* mark the packet as signed - BEFORE we sign it...*/
516 mark_packet_signed(outbuf);
518 /* I wonder what BSRSPYL stands for - but this is what MS
520 memcpy(&outbuf[smb_ss_field], "BSRSPYL ", 8);
524 /***********************************************************
525 SMB signing - TEMP implementation - check a MAC sent by server.
526 ************************************************************/
528 static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si)
533 /***********************************************************
534 SMB signing - TEMP implementation - free signing context
535 ************************************************************/
537 static void temp_free_signing_context(struct smb_sign_info *si)
542 /***********************************************************
543 SMB signing - NULL implementation - setup the MAC key.
544 ************************************************************/
546 BOOL cli_null_set_signing(struct cli_state *cli)
548 return null_set_signing(&cli->sign_info);
551 /***********************************************************
552 SMB signing - temp implementation - setup the MAC key.
553 ************************************************************/
555 BOOL cli_temp_set_signing(struct cli_state *cli)
557 if (!cli_set_smb_signing_common(cli)) {
561 cli->sign_info.signing_context = NULL;
563 cli->sign_info.sign_outgoing_message = temp_sign_outgoing_message;
564 cli->sign_info.check_incoming_message = temp_check_incoming_message;
565 cli->sign_info.free_signing_context = temp_free_signing_context;
570 void cli_free_signing_context(struct cli_state *cli)
572 free_signing_context(&cli->sign_info);
576 * Sign a packet with the current mechanism
579 void cli_calculate_sign_mac(struct cli_state *cli)
581 cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info);
585 * Check a packet with the current mechanism
586 * @return False if we had an established signing connection
587 * which had a bad checksum, True otherwise.
590 BOOL cli_check_sign_mac(struct cli_state *cli)
592 if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info)) {
593 free_signing_context(&cli->sign_info);
599 /***********************************************************
600 SMB signing - Server implementation - send the MAC.
601 ************************************************************/
603 static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
605 unsigned char calc_md5_mac[16];
606 struct smb_basic_signing_context *data = si->signing_context;
607 uint32 send_seq_number = data->send_seq_num;
608 BOOL was_deferred_packet = False;
611 if (!si->doing_signing) {
615 /* JRA Paranioa test - we should be able to get rid of this... */
616 if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) {
617 DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't send signature on short packet! smb_len = %u\n",
622 /* mark the packet as signed - BEFORE we sign it...*/
623 mark_packet_signed(outbuf);
625 mid = SVAL(outbuf, smb_mid);
627 /* See if this is a reply for a deferred packet. */
628 was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number);
630 if (data->trans_info && (data->trans_info->mid == mid)) {
631 /* This is a reply in a trans stream. Use the sequence
632 * number associated with the stream mid. */
633 send_seq_number = data->trans_info->send_seq_num;
636 simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_number, calc_md5_mac);
638 DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number));
639 dump_data(10, (const char *)calc_md5_mac, 8);
641 memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8);
643 /* cli->outbuf[smb_ss_field+2]=0;
644 Uncomment this to test if the remote client actually verifies signatures...*/
646 /* Don't mess with the sequence number for a deferred packet. */
647 if (was_deferred_packet) {
651 if (!data->trans_info) {
652 /* Always increment if not in a trans stream. */
653 data->send_seq_num++;
654 } else if ((data->trans_info->send_seq_num == data->send_seq_num) || (data->trans_info->mid != mid)) {
655 /* Increment if this is the first reply in a trans stream or a
656 * packet that doesn't belong to this stream (different mid). */
657 data->send_seq_num++;
661 /***********************************************************
662 Is an incoming packet an oplock break reply ?
663 ************************************************************/
665 static BOOL is_oplock_break(char *inbuf)
667 if (CVAL(inbuf,smb_com) != SMBlockingX)
670 if (!(CVAL(inbuf,smb_vwv3) & LOCKING_ANDX_OPLOCK_RELEASE))
673 DEBUG(10,("is_oplock_break: Packet is oplock break\n"));
677 /***********************************************************
678 SMB signing - Server implementation - check a MAC sent by server.
679 ************************************************************/
681 static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si)
684 struct smb_basic_signing_context *data = si->signing_context;
685 uint32 reply_seq_number = data->send_seq_num;
687 unsigned char calc_md5_mac[16];
688 unsigned char *server_sent_mac;
691 if (!si->doing_signing)
694 if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) {
695 DEBUG(1, ("srv_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf)));
699 mid = SVAL(inbuf, smb_mid);
701 /* Is this part of a trans stream ? */
702 if (data->trans_info && (data->trans_info->mid == mid)) {
703 /* If so we don't increment the sequence. */
704 reply_seq_number = data->trans_info->reply_seq_num;
706 /* We always increment the sequence number. */
707 data->send_seq_num++;
709 /* If we get an asynchronous oplock break reply and there
710 * isn't a reply pending we need to re-sync the sequence
713 if (is_oplock_break(inbuf)) {
714 DEBUG(10,("srv_check_incoming_message: oplock break at seq num %u\n", data->send_seq_num));
715 data->send_seq_num++;
719 saved_seq = reply_seq_number;
720 simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
722 server_sent_mac = (unsigned char *)&inbuf[smb_ss_field];
723 good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
727 DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n",
728 (unsigned int)saved_seq));
729 dump_data(5, (const char *)calc_md5_mac, 8);
731 DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n",
732 (unsigned int)saved_seq));
733 dump_data(5, (const char *)server_sent_mac, 8);
738 reply_seq_number -= 5;
739 for (i = 0; i < 10; i++, reply_seq_number++) {
740 simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
741 if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) {
742 DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches. \
743 We were expecting seq %u\n", reply_seq_number, saved_seq ));
751 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));
752 dump_data(10, (const char *)server_sent_mac, 8);
755 if (!signing_good(inbuf, si, good, saved_seq)) {
756 if (!si->mandatory_signing && (data->send_seq_num < 3)){
757 /* Non-mandatory signing - just turn off if this is the first bad packet.. */
758 DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and client \
759 isn't sending correct signatures. Turning off.\n"));
760 si->negotiated_smb_signing = False;
761 si->allow_smb_signing = False;
762 si->doing_signing = False;
763 free_signing_context(si);
766 /* Mandatory signing or bad packet after signing started - fail and disconnect. */
774 /***********************************************************
775 SMB signing - server API's.
776 ************************************************************/
778 static struct smb_sign_info srv_sign_info = {
779 null_sign_outgoing_message,
780 null_check_incoming_message,
781 null_free_signing_context,
789 /***********************************************************
790 Turn signing off or on for oplock break code.
791 ************************************************************/
793 BOOL srv_oplock_set_signing(BOOL onoff)
795 BOOL ret = srv_sign_info.doing_signing;
796 srv_sign_info.doing_signing = onoff;
800 /***********************************************************
801 Called to validate an incoming packet from the client.
802 ************************************************************/
804 BOOL srv_check_sign_mac(char *inbuf)
806 /* Check if it's a session keepalive. */
807 if(CVAL(inbuf,0) == SMBkeepalive)
810 return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info);
813 /***********************************************************
814 Called to sign an outgoing packet to the client.
815 ************************************************************/
817 void srv_calculate_sign_mac(char *outbuf)
819 /* Check if it's a session keepalive. */
820 /* JRA Paranioa test - do we ever generate these in the server ? */
821 if(CVAL(outbuf,0) == SMBkeepalive)
824 srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info);
827 /***********************************************************
828 Called by server to defer an outgoing packet.
829 ************************************************************/
831 void srv_defer_sign_response(uint16 mid)
833 struct smb_basic_signing_context *data;
835 if (!srv_sign_info.doing_signing)
838 data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
843 store_sequence_for_reply(&data->outstanding_packet_list,
844 mid, data->send_seq_num);
845 data->send_seq_num++;
848 /***********************************************************
849 Called to remove sequence records when a deferred packet is
850 cancelled by mid. This should never find one....
851 ************************************************************/
853 void srv_cancel_sign_response(uint16 mid)
855 struct smb_basic_signing_context *data;
858 if (!srv_sign_info.doing_signing)
861 data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
866 DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid ));
868 while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq))
872 /***********************************************************
873 Called by server negprot when signing has been negotiated.
874 ************************************************************/
876 void srv_set_signing_negotiated(void)
878 srv_sign_info.allow_smb_signing = True;
879 srv_sign_info.negotiated_smb_signing = True;
880 if (lp_server_signing() == Required)
881 srv_sign_info.mandatory_signing = True;
883 srv_sign_info.sign_outgoing_message = temp_sign_outgoing_message;
884 srv_sign_info.check_incoming_message = temp_check_incoming_message;
885 srv_sign_info.free_signing_context = temp_free_signing_context;
888 /***********************************************************
889 Returns whether signing is active. We can't use sendfile or raw
890 reads/writes if it is.
891 ************************************************************/
893 BOOL srv_is_signing_active(void)
895 return srv_sign_info.doing_signing;
898 /***********************************************************
899 Tell server code we are in a multiple trans reply state.
900 ************************************************************/
902 void srv_signing_trans_start(uint16 mid)
904 struct smb_basic_signing_context *data;
906 if (!srv_sign_info.doing_signing)
909 data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
913 data->trans_info = smb_xmalloc(sizeof(struct trans_info_context));
914 ZERO_STRUCTP(data->trans_info);
916 data->trans_info->reply_seq_num = data->send_seq_num-1;
917 data->trans_info->mid = mid;
918 data->trans_info->send_seq_num = data->send_seq_num;
920 DEBUG(10,("srv_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \
921 data->send_seq_num = %u\n",
923 (unsigned int)data->trans_info->reply_seq_num,
924 (unsigned int)data->trans_info->send_seq_num,
925 (unsigned int)data->send_seq_num ));
928 /***********************************************************
929 Tell server code we are out of a multiple trans reply state.
930 ************************************************************/
932 void srv_signing_trans_stop(void)
934 struct smb_basic_signing_context *data;
936 if (!srv_sign_info.doing_signing)
939 data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
940 if (!data || !data->trans_info)
943 DEBUG(10,("srv_signing_trans_stop: removing mid = %u, reply_seq_num = %u, send_seq_num = %u \
944 data->send_seq_num = %u\n",
945 (unsigned int)data->trans_info->mid,
946 (unsigned int)data->trans_info->reply_seq_num,
947 (unsigned int)data->trans_info->send_seq_num,
948 (unsigned int)data->send_seq_num ));
950 SAFE_FREE(data->trans_info);
951 data->trans_info = NULL;
954 /***********************************************************
955 Turn on signing from this packet onwards.
956 ************************************************************/
958 void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response)
960 struct smb_basic_signing_context *data;
962 if (!user_session_key.length)
965 if (!srv_sign_info.negotiated_smb_signing && !srv_sign_info.mandatory_signing) {
966 DEBUG(5,("srv_set_signing: signing negotiated = %u, mandatory_signing = %u. Not allowing smb signing.\n",
967 (unsigned int)srv_sign_info.negotiated_smb_signing,
968 (unsigned int)srv_sign_info.mandatory_signing ));
972 /* Once we've turned on, ignore any more sessionsetups. */
973 if (srv_sign_info.doing_signing) {
977 if (srv_sign_info.free_signing_context)
978 srv_sign_info.free_signing_context(&srv_sign_info);
980 srv_sign_info.doing_signing = True;
982 data = smb_xmalloc(sizeof(*data));
983 memset(data, '\0', sizeof(*data));
985 srv_sign_info.signing_context = data;
987 data->mac_key = data_blob(NULL, response.length + user_session_key.length);
989 memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length);
991 memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length);
993 dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length);
995 DEBUG(3,("srv_set_signing: turning on SMB signing: signing negotiated = %s, mandatory_signing = %s.\n",
996 BOOLSTR(srv_sign_info.negotiated_smb_signing),
997 BOOLSTR(srv_sign_info.mandatory_signing) ));
999 /* Initialise the sequence number */
1000 data->send_seq_num = 0;
1002 /* Initialise the list of outstanding packets */
1003 data->outstanding_packet_list = NULL;
1005 srv_sign_info.sign_outgoing_message = srv_sign_outgoing_message;
1006 srv_sign_info.check_incoming_message = srv_check_incoming_message;
1007 srv_sign_info.free_signing_context = simple_free_signing_context;