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