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