r17431: Fix bug #4003, reported by dale-keyword-samba.c7b741@codefu.org.
[ira/wip.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         struct outstanding_packet_lookup *prev, *next;
27         uint16 mid;
28         uint32 reply_seq_num;
29         BOOL can_delete; /* Set to False in trans state. */
30 };
31
32 struct smb_basic_signing_context {
33         DATA_BLOB mac_key;
34         uint32 send_seq_num;
35         struct outstanding_packet_lookup *outstanding_packet_list;
36 };
37
38 static BOOL store_sequence_for_reply(struct outstanding_packet_lookup **list, 
39                                      uint16 mid, uint32 reply_seq_num)
40 {
41         struct outstanding_packet_lookup *t;
42
43         /* Ensure we only add a mid once. */
44         for (t = *list; t; t = t->next) {
45                 if (t->mid == mid) {
46                         return False;
47                 }
48         }
49
50         t = SMB_XMALLOC_P(struct outstanding_packet_lookup);
51         ZERO_STRUCTP(t);
52
53         t->mid = mid;
54         t->reply_seq_num = reply_seq_num;
55         t->can_delete = True;
56
57         /*
58          * Add to the *start* of the list not the end of the list.
59          * This ensures that the *last* send sequence with this mid
60          * is returned by preference.
61          * This can happen if the mid wraps and one of the early
62          * mid numbers didn't get a reply and is still lurking on
63          * the list. JRA. Found by Fran Fabrizio <fran@cis.uab.edu>.
64          */
65
66         DLIST_ADD(*list, t);
67         DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n",
68                         (unsigned int)reply_seq_num, (unsigned int)mid ));
69         return True;
70 }
71
72 static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list,
73                                    uint16 mid, uint32 *reply_seq_num)
74 {
75         struct outstanding_packet_lookup *t;
76
77         for (t = *list; t; t = t->next) {
78                 if (t->mid == mid) {
79                         *reply_seq_num = t->reply_seq_num;
80                         DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n",
81                                 (unsigned int)t->reply_seq_num, (unsigned int)t->mid ));
82                         if (t->can_delete) {
83                                 DLIST_REMOVE(*list, t);
84                                 SAFE_FREE(t);
85                         }
86                         return True;
87                 }
88         }
89         return False;
90 }
91
92 static BOOL set_sequence_can_delete_flag(struct outstanding_packet_lookup **list, uint16 mid, BOOL can_delete_entry)
93 {
94         struct outstanding_packet_lookup *t;
95
96         for (t = *list; t; t = t->next) {
97                 if (t->mid == mid) {
98                         t->can_delete = can_delete_entry;
99                         return True;
100                 }
101         }
102         return False;
103 }
104
105 /***********************************************************
106  SMB signing - Common code before we set a new signing implementation
107 ************************************************************/
108
109 static BOOL cli_set_smb_signing_common(struct cli_state *cli) 
110 {
111         if (!cli->sign_info.negotiated_smb_signing 
112             && !cli->sign_info.mandatory_signing) {
113                 return False;
114         }
115
116         if (cli->sign_info.doing_signing) {
117                 return False;
118         }
119         
120         if (cli->sign_info.free_signing_context)
121                 cli->sign_info.free_signing_context(&cli->sign_info);
122
123         /* These calls are INCOMPATIBLE with SMB signing */
124         cli->readbraw_supported = False;
125         cli->writebraw_supported = False;
126         
127         return True;
128 }
129
130 /***********************************************************
131  SMB signing - Common code for 'real' implementations
132 ************************************************************/
133
134 static BOOL set_smb_signing_real_common(struct smb_sign_info *si)
135 {
136         if (si->mandatory_signing) {
137                 DEBUG(5, ("Mandatory SMB signing enabled!\n"));
138         }
139
140         si->doing_signing = True;
141         DEBUG(5, ("SMB signing enabled!\n"));
142
143         return True;
144 }
145
146 static void mark_packet_signed(char *outbuf)
147 {
148         uint16 flags2;
149         flags2 = SVAL(outbuf,smb_flg2);
150         flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
151         SSVAL(outbuf,smb_flg2, flags2);
152 }
153
154 /***********************************************************
155  SMB signing - NULL implementation - calculate a MAC to send.
156 ************************************************************/
157
158 static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
159 {
160         /* we can't zero out the sig, as we might be trying to send a
161            session request - which is NBT-level, not SMB level and doesn't
162            have the field */
163         return;
164 }
165
166 /***********************************************************
167  SMB signing - NULL implementation - check a MAC sent by server.
168 ************************************************************/
169
170 static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok)
171 {
172         return True;
173 }
174
175 /***********************************************************
176  SMB signing - NULL implementation - free signing context
177 ************************************************************/
178
179 static void null_free_signing_context(struct smb_sign_info *si)
180 {
181         return;
182 }
183
184 /**
185  SMB signing - NULL implementation - setup the MAC key.
186
187  @note Used as an initialisation only - it will not correctly
188        shut down a real signing mechanism
189 */
190
191 static BOOL null_set_signing(struct smb_sign_info *si)
192 {
193         si->signing_context = NULL;
194         
195         si->sign_outgoing_message = null_sign_outgoing_message;
196         si->check_incoming_message = null_check_incoming_message;
197         si->free_signing_context = null_free_signing_context;
198
199         return True;
200 }
201
202 /**
203  * Free the signing context
204  */
205  
206 static void free_signing_context(struct smb_sign_info *si)
207 {
208         if (si->free_signing_context) {
209                 si->free_signing_context(si);
210                 si->signing_context = NULL;
211         }
212
213         null_set_signing(si);
214 }
215
216
217 static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq, BOOL must_be_ok) 
218 {
219         if (good) {
220
221                 if (!si->doing_signing) {
222                         si->doing_signing = True;
223                 }
224                 
225                 if (!si->seen_valid) {
226                         si->seen_valid = True;
227                 }
228
229         } else {
230                 if (!si->mandatory_signing && !si->seen_valid) {
231
232                         if (!must_be_ok) {
233                                 return True;
234                         }
235                         /* Non-mandatory signing - just turn off if this is the first bad packet.. */
236                         DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and peer\n"
237                                   "isn't sending correct signatures. Turning off.\n"));
238                         si->negotiated_smb_signing = False;
239                         si->allow_smb_signing = False;
240                         si->doing_signing = False;
241                         free_signing_context(si);
242                         return True;
243                 } else if (!must_be_ok) {
244                         /* This packet is known to be unsigned */
245                         return True;
246                 } else {
247                         /* Mandatory signing or bad packet after signing started - fail and disconnect. */
248                         if (seq)
249                                 DEBUG(0, ("signing_good: BAD SIG: seq %u\n", (unsigned int)seq));
250                         return False;
251                 }
252         }
253         return True;
254 }       
255
256 /***********************************************************
257  SMB signing - Simple implementation - calculate a MAC on the packet
258 ************************************************************/
259
260 static void simple_packet_signature(struct smb_basic_signing_context *data, 
261                                     const uchar *buf, uint32 seq_number, 
262                                     unsigned char calc_md5_mac[16])
263 {
264         const size_t offset_end_of_sig = (smb_ss_field + 8);
265         unsigned char sequence_buf[8];
266         struct MD5Context md5_ctx;
267 #if 0
268         /* JRA - apparently this is incorrect. */
269         unsigned char key_buf[16];
270 #endif
271
272         /*
273          * Firstly put the sequence number into the first 4 bytes.
274          * and zero out the next 4 bytes.
275          *
276          * We do this here, to avoid modifying the packet.
277          */
278
279         DEBUG(10,("simple_packet_signature: sequence number %u\n", seq_number ));
280
281         SIVAL(sequence_buf, 0, seq_number);
282         SIVAL(sequence_buf, 4, 0);
283
284         /* Calculate the 16 byte MAC - but don't alter the data in the
285            incoming packet.
286            
287            This makes for a bit of fussing about, but it's not too bad.
288         */
289         MD5Init(&md5_ctx);
290
291         /* intialise with the key */
292         MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); 
293 #if 0
294         /* JRA - apparently this is incorrect. */
295         /* NB. When making and verifying SMB signatures, Windows apparently
296                 zero-pads the key to 128 bits if it isn't long enough.
297                 From Nalin Dahyabhai <nalin@redhat.com> */
298         if (data->mac_key.length < sizeof(key_buf)) {
299                 memset(key_buf, 0, sizeof(key_buf));
300                 MD5Update(&md5_ctx, key_buf, sizeof(key_buf) - data->mac_key.length);
301         }
302 #endif
303
304         /* copy in the first bit of the SMB header */
305         MD5Update(&md5_ctx, buf + 4, smb_ss_field - 4);
306
307         /* copy in the sequence number, instead of the signature */
308         MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf));
309
310         /* copy in the rest of the packet in, skipping the signature */
311         MD5Update(&md5_ctx, buf + offset_end_of_sig, 
312                   smb_len(buf) - (offset_end_of_sig - 4));
313
314         /* calculate the MD5 sig */ 
315         MD5Final(calc_md5_mac, &md5_ctx);
316 }
317
318
319 /***********************************************************
320  SMB signing - Client implementation - send the MAC.
321 ************************************************************/
322
323 static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
324 {
325         unsigned char calc_md5_mac[16];
326         struct smb_basic_signing_context *data =
327                 (struct smb_basic_signing_context *)si->signing_context;
328
329         if (!si->doing_signing)
330                 return;
331
332         /* JRA Paranioa test - we should be able to get rid of this... */
333         if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) {
334                 DEBUG(1, ("client_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n",
335                                         smb_len(outbuf) ));
336                 abort();
337         }
338
339         /* mark the packet as signed - BEFORE we sign it...*/
340         mark_packet_signed(outbuf);
341
342         simple_packet_signature(data, (const unsigned char *)outbuf,
343                                 data->send_seq_num, calc_md5_mac);
344
345         DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n"));
346         dump_data(10, (const char *)calc_md5_mac, 8);
347
348         memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8);
349
350 /*      cli->outbuf[smb_ss_field+2]=0; 
351         Uncomment this to test if the remote server actually verifies signatures...*/
352
353         /* Instead of re-introducing the trans_info_conect we
354            used to have here, we use the fact that during a
355            SMBtrans/SMBtrans2/SMBnttrans send that the mid stays
356            constant. This means that calling store_sequence_for_reply()
357            will return False for all trans secondaries, as the mid is already
358            on the stored sequence list. As the send_seqence_number must
359            remain constant for all primary+secondary trans sends, we
360            only increment the send sequence number when we successfully
361            add a new entry to the outstanding sequence list. This means
362            I can isolate the fix here rather than re-adding the trans
363            signing on/off calls in libsmb/clitrans2.c JRA.
364          */
365         
366         if (store_sequence_for_reply(&data->outstanding_packet_list, SVAL(outbuf,smb_mid), data->send_seq_num + 1)) {
367                 data->send_seq_num += 2;
368         }
369 }
370
371 /***********************************************************
372  SMB signing - Client implementation - check a MAC sent by server.
373 ************************************************************/
374
375 static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok)
376 {
377         BOOL good;
378         uint32 reply_seq_number;
379         unsigned char calc_md5_mac[16];
380         unsigned char *server_sent_mac;
381
382         struct smb_basic_signing_context *data =
383                 (struct smb_basic_signing_context *)si->signing_context;
384
385         if (!si->doing_signing)
386                 return True;
387
388         if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) {
389                 DEBUG(1, ("client_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf)));
390                 return False;
391         }
392
393         if (!get_sequence_for_reply(&data->outstanding_packet_list, SVAL(inbuf, smb_mid), &reply_seq_number)) {
394                 DEBUG(1, ("client_check_incoming_message: received message "
395                         "with mid %u with no matching send record.\n", (unsigned int)SVAL(inbuf, smb_mid) ));
396                 return False;
397         }
398
399         simple_packet_signature(data, (const unsigned char *)inbuf,
400                                 reply_seq_number, calc_md5_mac);
401
402         server_sent_mac = (unsigned char *)&inbuf[smb_ss_field];
403         good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
404         
405         if (!good) {
406                 DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n"));
407                 dump_data(5, (const char *)calc_md5_mac, 8);
408                 
409                 DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n"));
410                 dump_data(5, (const char *)server_sent_mac, 8);
411 #if 1 /* JRATEST */
412                 {
413                         int i;
414                         for (i = -5; i < 5; i++) {
415                                 simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number+i, calc_md5_mac);
416                                 if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) {
417                                         DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches. \
418 We were expecting seq %u\n", reply_seq_number+i, reply_seq_number ));
419                                         break;
420                                 }
421                         }
422                 }
423 #endif /* JRATEST */
424
425         } else {
426                 DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number));
427                 dump_data(10, (const char *)server_sent_mac, 8);
428         }
429         return signing_good(inbuf, si, good, reply_seq_number, must_be_ok);
430 }
431
432 /***********************************************************
433  SMB signing - Simple implementation - free signing context
434 ************************************************************/
435
436 static void simple_free_signing_context(struct smb_sign_info *si)
437 {
438         struct smb_basic_signing_context *data =
439                 (struct smb_basic_signing_context *)si->signing_context;
440         struct outstanding_packet_lookup *list;
441         struct outstanding_packet_lookup *next;
442         
443         for (list = data->outstanding_packet_list; list; list = next) {
444                 next = list->next;
445                 DLIST_REMOVE(data->outstanding_packet_list, list);
446                 SAFE_FREE(list);
447         }
448
449         data_blob_free(&data->mac_key);
450
451         SAFE_FREE(si->signing_context);
452
453         return;
454 }
455
456 /***********************************************************
457  SMB signing - Simple implementation - setup the MAC key.
458 ************************************************************/
459
460 BOOL cli_simple_set_signing(struct cli_state *cli,
461                             const DATA_BLOB user_session_key,
462                             const DATA_BLOB response)
463 {
464         struct smb_basic_signing_context *data;
465
466         if (!user_session_key.length)
467                 return False;
468
469         if (!cli_set_smb_signing_common(cli)) {
470                 return False;
471         }
472
473         if (!set_smb_signing_real_common(&cli->sign_info)) {
474                 return False;
475         }
476
477         data = SMB_XMALLOC_P(struct smb_basic_signing_context);
478         memset(data, '\0', sizeof(*data));
479
480         cli->sign_info.signing_context = data;
481         
482         data->mac_key = data_blob(NULL, response.length + user_session_key.length);
483
484         memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length);
485
486         DEBUG(10, ("cli_simple_set_signing: user_session_key\n"));
487         dump_data(10, (const char *)user_session_key.data, user_session_key.length);
488
489         if (response.length) {
490                 memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length);
491                 DEBUG(10, ("cli_simple_set_signing: response_data\n"));
492                 dump_data(10, (const char *)response.data, response.length);
493         } else {
494                 DEBUG(10, ("cli_simple_set_signing: NULL response_data\n"));
495         }
496
497         dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length);
498
499         /* Initialise the sequence number */
500         data->send_seq_num = 0;
501
502         /* Initialise the list of outstanding packets */
503         data->outstanding_packet_list = NULL;
504
505         cli->sign_info.sign_outgoing_message = client_sign_outgoing_message;
506         cli->sign_info.check_incoming_message = client_check_incoming_message;
507         cli->sign_info.free_signing_context = simple_free_signing_context;
508
509         return True;
510 }
511
512 /***********************************************************
513  SMB signing - TEMP implementation - calculate a MAC to send.
514 ************************************************************/
515
516 static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
517 {
518         /* mark the packet as signed - BEFORE we sign it...*/
519         mark_packet_signed(outbuf);
520
521         /* I wonder what BSRSPYL stands for - but this is what MS 
522            actually sends! */
523         memcpy(&outbuf[smb_ss_field], "BSRSPYL ", 8);
524         return;
525 }
526
527 /***********************************************************
528  SMB signing - TEMP implementation - check a MAC sent by server.
529 ************************************************************/
530
531 static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL foo)
532 {
533         return True;
534 }
535
536 /***********************************************************
537  SMB signing - TEMP implementation - free signing context
538 ************************************************************/
539
540 static void temp_free_signing_context(struct smb_sign_info *si)
541 {
542         return;
543 }
544
545 /***********************************************************
546  SMB signing - NULL implementation - setup the MAC key.
547 ************************************************************/
548
549 BOOL cli_null_set_signing(struct cli_state *cli)
550 {
551         return null_set_signing(&cli->sign_info);
552 }
553
554 /***********************************************************
555  SMB signing - temp implementation - setup the MAC key.
556 ************************************************************/
557
558 BOOL cli_temp_set_signing(struct cli_state *cli)
559 {
560         if (!cli_set_smb_signing_common(cli)) {
561                 return False;
562         }
563
564         cli->sign_info.signing_context = NULL;
565         
566         cli->sign_info.sign_outgoing_message = temp_sign_outgoing_message;
567         cli->sign_info.check_incoming_message = temp_check_incoming_message;
568         cli->sign_info.free_signing_context = temp_free_signing_context;
569
570         return True;
571 }
572
573 void cli_free_signing_context(struct cli_state *cli)
574 {
575         free_signing_context(&cli->sign_info);
576 }
577
578 /**
579  * Sign a packet with the current mechanism
580  */
581  
582 void cli_calculate_sign_mac(struct cli_state *cli)
583 {
584         cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info);
585 }
586
587 /**
588  * Check a packet with the current mechanism
589  * @return False if we had an established signing connection
590  *         which had a bad checksum, True otherwise.
591  */
592  
593 BOOL cli_check_sign_mac(struct cli_state *cli) 
594 {
595         if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, True)) {
596                 free_signing_context(&cli->sign_info);  
597                 return False;
598         }
599         return True;
600 }
601
602 /***********************************************************
603  Enter trans/trans2/nttrans state.
604 ************************************************************/
605
606 BOOL client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid)
607 {
608         struct smb_sign_info *si = &cli->sign_info;
609         struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context;
610
611         if (!si->doing_signing) {
612                 return True;
613         }
614
615         if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, False)) {
616                 return False;
617         }
618
619         return True;
620 }
621
622 /***********************************************************
623  Leave trans/trans2/nttrans state.
624 ************************************************************/
625
626 BOOL client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid)
627 {
628         uint32 reply_seq_num;
629         struct smb_sign_info *si = &cli->sign_info;
630         struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context;
631
632         if (!si->doing_signing) {
633                 return True;
634         }
635
636         if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, True)) {
637                 return False;
638         }
639
640         /* Now delete the stored mid entry. */
641         if (!get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_num)) {
642                 return False;
643         }
644
645         return True;
646 }
647
648 /***********************************************************
649  SMB signing - Server implementation - send the MAC.
650 ************************************************************/
651
652 static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
653 {
654         unsigned char calc_md5_mac[16];
655         struct smb_basic_signing_context *data =
656                 (struct smb_basic_signing_context *)si->signing_context;
657         uint32 send_seq_number = data->send_seq_num-1;
658         uint16 mid;
659
660         if (!si->doing_signing) {
661                 return;
662         }
663
664         /* JRA Paranioa test - we should be able to get rid of this... */
665         if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) {
666                 DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't send signature on short packet! smb_len = %u\n",
667                                         smb_len(outbuf) ));
668                 abort();
669         }
670
671         /* mark the packet as signed - BEFORE we sign it...*/
672         mark_packet_signed(outbuf);
673
674         mid = SVAL(outbuf, smb_mid);
675
676         /* See if this is a reply for a deferred packet. */
677         get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number);
678
679         simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_number, calc_md5_mac);
680
681         DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number));
682         dump_data(10, (const char *)calc_md5_mac, 8);
683
684         memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8);
685
686 /*      cli->outbuf[smb_ss_field+2]=0; 
687         Uncomment this to test if the remote client actually verifies signatures...*/
688 }
689
690 /***********************************************************
691  SMB signing - Server implementation - check a MAC sent by server.
692 ************************************************************/
693
694 static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok)
695 {
696         BOOL good;
697         struct smb_basic_signing_context *data =
698                 (struct smb_basic_signing_context *)si->signing_context;
699         uint32 reply_seq_number = data->send_seq_num;
700         uint32 saved_seq;
701         unsigned char calc_md5_mac[16];
702         unsigned char *server_sent_mac;
703
704         if (!si->doing_signing)
705                 return True;
706
707         if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) {
708                 DEBUG(1, ("srv_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf)));
709                 return False;
710         }
711
712         /* We always increment the sequence number. */
713         data->send_seq_num += 2;
714
715         saved_seq = reply_seq_number;
716         simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
717
718         server_sent_mac = (unsigned char *)&inbuf[smb_ss_field];
719         good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
720         
721         if (!good) {
722
723                 if (saved_seq) {
724                         DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n",
725                                         (unsigned int)saved_seq));
726                         dump_data(5, (const char *)calc_md5_mac, 8);
727
728                         DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n",
729                                                 (unsigned int)reply_seq_number));
730                         dump_data(5, (const char *)server_sent_mac, 8);
731                 }
732                 
733 #if 1 /* JRATEST */
734                 {
735                         int i;
736                         reply_seq_number -= 5;
737                         for (i = 0; i < 10; i++, reply_seq_number++) {
738                                 simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
739                                 if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) {
740                                         DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches. \
741 We were expecting seq %u\n", reply_seq_number, saved_seq ));
742                                         break;
743                                 }
744                         }
745                 }
746 #endif /* JRATEST */
747
748         } else {
749                 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));
750                 dump_data(10, (const char *)server_sent_mac, 8);
751         }
752
753         return (signing_good(inbuf, si, good, saved_seq, must_be_ok));
754 }
755
756 /***********************************************************
757  SMB signing - server API's.
758 ************************************************************/
759
760 static struct smb_sign_info srv_sign_info = {
761         null_sign_outgoing_message,
762         null_check_incoming_message,
763         null_free_signing_context,
764         NULL,
765         False,
766         False,
767         False,
768         False
769 };
770
771 /***********************************************************
772  Turn signing off or on for oplock break code.
773 ************************************************************/
774
775 BOOL srv_oplock_set_signing(BOOL onoff)
776 {
777         BOOL ret = srv_sign_info.doing_signing;
778         srv_sign_info.doing_signing = onoff;
779         return ret;
780 }
781
782 /***********************************************************
783  Called to validate an incoming packet from the client.
784 ************************************************************/
785
786 BOOL srv_check_sign_mac(char *inbuf, BOOL must_be_ok)
787 {
788         /* Check if it's a session keepalive. */
789         if(CVAL(inbuf,0) == SMBkeepalive)
790                 return True;
791
792         return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info, must_be_ok);
793 }
794
795 /***********************************************************
796  Called to sign an outgoing packet to the client.
797 ************************************************************/
798
799 void srv_calculate_sign_mac(char *outbuf)
800 {
801         /* Check if it's a session keepalive. */
802         /* JRA Paranioa test - do we ever generate these in the server ? */
803         if(CVAL(outbuf,0) == SMBkeepalive)
804                 return;
805
806         srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info);
807 }
808
809 /***********************************************************
810  Called by server to defer an outgoing packet.
811 ************************************************************/
812
813 void srv_defer_sign_response(uint16 mid)
814 {
815         struct smb_basic_signing_context *data;
816
817         if (!srv_sign_info.doing_signing)
818                 return;
819
820         data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
821
822         if (!data)
823                 return;
824
825         /*
826          * Ensure we only store this mid reply once...
827          */
828
829         store_sequence_for_reply(&data->outstanding_packet_list, mid,
830                                  data->send_seq_num-1);
831 }
832
833 /***********************************************************
834  Called to remove sequence records when a deferred packet is
835  cancelled by mid. This should never find one....
836 ************************************************************/
837
838 void srv_cancel_sign_response(uint16 mid)
839 {
840         struct smb_basic_signing_context *data;
841         uint32 dummy_seq;
842
843         if (!srv_sign_info.doing_signing)
844                 return;
845
846         data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
847
848         if (!data)
849                 return;
850
851         DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid ));
852
853         while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq))
854                 ;
855
856         /* cancel doesn't send a reply so doesn't burn a sequence number. */
857         data->send_seq_num -= 1;
858 }
859
860 /***********************************************************
861  Called by server negprot when signing has been negotiated.
862 ************************************************************/
863
864 void srv_set_signing_negotiated(void)
865 {
866         srv_sign_info.allow_smb_signing = True;
867         srv_sign_info.negotiated_smb_signing = True;
868         if (lp_server_signing() == Required)
869                 srv_sign_info.mandatory_signing = True;
870
871         srv_sign_info.sign_outgoing_message = temp_sign_outgoing_message;
872         srv_sign_info.check_incoming_message = temp_check_incoming_message;
873         srv_sign_info.free_signing_context = temp_free_signing_context;
874 }
875
876 /***********************************************************
877  Returns whether signing is active. We can't use sendfile or raw
878  reads/writes if it is.
879 ************************************************************/
880
881 BOOL srv_is_signing_active(void)
882 {
883         return srv_sign_info.doing_signing;
884 }
885
886
887 /***********************************************************
888  Returns whether signing is negotiated. We can't use it unless it was
889  in the negprot.  
890 ************************************************************/
891
892 BOOL srv_is_signing_negotiated(void)
893 {
894         return srv_sign_info.negotiated_smb_signing;
895 }
896
897 /***********************************************************
898  Returns whether signing is actually happening
899 ************************************************************/
900
901 BOOL srv_signing_started(void)
902 {
903         struct smb_basic_signing_context *data;
904
905         if (!srv_sign_info.doing_signing) {
906                 return False;
907         }
908
909         data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
910         if (!data)
911                 return False;
912
913         if (data->send_seq_num == 0) {
914                 return False;
915         }
916
917         return True;
918 }
919
920 /***********************************************************
921  Turn on signing from this packet onwards. 
922 ************************************************************/
923
924 void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response)
925 {
926         struct smb_basic_signing_context *data;
927
928         if (!user_session_key.length)
929                 return;
930
931         if (!srv_sign_info.negotiated_smb_signing && !srv_sign_info.mandatory_signing) {
932                 DEBUG(5,("srv_set_signing: signing negotiated = %u, mandatory_signing = %u. Not allowing smb signing.\n",
933                         (unsigned int)srv_sign_info.negotiated_smb_signing,
934                         (unsigned int)srv_sign_info.mandatory_signing ));
935                 return;
936         }
937
938         /* Once we've turned on, ignore any more sessionsetups. */
939         if (srv_sign_info.doing_signing) {
940                 return;
941         }
942         
943         if (srv_sign_info.free_signing_context)
944                 srv_sign_info.free_signing_context(&srv_sign_info);
945         
946         srv_sign_info.doing_signing = True;
947
948         data = SMB_XMALLOC_P(struct smb_basic_signing_context);
949         memset(data, '\0', sizeof(*data));
950
951         srv_sign_info.signing_context = data;
952         
953         data->mac_key = data_blob(NULL, response.length + user_session_key.length);
954
955         memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length);
956         if (response.length)
957                 memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length);
958
959         dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length);
960
961         DEBUG(3,("srv_set_signing: turning on SMB signing: signing negotiated = %s, mandatory_signing = %s.\n",
962                                 BOOLSTR(srv_sign_info.negotiated_smb_signing),
963                                 BOOLSTR(srv_sign_info.mandatory_signing) ));
964
965         /* Initialise the sequence number */
966         data->send_seq_num = 0;
967
968         /* Initialise the list of outstanding packets */
969         data->outstanding_packet_list = NULL;
970
971         srv_sign_info.sign_outgoing_message = srv_sign_outgoing_message;
972         srv_sign_info.check_incoming_message = srv_check_incoming_message;
973         srv_sign_info.free_signing_context = simple_free_signing_context;
974 }