Turns out I had my packet sequences wrong for oplock break code.
[tprouty/samba.git] / source / libsmb / smb_signing.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB Signing Code
4    Copyright (C) Jeremy Allison 2003.
5    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
6    
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.
11    
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.
16    
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.
20 */
21
22 #include "includes.h"
23
24 /* Lookup a packet's MID (multiplex id) and figure out it's sequence number */
25 struct outstanding_packet_lookup {
26         uint16 mid;
27         uint32 reply_seq_num;
28         BOOL deferred_packet;
29         struct outstanding_packet_lookup *prev, *next;
30 };
31
32 /* Store the data for an ongoing trans/trans2/nttrans operation. */
33 struct trans_info_context {
34         uint16 mid;
35         uint32 send_seq_num;
36         uint32 reply_seq_num;
37 };
38
39 struct smb_basic_signing_context {
40         DATA_BLOB mac_key;
41         uint32 send_seq_num;
42         struct trans_info_context *trans_info;
43         struct outstanding_packet_lookup *outstanding_packet_list;
44 };
45
46 static void store_sequence_for_reply(struct outstanding_packet_lookup **list, 
47                                      uint16 mid, uint32 reply_seq_num, BOOL deferred_pkt) 
48 {
49         struct outstanding_packet_lookup *t;
50         struct outstanding_packet_lookup *tmp;
51         
52         t = smb_xmalloc(sizeof(*t));
53         ZERO_STRUCTP(t);
54
55         DLIST_ADD_END(*list, t, tmp);
56         t->mid = mid;
57         t->reply_seq_num = reply_seq_num;
58         t->deferred_packet = deferred_pkt;
59
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 ));
63 }
64
65 static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list,
66                                    uint16 mid, uint32 *reply_seq_num, BOOL *def) 
67 {
68         struct outstanding_packet_lookup *t;
69
70         for (t = *list; t; t = t->next) {
71                 if (t->mid == mid) {
72                         *reply_seq_num = t->reply_seq_num;
73                         if (def)
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);
79                         SAFE_FREE(t);
80                         return True;
81                 }
82         }
83         return False;
84 }
85
86 /***********************************************************
87  SMB signing - Common code before we set a new signing implementation
88 ************************************************************/
89
90 static BOOL cli_set_smb_signing_common(struct cli_state *cli) 
91 {
92         if (!cli->sign_info.negotiated_smb_signing 
93             && !cli->sign_info.mandatory_signing) {
94                 return False;
95         }
96
97         if (cli->sign_info.doing_signing) {
98                 return False;
99         }
100         
101         if (cli->sign_info.free_signing_context)
102                 cli->sign_info.free_signing_context(&cli->sign_info);
103
104         /* These calls are INCOMPATIBLE with SMB signing */
105         cli->readbraw_supported = False;
106         cli->writebraw_supported = False;
107         
108         return True;
109 }
110
111 /***********************************************************
112  SMB signing - Common code for 'real' implementations
113 ************************************************************/
114
115 static BOOL set_smb_signing_real_common(struct smb_sign_info *si)
116 {
117         if (si->mandatory_signing) {
118                 DEBUG(5, ("Mandatory SMB signing enabled!\n"));
119         }
120
121         si->doing_signing = True;
122         DEBUG(5, ("SMB signing enabled!\n"));
123
124         return True;
125 }
126
127 static void mark_packet_signed(char *outbuf)
128 {
129         uint16 flags2;
130         flags2 = SVAL(outbuf,smb_flg2);
131         flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
132         SSVAL(outbuf,smb_flg2, flags2);
133 }
134
135 /***********************************************************
136  SMB signing - NULL implementation - calculate a MAC to send.
137 ************************************************************/
138
139 static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
140 {
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
143            have the field */
144         return;
145 }
146
147 /***********************************************************
148  SMB signing - NULL implementation - check a MAC sent by server.
149 ************************************************************/
150
151 static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si)
152 {
153         return True;
154 }
155
156 /***********************************************************
157  SMB signing - NULL implementation - free signing context
158 ************************************************************/
159
160 static void null_free_signing_context(struct smb_sign_info *si)
161 {
162         return;
163 }
164
165 /**
166  SMB signing - NULL implementation - setup the MAC key.
167
168  @note Used as an initialisation only - it will not correctly
169        shut down a real signing mechanism
170 */
171
172 static BOOL null_set_signing(struct smb_sign_info *si)
173 {
174         si->signing_context = NULL;
175         
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;
179
180         return True;
181 }
182
183 /**
184  * Free the signing context
185  */
186  
187 static void free_signing_context(struct smb_sign_info *si)
188 {
189         if (si->free_signing_context) {
190                 si->free_signing_context(si);
191                 si->signing_context = NULL;
192         }
193
194         null_set_signing(si);
195 }
196
197
198 static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq) 
199 {
200         if (good && !si->doing_signing) {
201                 si->doing_signing = True;
202         }
203
204         if (!good) {
205                 if (si->doing_signing) {
206                         struct smb_basic_signing_context *data = si->signing_context;
207
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 ));
212
213                         return False;
214                 } else {
215                         DEBUG(3, ("signing_good: Peer did not sign reply correctly\n"));
216                         free_signing_context(si);
217                         return False;
218                 }
219         }
220         return True;
221 }       
222
223 /***********************************************************
224  SMB signing - Simple implementation - calculate a MAC on the packet
225 ************************************************************/
226
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])
230 {
231         const size_t offset_end_of_sig = (smb_ss_field + 8);
232         unsigned char sequence_buf[8];
233         struct MD5Context md5_ctx;
234
235         /*
236          * Firstly put the sequence number into the first 4 bytes.
237          * and zero out the next 4 bytes.
238          *
239          * We do this here, to avoid modifying the packet.
240          */
241
242         DEBUG(10,("simple_packet_signature: sequence number %u\n", seq_number ));
243
244         SIVAL(sequence_buf, 0, seq_number);
245         SIVAL(sequence_buf, 4, 0);
246
247         /* Calculate the 16 byte MAC - but don't alter the data in the
248            incoming packet.
249            
250            This makes for a bit of fussing about, but it's not too bad.
251         */
252         MD5Init(&md5_ctx);
253
254         /* intialise with the key */
255         MD5Update(&md5_ctx, data->mac_key.data, 
256                   data->mac_key.length); 
257
258         /* copy in the first bit of the SMB header */
259         MD5Update(&md5_ctx, buf + 4, smb_ss_field - 4);
260
261         /* copy in the sequence number, instead of the signature */
262         MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf));
263
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));
267
268         /* calculate the MD5 sig */ 
269         MD5Final(calc_md5_mac, &md5_ctx);
270 }
271
272
273 /***********************************************************
274  SMB signing - Client implementation - send the MAC.
275 ************************************************************/
276
277 static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
278 {
279         unsigned char calc_md5_mac[16];
280         struct smb_basic_signing_context *data = si->signing_context;
281         uint32 send_seq_num;
282
283         if (!si->doing_signing)
284                 return;
285
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",
289                                         smb_len(outbuf) ));
290                 abort();
291         }
292
293         /* mark the packet as signed - BEFORE we sign it...*/
294         mark_packet_signed(outbuf);
295
296         if (data->trans_info)
297                 send_seq_num = data->trans_info->send_seq_num;
298         else
299                 send_seq_num = data->send_seq_num;
300
301         simple_packet_signature(data, outbuf, send_seq_num, calc_md5_mac);
302
303         DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n"));
304         dump_data(10, calc_md5_mac, 8);
305
306         memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8);
307
308 /*      cli->outbuf[smb_ss_field+2]=0; 
309         Uncomment this to test if the remote server actually verifies signatures...*/
310
311         if (data->trans_info)
312                 return;
313
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++;
319 }
320
321 /***********************************************************
322  SMB signing - Client implementation - check a MAC sent by server.
323 ************************************************************/
324
325 static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si)
326 {
327         BOOL good;
328         uint32 reply_seq_number;
329         uint32 saved_seq;
330         unsigned char calc_md5_mac[16];
331         unsigned char *server_sent_mac;
332
333         struct smb_basic_signing_context *data = si->signing_context;
334
335         if (!si->doing_signing)
336                 return True;
337
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)));
340                 return False;
341         }
342
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) ));
350                 return False;
351         }
352
353         saved_seq = reply_seq_number;
354         simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac);
355
356         server_sent_mac = &inbuf[smb_ss_field];
357         good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
358         
359         if (!good) {
360                 DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n"));
361                 dump_data(5, calc_md5_mac, 8);
362                 
363                 DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n"));
364                 dump_data(5, server_sent_mac, 8);
365 #if 1 /* JRATEST */
366                 {
367                         int i;
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",
373                                                         reply_seq_number ));
374                                         break;
375                                 }
376                         }
377                 }
378 #endif /* JRATEST */
379
380         } else {
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);
383         }
384         return signing_good(inbuf, si, good, saved_seq);
385 }
386
387 /***********************************************************
388  SMB signing - Simple implementation - free signing context
389 ************************************************************/
390
391 static void simple_free_signing_context(struct smb_sign_info *si)
392 {
393         struct smb_basic_signing_context *data = si->signing_context;
394         struct outstanding_packet_lookup *list = data->outstanding_packet_list;
395         
396         while (list) {
397                 struct outstanding_packet_lookup *old_head = list;
398                 DLIST_REMOVE(list, list);
399                 SAFE_FREE(old_head);
400         }
401
402         data_blob_free(&data->mac_key);
403
404         if (data->trans_info)
405                 SAFE_FREE(data->trans_info);
406
407         SAFE_FREE(si->signing_context);
408
409         return;
410 }
411
412 /***********************************************************
413  SMB signing - Simple implementation - setup the MAC key.
414 ************************************************************/
415
416 BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response)
417 {
418         struct smb_basic_signing_context *data;
419
420         if (!user_session_key)
421                 return False;
422
423         if (!cli_set_smb_signing_common(cli)) {
424                 return False;
425         }
426
427         if (!set_smb_signing_real_common(&cli->sign_info)) {
428                 return False;
429         }
430
431         data = smb_xmalloc(sizeof(*data));
432         memset(data, '\0', sizeof(*data));
433
434         cli->sign_info.signing_context = data;
435         
436         data->mac_key = data_blob(NULL, response.length + 16);
437
438         memcpy(&data->mac_key.data[0], user_session_key, 16);
439
440         DEBUG(10, ("cli_simple_set_signing: user_session_key\n"));
441         dump_data(10, user_session_key, 16);
442
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);
447         } else {
448                 DEBUG(10, ("cli_simple_set_signing: NULL response_data\n"));
449         }
450
451         /* Initialise the sequence number */
452         data->send_seq_num = 0;
453
454         /* Initialise the list of outstanding packets */
455         data->outstanding_packet_list = NULL;
456
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;
460
461         return True;
462 }
463
464 /***********************************************************
465  Tell client code we are in a multiple trans reply state.
466 ************************************************************/
467
468 void cli_signing_trans_start(struct cli_state *cli)
469 {
470         struct smb_basic_signing_context *data = cli->sign_info.signing_context;
471
472         if (!cli->sign_info.doing_signing || !data)
473                 return;
474
475         data->trans_info = smb_xmalloc(sizeof(struct trans_info_context));
476         ZERO_STRUCTP(data->trans_info);
477
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;
481
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 ));
488 }
489
490 /***********************************************************
491  Tell client code we are out of a multiple trans reply state.
492 ************************************************************/
493
494 void cli_signing_trans_stop(struct cli_state *cli)
495 {
496         struct smb_basic_signing_context *data = cli->sign_info.signing_context;
497
498         if (!cli->sign_info.doing_signing || !data)
499                 return;
500
501         SAFE_FREE(data->trans_info);
502         data->trans_info = NULL;
503
504         data->send_seq_num += 2;
505 }
506
507 /***********************************************************
508  SMB signing - TEMP implementation - calculate a MAC to send.
509 ************************************************************/
510
511 static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
512 {
513         /* mark the packet as signed - BEFORE we sign it...*/
514         mark_packet_signed(outbuf);
515
516         /* I wonder what BSRSPYL stands for - but this is what MS 
517            actually sends! */
518         memcpy(&outbuf[smb_ss_field], "BSRSPYL ", 8);
519         return;
520 }
521
522 /***********************************************************
523  SMB signing - TEMP implementation - check a MAC sent by server.
524 ************************************************************/
525
526 static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si)
527 {
528         return True;
529 }
530
531 /***********************************************************
532  SMB signing - TEMP implementation - free signing context
533 ************************************************************/
534
535 static void temp_free_signing_context(struct smb_sign_info *si)
536 {
537         return;
538 }
539
540 /***********************************************************
541  SMB signing - NULL implementation - setup the MAC key.
542 ************************************************************/
543
544 BOOL cli_null_set_signing(struct cli_state *cli)
545 {
546         return null_set_signing(&cli->sign_info);
547 }
548
549 /***********************************************************
550  SMB signing - temp implementation - setup the MAC key.
551 ************************************************************/
552
553 BOOL cli_temp_set_signing(struct cli_state *cli)
554 {
555         if (!cli_set_smb_signing_common(cli)) {
556                 return False;
557         }
558
559         cli->sign_info.signing_context = NULL;
560         
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;
564
565         return True;
566 }
567
568 void cli_free_signing_context(struct cli_state *cli)
569 {
570         free_signing_context(&cli->sign_info);
571 }
572
573 /**
574  * Sign a packet with the current mechanism
575  */
576  
577 void cli_calculate_sign_mac(struct cli_state *cli)
578 {
579         cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info);
580 }
581
582 /**
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.
586  */
587  
588 BOOL cli_check_sign_mac(struct cli_state *cli) 
589 {
590         if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info)) {
591                 free_signing_context(&cli->sign_info);  
592                 return False;
593         }
594         return True;
595 }
596
597 /***********************************************************
598  SMB signing - Server implementation - send the MAC.
599 ************************************************************/
600
601 static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
602 {
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;
607         uint16 mid;
608
609         if (!si->doing_signing) {
610                 return;
611         }
612
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",
616                                         smb_len(outbuf) ));
617                 abort();
618         }
619
620         /* mark the packet as signed - BEFORE we sign it...*/
621         mark_packet_signed(outbuf);
622
623         mid = SVAL(outbuf, smb_mid);
624
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);
627
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;
632         }
633
634         simple_packet_signature(data, outbuf, send_seq_number, calc_md5_mac);
635
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);
638
639         memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8);
640
641 /*      cli->outbuf[smb_ss_field+2]=0; 
642         Uncomment this to test if the remote server actually verifies signatures...*/
643
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++;
652                 }
653         } 
654 }
655
656 /***********************************************************
657  SMB signing - Server implementation - check a MAC sent by server.
658 ************************************************************/
659
660 static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si)
661 {
662         BOOL good;
663         struct smb_basic_signing_context *data = si->signing_context;
664         uint32 reply_seq_number = data->send_seq_num;
665         uint32 saved_seq;
666         unsigned char calc_md5_mac[16];
667         unsigned char *server_sent_mac;
668         uint mid;
669
670         if (!si->doing_signing)
671                 return True;
672
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)));
675                 return False;
676         }
677
678         mid = SVAL(inbuf, smb_mid);
679
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;
684         } else {
685                 /* We always increment the sequence number. */
686                 data->send_seq_num++;
687         }
688
689         saved_seq = reply_seq_number;
690         simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac);
691
692         server_sent_mac = &inbuf[smb_ss_field];
693         good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
694         
695         if (!good) {
696
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);
700                 
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);
704
705 #if 1 /* JRATEST */
706                 {
707                         int i;
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",
713                                                         reply_seq_number ));
714                                         break;
715                                 }
716                         }
717                 }
718 #endif /* JRATEST */
719
720         } else {
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);
723         }
724         return signing_good(inbuf, si, good, saved_seq);
725 }
726
727 /***********************************************************
728  SMB signing - server API's.
729 ************************************************************/
730
731 static struct smb_sign_info srv_sign_info = {
732         null_sign_outgoing_message,
733         null_check_incoming_message,
734         null_free_signing_context,
735         NULL,
736         False,
737         False,
738         False,
739         False
740 };
741
742 /***********************************************************
743  Turn signing off or on for oplock break code.
744 ************************************************************/
745
746 BOOL srv_oplock_set_signing(BOOL onoff)
747 {
748         BOOL ret = srv_sign_info.doing_signing;
749         srv_sign_info.doing_signing = onoff;
750         return ret;
751 }
752
753 /***********************************************************
754  Called to validate an incoming packet from the client.
755 ************************************************************/
756
757 BOOL srv_check_sign_mac(char *inbuf)
758 {
759         /* Check if it's a session keepalive. */
760         if(CVAL(inbuf,0) == SMBkeepalive)
761                 return True;
762
763         return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info);
764 }
765
766 /***********************************************************
767  Called to sign an outgoing packet to the client.
768 ************************************************************/
769
770 void srv_calculate_sign_mac(char *outbuf)
771 {
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)
775                 return;
776
777         srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info);
778 }
779
780 /***********************************************************
781  Called by server to defer an outgoing packet.
782 ************************************************************/
783
784 void srv_defer_sign_response(uint16 mid, BOOL deferred_packet)
785 {
786         struct smb_basic_signing_context *data;
787
788         if (!srv_sign_info.doing_signing)
789                 return;
790
791         data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
792
793         if (!data)
794                 return;
795
796         store_sequence_for_reply(&data->outstanding_packet_list, 
797                                  mid, data->send_seq_num, deferred_packet);
798         data->send_seq_num++;
799 }
800
801 /***********************************************************
802  Called to remove sequence records when a deferred packet is
803  cancelled by mid. This should never find one....
804 ************************************************************/
805
806 void srv_cancel_sign_response(uint16 mid)
807 {
808         struct smb_basic_signing_context *data;
809         uint32 dummy_seq;
810
811         if (!srv_sign_info.doing_signing)
812                 return;
813
814         data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
815
816         if (!data)
817                 return;
818
819         DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid ));
820
821         while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq,NULL))
822                 ;
823 }
824
825 /***********************************************************
826  Called by server negprot when signing has been negotiated.
827 ************************************************************/
828
829 void srv_set_signing_negotiated(void)
830 {
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;
835
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;
839 }
840
841 /***********************************************************
842  Returns whether signing is active. We can't use sendfile or raw
843  reads/writes if it is.
844 ************************************************************/
845
846 BOOL srv_is_signing_active(void)
847 {
848         return srv_sign_info.doing_signing;
849 }
850
851 /***********************************************************
852  Tell server code we are in a multiple trans reply state.
853 ************************************************************/
854
855 void srv_signing_trans_start(uint16 mid)
856 {
857         struct smb_basic_signing_context *data;
858
859         if (!srv_sign_info.doing_signing)
860                 return;
861
862         data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
863         if (!data)
864                 return;
865
866         data->trans_info = smb_xmalloc(sizeof(struct trans_info_context));
867         ZERO_STRUCTP(data->trans_info);
868
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;
872
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",
875                         (unsigned int)mid,
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 ));
879 }
880
881 /***********************************************************
882  Tell server code we are out of a multiple trans reply state.
883 ************************************************************/
884
885 void srv_signing_trans_stop(void)
886 {
887         struct smb_basic_signing_context *data;
888
889         if (!srv_sign_info.doing_signing)
890                 return;
891
892         data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
893         if (!data || !data->trans_info)
894                 return;
895
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 ));
902
903         SAFE_FREE(data->trans_info);
904         data->trans_info = NULL;
905 }
906
907 /***********************************************************
908  Turn on signing from this packet onwards. 
909 ************************************************************/
910
911 void srv_set_signing(const uchar user_session_key[16], const DATA_BLOB response)
912 {
913         struct smb_basic_signing_context *data;
914
915         if (!user_session_key)
916                 return;
917
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 ));
922                 return;
923         }
924
925         /* Once we've turned on, ignore any more sessionsetups. */
926         if (srv_sign_info.doing_signing) {
927                 return;
928         }
929         
930         if (srv_sign_info.free_signing_context)
931                 srv_sign_info.free_signing_context(&srv_sign_info);
932         
933         srv_sign_info.doing_signing = True;
934
935         data = smb_xmalloc(sizeof(*data));
936         memset(data, '\0', sizeof(*data));
937
938         srv_sign_info.signing_context = data;
939         
940         data->mac_key = data_blob(NULL, response.length + 16);
941
942         memcpy(&data->mac_key.data[0], user_session_key, 16);
943         if (response.length)
944                 memcpy(&data->mac_key.data[16],response.data, response.length);
945
946         /* Initialise the sequence number */
947         data->send_seq_num = 0;
948
949         /* Initialise the list of outstanding packets */
950         data->outstanding_packet_list = NULL;
951
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;
955 }