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 {
29 struct outstanding_packet_lookup *prev, *next;
32 /* Store the data for an ongoing trans/trans2/nttrans operation. */
33 struct trans_info_context {
39 struct smb_basic_signing_context {
42 struct trans_info_context *trans_info;
43 struct outstanding_packet_lookup *outstanding_packet_list;
46 static void store_sequence_for_reply(struct outstanding_packet_lookup **list,
47 uint16 mid, uint32 reply_seq_num, BOOL deferred_pkt)
49 struct outstanding_packet_lookup *t;
50 struct outstanding_packet_lookup *tmp;
52 t = smb_xmalloc(sizeof(*t));
55 DLIST_ADD_END(*list, t, tmp);
57 t->reply_seq_num = reply_seq_num;
58 t->deferred_packet = deferred_pkt;
60 DEBUG(10,("store_sequence_for_reply: stored %sseq = %u mid = %u\n",
61 deferred_pkt ? "deferred " : "",
62 (unsigned int)reply_seq_num, (unsigned int)mid ));
65 static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list,
66 uint16 mid, uint32 *reply_seq_num, BOOL *def)
68 struct outstanding_packet_lookup *t;
70 for (t = *list; t; t = t->next) {
72 *reply_seq_num = t->reply_seq_num;
74 *def = t->deferred_packet;
75 DEBUG(10,("get_sequence_for_reply: found %sseq = %u mid = %u\n",
76 (t->deferred_packet) ? "deferred " : "",
77 (unsigned int)t->reply_seq_num, (unsigned int)t->mid ));
78 DLIST_REMOVE(*list, t);
86 /***********************************************************
87 SMB signing - Common code before we set a new signing implementation
88 ************************************************************/
90 static BOOL cli_set_smb_signing_common(struct cli_state *cli)
92 if (!cli->sign_info.negotiated_smb_signing
93 && !cli->sign_info.mandatory_signing) {
97 if (cli->sign_info.doing_signing) {
101 if (cli->sign_info.free_signing_context)
102 cli->sign_info.free_signing_context(&cli->sign_info);
104 /* These calls are INCOMPATIBLE with SMB signing */
105 cli->readbraw_supported = False;
106 cli->writebraw_supported = False;
111 /***********************************************************
112 SMB signing - Common code for 'real' implementations
113 ************************************************************/
115 static BOOL set_smb_signing_real_common(struct smb_sign_info *si)
117 if (si->mandatory_signing) {
118 DEBUG(5, ("Mandatory SMB signing enabled!\n"));
121 si->doing_signing = True;
122 DEBUG(5, ("SMB signing enabled!\n"));
127 static void mark_packet_signed(char *outbuf)
130 flags2 = SVAL(outbuf,smb_flg2);
131 flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
132 SSVAL(outbuf,smb_flg2, flags2);
135 /***********************************************************
136 SMB signing - NULL implementation - calculate a MAC to send.
137 ************************************************************/
139 static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
141 /* we can't zero out the sig, as we might be trying to send a
142 session request - which is NBT-level, not SMB level and doesn't
147 /***********************************************************
148 SMB signing - NULL implementation - check a MAC sent by server.
149 ************************************************************/
151 static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si)
156 /***********************************************************
157 SMB signing - NULL implementation - free signing context
158 ************************************************************/
160 static void null_free_signing_context(struct smb_sign_info *si)
166 SMB signing - NULL implementation - setup the MAC key.
168 @note Used as an initialisation only - it will not correctly
169 shut down a real signing mechanism
172 static BOOL null_set_signing(struct smb_sign_info *si)
174 si->signing_context = NULL;
176 si->sign_outgoing_message = null_sign_outgoing_message;
177 si->check_incoming_message = null_check_incoming_message;
178 si->free_signing_context = null_free_signing_context;
184 * Free the signing context
187 static void free_signing_context(struct smb_sign_info *si)
189 if (si->free_signing_context) {
190 si->free_signing_context(si);
191 si->signing_context = NULL;
194 null_set_signing(si);
198 static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq)
200 if (good && !si->doing_signing) {
201 si->doing_signing = True;
205 if (si->doing_signing) {
206 struct smb_basic_signing_context *data = si->signing_context;
208 /* W2K sends a bad first signature but the sign engine is on.... JRA. */
209 if (data->send_seq_num > 1)
210 DEBUG(1, ("signing_good: SMB signature check failed on seq %u!\n",
211 (unsigned int)seq ));
215 DEBUG(3, ("signing_good: Peer did not sign reply correctly\n"));
216 free_signing_context(si);
223 /***********************************************************
224 SMB signing - Simple implementation - calculate a MAC on the packet
225 ************************************************************/
227 static void simple_packet_signature(struct smb_basic_signing_context *data,
228 const uchar *buf, uint32 seq_number,
229 unsigned char calc_md5_mac[16])
231 const size_t offset_end_of_sig = (smb_ss_field + 8);
232 unsigned char sequence_buf[8];
233 struct MD5Context md5_ctx;
236 * Firstly put the sequence number into the first 4 bytes.
237 * and zero out the next 4 bytes.
239 * We do this here, to avoid modifying the packet.
242 DEBUG(10,("simple_packet_signature: sequence number %u\n", seq_number ));
244 SIVAL(sequence_buf, 0, seq_number);
245 SIVAL(sequence_buf, 4, 0);
247 /* Calculate the 16 byte MAC - but don't alter the data in the
250 This makes for a bit of fussing about, but it's not too bad.
254 /* intialise with the key */
255 MD5Update(&md5_ctx, data->mac_key.data,
256 data->mac_key.length);
258 /* copy in the first bit of the SMB header */
259 MD5Update(&md5_ctx, buf + 4, smb_ss_field - 4);
261 /* copy in the sequence number, instead of the signature */
262 MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf));
264 /* copy in the rest of the packet in, skipping the signature */
265 MD5Update(&md5_ctx, buf + offset_end_of_sig,
266 smb_len(buf) - (offset_end_of_sig - 4));
268 /* calculate the MD5 sig */
269 MD5Final(calc_md5_mac, &md5_ctx);
273 /***********************************************************
274 SMB signing - Client implementation - send the MAC.
275 ************************************************************/
277 static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
279 unsigned char calc_md5_mac[16];
280 struct smb_basic_signing_context *data = si->signing_context;
283 if (!si->doing_signing)
286 /* JRA Paranioa test - we should be able to get rid of this... */
287 if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) {
288 DEBUG(1, ("client_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n",
293 /* mark the packet as signed - BEFORE we sign it...*/
294 mark_packet_signed(outbuf);
296 if (data->trans_info)
297 send_seq_num = data->trans_info->send_seq_num;
299 send_seq_num = data->send_seq_num;
301 simple_packet_signature(data, outbuf, send_seq_num, calc_md5_mac);
303 DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n"));
304 dump_data(10, calc_md5_mac, 8);
306 memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8);
308 /* cli->outbuf[smb_ss_field+2]=0;
309 Uncomment this to test if the remote server actually verifies signatures...*/
311 if (data->trans_info)
314 data->send_seq_num++;
315 store_sequence_for_reply(&data->outstanding_packet_list,
316 SVAL(outbuf,smb_mid),
317 data->send_seq_num, False);
318 data->send_seq_num++;
321 /***********************************************************
322 SMB signing - Client implementation - check a MAC sent by server.
323 ************************************************************/
325 static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si)
328 uint32 reply_seq_number;
330 unsigned char calc_md5_mac[16];
331 unsigned char *server_sent_mac;
333 struct smb_basic_signing_context *data = si->signing_context;
335 if (!si->doing_signing)
338 if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) {
339 DEBUG(1, ("client_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf)));
343 if (data->trans_info) {
344 reply_seq_number = data->trans_info->reply_seq_num;
345 } else if (!get_sequence_for_reply(&data->outstanding_packet_list,
346 SVAL(inbuf, smb_mid),
347 &reply_seq_number, NULL)) {
348 DEBUG(1, ("client_check_incoming_message: failed to get sequence number %u for reply.\n",
349 (unsigned int) SVAL(inbuf, smb_mid) ));
353 saved_seq = reply_seq_number;
354 simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac);
356 server_sent_mac = &inbuf[smb_ss_field];
357 good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
360 DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n"));
361 dump_data(5, calc_md5_mac, 8);
363 DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n"));
364 dump_data(5, server_sent_mac, 8);
368 reply_seq_number -= 5;
369 for (i = 0; i < 10; i++, reply_seq_number++) {
370 simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac);
371 if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) {
372 DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches.\n",
381 DEBUG(10, ("client_check_incoming_message:: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number));
382 dump_data(10, server_sent_mac, 8);
384 return signing_good(inbuf, si, good, saved_seq);
387 /***********************************************************
388 SMB signing - Simple implementation - free signing context
389 ************************************************************/
391 static void simple_free_signing_context(struct smb_sign_info *si)
393 struct smb_basic_signing_context *data = si->signing_context;
394 struct outstanding_packet_lookup *list = data->outstanding_packet_list;
397 struct outstanding_packet_lookup *old_head = list;
398 DLIST_REMOVE(list, list);
402 data_blob_free(&data->mac_key);
404 if (data->trans_info)
405 SAFE_FREE(data->trans_info);
407 SAFE_FREE(si->signing_context);
412 /***********************************************************
413 SMB signing - Simple implementation - setup the MAC key.
414 ************************************************************/
416 BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response)
418 struct smb_basic_signing_context *data;
420 if (!user_session_key)
423 if (!cli_set_smb_signing_common(cli)) {
427 if (!set_smb_signing_real_common(&cli->sign_info)) {
431 data = smb_xmalloc(sizeof(*data));
432 memset(data, '\0', sizeof(*data));
434 cli->sign_info.signing_context = data;
436 data->mac_key = data_blob(NULL, response.length + 16);
438 memcpy(&data->mac_key.data[0], user_session_key, 16);
440 DEBUG(10, ("cli_simple_set_signing: user_session_key\n"));
441 dump_data(10, user_session_key, 16);
443 if (response.length) {
444 memcpy(&data->mac_key.data[16],response.data, response.length);
445 DEBUG(10, ("cli_simple_set_signing: response_data\n"));
446 dump_data(10, response.data, response.length);
448 DEBUG(10, ("cli_simple_set_signing: NULL response_data\n"));
451 /* Initialise the sequence number */
452 data->send_seq_num = 0;
454 /* Initialise the list of outstanding packets */
455 data->outstanding_packet_list = NULL;
457 cli->sign_info.sign_outgoing_message = client_sign_outgoing_message;
458 cli->sign_info.check_incoming_message = client_check_incoming_message;
459 cli->sign_info.free_signing_context = simple_free_signing_context;
464 /***********************************************************
465 Tell client code we are in a multiple trans reply state.
466 ************************************************************/
468 void cli_signing_trans_start(struct cli_state *cli)
470 struct smb_basic_signing_context *data = cli->sign_info.signing_context;
472 if (!cli->sign_info.doing_signing || !data)
475 data->trans_info = smb_xmalloc(sizeof(struct trans_info_context));
476 ZERO_STRUCTP(data->trans_info);
478 data->trans_info->send_seq_num = data->send_seq_num;
479 data->trans_info->mid = SVAL(cli->outbuf,smb_mid);
480 data->trans_info->reply_seq_num = data->send_seq_num+1;
482 DEBUG(10,("cli_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \
483 data->send_seq_num = %u\n",
484 (unsigned int)data->trans_info->mid,
485 (unsigned int)data->trans_info->reply_seq_num,
486 (unsigned int)data->trans_info->send_seq_num,
487 (unsigned int)data->send_seq_num ));
490 /***********************************************************
491 Tell client code we are out of a multiple trans reply state.
492 ************************************************************/
494 void cli_signing_trans_stop(struct cli_state *cli)
496 struct smb_basic_signing_context *data = cli->sign_info.signing_context;
498 if (!cli->sign_info.doing_signing || !data)
501 SAFE_FREE(data->trans_info);
502 data->trans_info = NULL;
504 data->send_seq_num += 2;
507 /***********************************************************
508 SMB signing - TEMP implementation - calculate a MAC to send.
509 ************************************************************/
511 static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
513 /* mark the packet as signed - BEFORE we sign it...*/
514 mark_packet_signed(outbuf);
516 /* I wonder what BSRSPYL stands for - but this is what MS
518 memcpy(&outbuf[smb_ss_field], "BSRSPYL ", 8);
522 /***********************************************************
523 SMB signing - TEMP implementation - check a MAC sent by server.
524 ************************************************************/
526 static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si)
531 /***********************************************************
532 SMB signing - TEMP implementation - free signing context
533 ************************************************************/
535 static void temp_free_signing_context(struct smb_sign_info *si)
540 /***********************************************************
541 SMB signing - NULL implementation - setup the MAC key.
542 ************************************************************/
544 BOOL cli_null_set_signing(struct cli_state *cli)
546 return null_set_signing(&cli->sign_info);
549 /***********************************************************
550 SMB signing - temp implementation - setup the MAC key.
551 ************************************************************/
553 BOOL cli_temp_set_signing(struct cli_state *cli)
555 if (!cli_set_smb_signing_common(cli)) {
559 cli->sign_info.signing_context = NULL;
561 cli->sign_info.sign_outgoing_message = temp_sign_outgoing_message;
562 cli->sign_info.check_incoming_message = temp_check_incoming_message;
563 cli->sign_info.free_signing_context = temp_free_signing_context;
568 void cli_free_signing_context(struct cli_state *cli)
570 free_signing_context(&cli->sign_info);
574 * Sign a packet with the current mechanism
577 void cli_calculate_sign_mac(struct cli_state *cli)
579 cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info);
583 * Check a packet with the current mechanism
584 * @return False if we had an established signing connection
585 * which had a bad checksum, True otherwise.
588 BOOL cli_check_sign_mac(struct cli_state *cli)
590 if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info)) {
591 free_signing_context(&cli->sign_info);
597 /***********************************************************
598 SMB signing - Server implementation - send the MAC.
599 ************************************************************/
601 static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
603 unsigned char calc_md5_mac[16];
604 struct smb_basic_signing_context *data = si->signing_context;
605 uint32 send_seq_number = data->send_seq_num;
606 BOOL was_deferred_packet = False;
609 if (!si->doing_signing) {
613 /* JRA Paranioa test - we should be able to get rid of this... */
614 if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) {
615 DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't send signature on short packet! smb_len = %u\n",
620 /* mark the packet as signed - BEFORE we sign it...*/
621 mark_packet_signed(outbuf);
623 mid = SVAL(outbuf, smb_mid);
625 /* See if this is a reply for a deferred packet. */
626 get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number, &was_deferred_packet);
628 if (data->trans_info && (data->trans_info->mid == mid)) {
629 /* This is a reply in a trans stream. Use the sequence
630 * number associated with the stream mid. */
631 send_seq_number = data->trans_info->send_seq_num;
634 simple_packet_signature(data, outbuf, send_seq_number, calc_md5_mac);
636 DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number));
637 dump_data(10, calc_md5_mac, 8);
639 memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8);
641 /* cli->outbuf[smb_ss_field+2]=0;
642 Uncomment this to test if the remote server actually verifies signatures...*/
644 if (!was_deferred_packet) {
645 if (!data->trans_info) {
646 /* Always increment if not in a trans stream. */
647 data->send_seq_num++;
648 } else if ((data->trans_info->send_seq_num == data->send_seq_num) || (data->trans_info->mid != mid)) {
649 /* Increment if this is the first reply in a trans stream or a
650 * packet that doesn't belong to this stream (different mid). */
651 data->send_seq_num++;
656 /***********************************************************
657 SMB signing - Server implementation - check a MAC sent by server.
658 ************************************************************/
660 static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si)
663 struct smb_basic_signing_context *data = si->signing_context;
664 uint32 reply_seq_number = data->send_seq_num;
666 unsigned char calc_md5_mac[16];
667 unsigned char *server_sent_mac;
670 if (!si->doing_signing)
673 if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) {
674 DEBUG(1, ("srv_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf)));
678 mid = SVAL(inbuf, smb_mid);
680 /* Is this part of a trans stream ? */
681 if (data->trans_info && (data->trans_info->mid == mid)) {
682 /* If so we don't increment the sequence. */
683 reply_seq_number = data->trans_info->reply_seq_num;
685 /* We always increment the sequence number. */
686 data->send_seq_num++;
689 saved_seq = reply_seq_number;
690 simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac);
692 server_sent_mac = &inbuf[smb_ss_field];
693 good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
697 DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n",
698 (unsigned int)saved_seq));
699 dump_data(5, calc_md5_mac, 8);
701 DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n",
702 (unsigned int)saved_seq));
703 dump_data(5, server_sent_mac, 8);
708 reply_seq_number -= 5;
709 for (i = 0; i < 10; i++, reply_seq_number++) {
710 simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac);
711 if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) {
712 DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches.\n",
721 DEBUG(10, ("srv_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number));
722 dump_data(10, server_sent_mac, 8);
724 return signing_good(inbuf, si, good, saved_seq);
727 /***********************************************************
728 SMB signing - server API's.
729 ************************************************************/
731 static struct smb_sign_info srv_sign_info = {
732 null_sign_outgoing_message,
733 null_check_incoming_message,
734 null_free_signing_context,
742 /***********************************************************
743 Turn signing off or on for oplock break code.
744 ************************************************************/
746 BOOL srv_oplock_set_signing(BOOL onoff)
748 BOOL ret = srv_sign_info.doing_signing;
749 srv_sign_info.doing_signing = onoff;
753 /***********************************************************
754 Called to validate an incoming packet from the client.
755 ************************************************************/
757 BOOL srv_check_sign_mac(char *inbuf)
759 /* Check if it's a session keepalive. */
760 if(CVAL(inbuf,0) == SMBkeepalive)
763 return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info);
766 /***********************************************************
767 Called to sign an outgoing packet to the client.
768 ************************************************************/
770 void srv_calculate_sign_mac(char *outbuf)
772 /* Check if it's a session keepalive. */
773 /* JRA Paranioa test - do we ever generate these in the server ? */
774 if(CVAL(outbuf,0) == SMBkeepalive)
777 srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info);
780 /***********************************************************
781 Called by server to defer an outgoing packet.
782 ************************************************************/
784 void srv_defer_sign_response(uint16 mid, BOOL deferred_packet)
786 struct smb_basic_signing_context *data;
788 if (!srv_sign_info.doing_signing)
791 data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
796 store_sequence_for_reply(&data->outstanding_packet_list,
797 mid, data->send_seq_num, deferred_packet);
798 data->send_seq_num++;
801 /***********************************************************
802 Called to remove sequence records when a deferred packet is
803 cancelled by mid. This should never find one....
804 ************************************************************/
806 void srv_cancel_sign_response(uint16 mid)
808 struct smb_basic_signing_context *data;
811 if (!srv_sign_info.doing_signing)
814 data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
819 DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid ));
821 while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq,NULL))
825 /***********************************************************
826 Called by server negprot when signing has been negotiated.
827 ************************************************************/
829 void srv_set_signing_negotiated(void)
831 srv_sign_info.allow_smb_signing = True;
832 srv_sign_info.negotiated_smb_signing = True;
833 if (lp_server_signing() == Required)
834 srv_sign_info.mandatory_signing = True;
836 srv_sign_info.sign_outgoing_message = temp_sign_outgoing_message;
837 srv_sign_info.check_incoming_message = temp_check_incoming_message;
838 srv_sign_info.free_signing_context = temp_free_signing_context;
841 /***********************************************************
842 Returns whether signing is active. We can't use sendfile or raw
843 reads/writes if it is.
844 ************************************************************/
846 BOOL srv_is_signing_active(void)
848 return srv_sign_info.doing_signing;
851 /***********************************************************
852 Tell server code we are in a multiple trans reply state.
853 ************************************************************/
855 void srv_signing_trans_start(uint16 mid)
857 struct smb_basic_signing_context *data;
859 if (!srv_sign_info.doing_signing)
862 data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
866 data->trans_info = smb_xmalloc(sizeof(struct trans_info_context));
867 ZERO_STRUCTP(data->trans_info);
869 data->trans_info->reply_seq_num = data->send_seq_num-1;
870 data->trans_info->mid = mid;
871 data->trans_info->send_seq_num = data->send_seq_num;
873 DEBUG(10,("srv_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \
874 data->send_seq_num = %u\n",
876 (unsigned int)data->trans_info->reply_seq_num,
877 (unsigned int)data->trans_info->send_seq_num,
878 (unsigned int)data->send_seq_num ));
881 /***********************************************************
882 Tell server code we are out of a multiple trans reply state.
883 ************************************************************/
885 void srv_signing_trans_stop(void)
887 struct smb_basic_signing_context *data;
889 if (!srv_sign_info.doing_signing)
892 data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
893 if (!data || !data->trans_info)
896 DEBUG(10,("srv_signing_trans_stop: removing mid = %u, reply_seq_num = %u, send_seq_num = %u \
897 data->send_seq_num = %u\n",
898 (unsigned int)data->trans_info->mid,
899 (unsigned int)data->trans_info->reply_seq_num,
900 (unsigned int)data->trans_info->send_seq_num,
901 (unsigned int)data->send_seq_num ));
903 SAFE_FREE(data->trans_info);
904 data->trans_info = NULL;
907 /***********************************************************
908 Turn on signing from this packet onwards.
909 ************************************************************/
911 void srv_set_signing(const uchar user_session_key[16], const DATA_BLOB response)
913 struct smb_basic_signing_context *data;
915 if (!user_session_key)
918 if (!srv_sign_info.negotiated_smb_signing && !srv_sign_info.mandatory_signing) {
919 DEBUG(5,("srv_set_signing: signing negotiated = %u, mandatory_signing = %u. Not allowing smb signing.\n",
920 (unsigned int)srv_sign_info.negotiated_smb_signing,
921 (unsigned int)srv_sign_info.mandatory_signing ));
925 /* Once we've turned on, ignore any more sessionsetups. */
926 if (srv_sign_info.doing_signing) {
930 if (srv_sign_info.free_signing_context)
931 srv_sign_info.free_signing_context(&srv_sign_info);
933 srv_sign_info.doing_signing = True;
935 data = smb_xmalloc(sizeof(*data));
936 memset(data, '\0', sizeof(*data));
938 srv_sign_info.signing_context = data;
940 data->mac_key = data_blob(NULL, response.length + 16);
942 memcpy(&data->mac_key.data[0], user_session_key, 16);
944 memcpy(&data->mac_key.data[16],response.data, response.length);
946 /* Initialise the sequence number */
947 data->send_seq_num = 0;
949 /* Initialise the list of outstanding packets */
950 data->outstanding_packet_list = NULL;
952 srv_sign_info.sign_outgoing_message = srv_sign_outgoing_message;
953 srv_sign_info.check_incoming_message = srv_check_incoming_message;
954 srv_sign_info.free_signing_context = simple_free_signing_context;