00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "includes.h"
00023
00024
00025 struct outstanding_packet_lookup {
00026 struct outstanding_packet_lookup *prev, *next;
00027 uint16 mid;
00028 uint32 reply_seq_num;
00029 BOOL can_delete;
00030 };
00031
00032 struct smb_basic_signing_context {
00033 DATA_BLOB mac_key;
00034 uint32 send_seq_num;
00035 struct outstanding_packet_lookup *outstanding_packet_list;
00036 };
00037
00038 static BOOL store_sequence_for_reply(struct outstanding_packet_lookup **list,
00039 uint16 mid, uint32 reply_seq_num)
00040 {
00041 struct outstanding_packet_lookup *t;
00042
00043
00044 for (t = *list; t; t = t->next) {
00045 if (t->mid == mid) {
00046 return False;
00047 }
00048 }
00049
00050 t = SMB_XMALLOC_P(struct outstanding_packet_lookup);
00051 ZERO_STRUCTP(t);
00052
00053 t->mid = mid;
00054 t->reply_seq_num = reply_seq_num;
00055 t->can_delete = True;
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 DLIST_ADD(*list, t);
00067 DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n",
00068 (unsigned int)reply_seq_num, (unsigned int)mid ));
00069 return True;
00070 }
00071
00072 static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list,
00073 uint16 mid, uint32 *reply_seq_num)
00074 {
00075 struct outstanding_packet_lookup *t;
00076
00077 for (t = *list; t; t = t->next) {
00078 if (t->mid == mid) {
00079 *reply_seq_num = t->reply_seq_num;
00080 DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n",
00081 (unsigned int)t->reply_seq_num, (unsigned int)t->mid ));
00082 if (t->can_delete) {
00083 DLIST_REMOVE(*list, t);
00084 SAFE_FREE(t);
00085 }
00086 return True;
00087 }
00088 }
00089 return False;
00090 }
00091
00092 static BOOL set_sequence_can_delete_flag(struct outstanding_packet_lookup **list, uint16 mid, BOOL can_delete_entry)
00093 {
00094 struct outstanding_packet_lookup *t;
00095
00096 for (t = *list; t; t = t->next) {
00097 if (t->mid == mid) {
00098 t->can_delete = can_delete_entry;
00099 return True;
00100 }
00101 }
00102 return False;
00103 }
00104
00105
00106
00107
00108
00109 static BOOL cli_set_smb_signing_common(struct cli_state *cli)
00110 {
00111 if (!cli->sign_info.allow_smb_signing) {
00112 return False;
00113 }
00114
00115 if (!cli->sign_info.negotiated_smb_signing
00116 && !cli->sign_info.mandatory_signing) {
00117 return False;
00118 }
00119
00120 if (cli->sign_info.doing_signing) {
00121 return False;
00122 }
00123
00124 if (cli->sign_info.free_signing_context)
00125 cli->sign_info.free_signing_context(&cli->sign_info);
00126
00127
00128 cli->readbraw_supported = False;
00129 cli->writebraw_supported = False;
00130
00131 return True;
00132 }
00133
00134
00135
00136
00137
00138 static BOOL set_smb_signing_real_common(struct smb_sign_info *si)
00139 {
00140 if (si->mandatory_signing) {
00141 DEBUG(5, ("Mandatory SMB signing enabled!\n"));
00142 }
00143
00144 si->doing_signing = True;
00145 DEBUG(5, ("SMB signing enabled!\n"));
00146
00147 return True;
00148 }
00149
00150 static void mark_packet_signed(char *outbuf)
00151 {
00152 uint16 flags2;
00153 flags2 = SVAL(outbuf,smb_flg2);
00154 flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
00155 SSVAL(outbuf,smb_flg2, flags2);
00156 }
00157
00158
00159
00160
00161
00162 static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
00163 {
00164
00165
00166
00167 return;
00168 }
00169
00170
00171
00172
00173
00174 static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok)
00175 {
00176 return True;
00177 }
00178
00179
00180
00181
00182
00183 static void null_free_signing_context(struct smb_sign_info *si)
00184 {
00185 return;
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195 static BOOL null_set_signing(struct smb_sign_info *si)
00196 {
00197 si->signing_context = NULL;
00198
00199 si->sign_outgoing_message = null_sign_outgoing_message;
00200 si->check_incoming_message = null_check_incoming_message;
00201 si->free_signing_context = null_free_signing_context;
00202
00203 return True;
00204 }
00205
00206
00207
00208
00209
00210 static void free_signing_context(struct smb_sign_info *si)
00211 {
00212 if (si->free_signing_context) {
00213 si->free_signing_context(si);
00214 si->signing_context = NULL;
00215 }
00216
00217 null_set_signing(si);
00218 }
00219
00220
00221 static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq, BOOL must_be_ok)
00222 {
00223 if (good) {
00224
00225 if (!si->doing_signing) {
00226 si->doing_signing = True;
00227 }
00228
00229 if (!si->seen_valid) {
00230 si->seen_valid = True;
00231 }
00232
00233 } else {
00234 if (!si->mandatory_signing && !si->seen_valid) {
00235
00236 if (!must_be_ok) {
00237 return True;
00238 }
00239
00240 DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and peer\n"
00241 "isn't sending correct signatures. Turning off.\n"));
00242 si->negotiated_smb_signing = False;
00243 si->allow_smb_signing = False;
00244 si->doing_signing = False;
00245 free_signing_context(si);
00246 return True;
00247 } else if (!must_be_ok) {
00248
00249 return True;
00250 } else {
00251
00252 if (seq)
00253 DEBUG(0, ("signing_good: BAD SIG: seq %u\n", (unsigned int)seq));
00254 return False;
00255 }
00256 }
00257 return True;
00258 }
00259
00260
00261
00262
00263
00264 static void simple_packet_signature(struct smb_basic_signing_context *data,
00265 const uchar *buf, uint32 seq_number,
00266 unsigned char calc_md5_mac[16])
00267 {
00268 const size_t offset_end_of_sig = (smb_ss_field + 8);
00269 unsigned char sequence_buf[8];
00270 struct MD5Context md5_ctx;
00271 #if 0
00272
00273 unsigned char key_buf[16];
00274 #endif
00275
00276
00277
00278
00279
00280
00281
00282
00283 DEBUG(10,("simple_packet_signature: sequence number %u\n", seq_number ));
00284
00285 SIVAL(sequence_buf, 0, seq_number);
00286 SIVAL(sequence_buf, 4, 0);
00287
00288
00289
00290
00291
00292
00293 MD5Init(&md5_ctx);
00294
00295
00296 MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length);
00297 #if 0
00298
00299
00300
00301
00302 if (data->mac_key.length < sizeof(key_buf)) {
00303 memset(key_buf, 0, sizeof(key_buf));
00304 MD5Update(&md5_ctx, key_buf, sizeof(key_buf) - data->mac_key.length);
00305 }
00306 #endif
00307
00308
00309 MD5Update(&md5_ctx, buf + 4, smb_ss_field - 4);
00310
00311
00312 MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf));
00313
00314
00315 MD5Update(&md5_ctx, buf + offset_end_of_sig,
00316 smb_len(buf) - (offset_end_of_sig - 4));
00317
00318
00319 MD5Final(calc_md5_mac, &md5_ctx);
00320 }
00321
00322
00323
00324
00325
00326
00327 static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
00328 {
00329 unsigned char calc_md5_mac[16];
00330 struct smb_basic_signing_context *data =
00331 (struct smb_basic_signing_context *)si->signing_context;
00332
00333 if (!si->doing_signing)
00334 return;
00335
00336
00337 if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) {
00338 DEBUG(1, ("client_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n",
00339 smb_len(outbuf) ));
00340 abort();
00341 }
00342
00343
00344 mark_packet_signed(outbuf);
00345
00346 simple_packet_signature(data, (const unsigned char *)outbuf,
00347 data->send_seq_num, calc_md5_mac);
00348
00349 DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n"));
00350 dump_data(10, (const char *)calc_md5_mac, 8);
00351
00352 memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8);
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 if (store_sequence_for_reply(&data->outstanding_packet_list, SVAL(outbuf,smb_mid), data->send_seq_num + 1)) {
00371 data->send_seq_num += 2;
00372 }
00373 }
00374
00375
00376
00377
00378
00379 static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok)
00380 {
00381 BOOL good;
00382 uint32 reply_seq_number;
00383 unsigned char calc_md5_mac[16];
00384 unsigned char *server_sent_mac;
00385
00386 struct smb_basic_signing_context *data =
00387 (struct smb_basic_signing_context *)si->signing_context;
00388
00389 if (!si->doing_signing)
00390 return True;
00391
00392 if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) {
00393 DEBUG(1, ("client_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf)));
00394 return False;
00395 }
00396
00397 if (!get_sequence_for_reply(&data->outstanding_packet_list, SVAL(inbuf, smb_mid), &reply_seq_number)) {
00398 DEBUG(1, ("client_check_incoming_message: received message "
00399 "with mid %u with no matching send record.\n", (unsigned int)SVAL(inbuf, smb_mid) ));
00400 return False;
00401 }
00402
00403 simple_packet_signature(data, (const unsigned char *)inbuf,
00404 reply_seq_number, calc_md5_mac);
00405
00406 server_sent_mac = (unsigned char *)&inbuf[smb_ss_field];
00407 good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
00408
00409 if (!good) {
00410 DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n"));
00411 dump_data(5, (const char *)calc_md5_mac, 8);
00412
00413 DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n"));
00414 dump_data(5, (const char *)server_sent_mac, 8);
00415 #if 1
00416 {
00417 int i;
00418 for (i = -5; i < 5; i++) {
00419 simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number+i, calc_md5_mac);
00420 if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) {
00421 DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches. \
00422 We were expecting seq %u\n", reply_seq_number+i, reply_seq_number ));
00423 break;
00424 }
00425 }
00426 }
00427 #endif
00428
00429 } else {
00430 DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number));
00431 dump_data(10, (const char *)server_sent_mac, 8);
00432 }
00433 return signing_good(inbuf, si, good, reply_seq_number, must_be_ok);
00434 }
00435
00436
00437
00438
00439
00440 static void simple_free_signing_context(struct smb_sign_info *si)
00441 {
00442 struct smb_basic_signing_context *data =
00443 (struct smb_basic_signing_context *)si->signing_context;
00444 struct outstanding_packet_lookup *list;
00445 struct outstanding_packet_lookup *next;
00446
00447 for (list = data->outstanding_packet_list; list; list = next) {
00448 next = list->next;
00449 DLIST_REMOVE(data->outstanding_packet_list, list);
00450 SAFE_FREE(list);
00451 }
00452
00453 data_blob_free(&data->mac_key);
00454
00455 SAFE_FREE(si->signing_context);
00456
00457 return;
00458 }
00459
00460
00461
00462
00463
00464 BOOL cli_simple_set_signing(struct cli_state *cli,
00465 const DATA_BLOB user_session_key,
00466 const DATA_BLOB response)
00467 {
00468 struct smb_basic_signing_context *data;
00469
00470 if (!user_session_key.length)
00471 return False;
00472
00473 if (!cli_set_smb_signing_common(cli)) {
00474 return False;
00475 }
00476
00477 if (!set_smb_signing_real_common(&cli->sign_info)) {
00478 return False;
00479 }
00480
00481 data = SMB_XMALLOC_P(struct smb_basic_signing_context);
00482 memset(data, '\0', sizeof(*data));
00483
00484 cli->sign_info.signing_context = data;
00485
00486 data->mac_key = data_blob(NULL, response.length + user_session_key.length);
00487
00488 memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length);
00489
00490 DEBUG(10, ("cli_simple_set_signing: user_session_key\n"));
00491 dump_data(10, (const char *)user_session_key.data, user_session_key.length);
00492
00493 if (response.length) {
00494 memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length);
00495 DEBUG(10, ("cli_simple_set_signing: response_data\n"));
00496 dump_data(10, (const char *)response.data, response.length);
00497 } else {
00498 DEBUG(10, ("cli_simple_set_signing: NULL response_data\n"));
00499 }
00500
00501 dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length);
00502
00503
00504 data->send_seq_num = 0;
00505
00506
00507 data->outstanding_packet_list = NULL;
00508
00509 cli->sign_info.sign_outgoing_message = client_sign_outgoing_message;
00510 cli->sign_info.check_incoming_message = client_check_incoming_message;
00511 cli->sign_info.free_signing_context = simple_free_signing_context;
00512
00513 return True;
00514 }
00515
00516
00517
00518
00519
00520 static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
00521 {
00522
00523 mark_packet_signed(outbuf);
00524
00525
00526
00527 memcpy(&outbuf[smb_ss_field], "BSRSPYL ", 8);
00528 return;
00529 }
00530
00531
00532
00533
00534
00535 static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL foo)
00536 {
00537 return True;
00538 }
00539
00540
00541
00542
00543
00544 static void temp_free_signing_context(struct smb_sign_info *si)
00545 {
00546 return;
00547 }
00548
00549
00550
00551
00552
00553 BOOL cli_null_set_signing(struct cli_state *cli)
00554 {
00555 return null_set_signing(&cli->sign_info);
00556 }
00557
00558
00559
00560
00561
00562 BOOL cli_temp_set_signing(struct cli_state *cli)
00563 {
00564 if (!cli_set_smb_signing_common(cli)) {
00565 return False;
00566 }
00567
00568 cli->sign_info.signing_context = NULL;
00569
00570 cli->sign_info.sign_outgoing_message = temp_sign_outgoing_message;
00571 cli->sign_info.check_incoming_message = temp_check_incoming_message;
00572 cli->sign_info.free_signing_context = temp_free_signing_context;
00573
00574 return True;
00575 }
00576
00577 void cli_free_signing_context(struct cli_state *cli)
00578 {
00579 free_signing_context(&cli->sign_info);
00580 }
00581
00582
00583
00584
00585
00586 void cli_calculate_sign_mac(struct cli_state *cli)
00587 {
00588 cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info);
00589 }
00590
00591
00592
00593
00594
00595
00596
00597 BOOL cli_check_sign_mac(struct cli_state *cli)
00598 {
00599 if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, True)) {
00600 free_signing_context(&cli->sign_info);
00601 return False;
00602 }
00603 return True;
00604 }
00605
00606
00607
00608
00609
00610 BOOL client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid)
00611 {
00612 struct smb_sign_info *si = &cli->sign_info;
00613 struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context;
00614
00615 if (!si->doing_signing) {
00616 return True;
00617 }
00618
00619 if (!data) {
00620 return False;
00621 }
00622
00623 if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, False)) {
00624 return False;
00625 }
00626
00627 return True;
00628 }
00629
00630
00631
00632
00633
00634 BOOL client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid)
00635 {
00636 uint32 reply_seq_num;
00637 struct smb_sign_info *si = &cli->sign_info;
00638 struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context;
00639
00640 if (!si->doing_signing) {
00641 return True;
00642 }
00643
00644 if (!data) {
00645 return False;
00646 }
00647
00648 if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, True)) {
00649 return False;
00650 }
00651
00652
00653 if (!get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_num)) {
00654 return False;
00655 }
00656
00657 return True;
00658 }
00659
00660
00661
00662
00663
00664 static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
00665 {
00666 unsigned char calc_md5_mac[16];
00667 struct smb_basic_signing_context *data =
00668 (struct smb_basic_signing_context *)si->signing_context;
00669 uint32 send_seq_number = data->send_seq_num-1;
00670 uint16 mid;
00671
00672 if (!si->doing_signing) {
00673 return;
00674 }
00675
00676
00677 if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) {
00678 DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't send signature on short packet! smb_len = %u\n",
00679 smb_len(outbuf) ));
00680 abort();
00681 }
00682
00683
00684 mark_packet_signed(outbuf);
00685
00686 mid = SVAL(outbuf, smb_mid);
00687
00688
00689 get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number);
00690
00691 simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_number, calc_md5_mac);
00692
00693 DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number));
00694 dump_data(10, (const char *)calc_md5_mac, 8);
00695
00696 memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8);
00697
00698
00699
00700 }
00701
00702
00703
00704
00705
00706 static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok)
00707 {
00708 BOOL good;
00709 struct smb_basic_signing_context *data =
00710 (struct smb_basic_signing_context *)si->signing_context;
00711 uint32 reply_seq_number = data->send_seq_num;
00712 uint32 saved_seq;
00713 unsigned char calc_md5_mac[16];
00714 unsigned char *server_sent_mac;
00715
00716 if (!si->doing_signing)
00717 return True;
00718
00719 if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) {
00720 DEBUG(1, ("srv_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf)));
00721 return False;
00722 }
00723
00724
00725 data->send_seq_num += 2;
00726
00727 saved_seq = reply_seq_number;
00728 simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
00729
00730 server_sent_mac = (unsigned char *)&inbuf[smb_ss_field];
00731 good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
00732
00733 if (!good) {
00734
00735 if (saved_seq) {
00736 DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n",
00737 (unsigned int)saved_seq));
00738 dump_data(5, (const char *)calc_md5_mac, 8);
00739
00740 DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n",
00741 (unsigned int)reply_seq_number));
00742 dump_data(5, (const char *)server_sent_mac, 8);
00743 }
00744
00745 #if 1
00746 {
00747 int i;
00748 reply_seq_number -= 5;
00749 for (i = 0; i < 10; i++, reply_seq_number++) {
00750 simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
00751 if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) {
00752 DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches. \
00753 We were expecting seq %u\n", reply_seq_number, saved_seq ));
00754 break;
00755 }
00756 }
00757 }
00758 #endif
00759
00760 } else {
00761 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));
00762 dump_data(10, (const char *)server_sent_mac, 8);
00763 }
00764
00765 return (signing_good(inbuf, si, good, saved_seq, must_be_ok));
00766 }
00767
00768
00769
00770
00771
00772 static struct smb_sign_info srv_sign_info = {
00773 null_sign_outgoing_message,
00774 null_check_incoming_message,
00775 null_free_signing_context,
00776 NULL,
00777 False,
00778 False,
00779 False,
00780 False
00781 };
00782
00783
00784
00785
00786
00787 BOOL srv_oplock_set_signing(BOOL onoff)
00788 {
00789 BOOL ret = srv_sign_info.doing_signing;
00790 srv_sign_info.doing_signing = onoff;
00791 return ret;
00792 }
00793
00794
00795
00796
00797
00798 BOOL srv_check_sign_mac(char *inbuf, BOOL must_be_ok)
00799 {
00800
00801 if(CVAL(inbuf,0) == SMBkeepalive)
00802 return True;
00803
00804 return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info, must_be_ok);
00805 }
00806
00807
00808
00809
00810
00811 void srv_calculate_sign_mac(char *outbuf)
00812 {
00813
00814
00815 if(CVAL(outbuf,0) == SMBkeepalive)
00816 return;
00817
00818 srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info);
00819 }
00820
00821
00822
00823
00824
00825 void srv_defer_sign_response(uint16 mid)
00826 {
00827 struct smb_basic_signing_context *data;
00828
00829 if (!srv_sign_info.doing_signing)
00830 return;
00831
00832 data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
00833
00834 if (!data)
00835 return;
00836
00837
00838
00839
00840
00841 store_sequence_for_reply(&data->outstanding_packet_list, mid,
00842 data->send_seq_num-1);
00843 }
00844
00845
00846
00847
00848
00849
00850 void srv_cancel_sign_response(uint16 mid)
00851 {
00852 struct smb_basic_signing_context *data;
00853 uint32 dummy_seq;
00854
00855 if (!srv_sign_info.doing_signing)
00856 return;
00857
00858 data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
00859
00860 if (!data)
00861 return;
00862
00863 DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid ));
00864
00865 while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq))
00866 ;
00867
00868
00869 data->send_seq_num -= 1;
00870 }
00871
00872
00873
00874
00875
00876 void srv_set_signing_negotiated(void)
00877 {
00878 srv_sign_info.allow_smb_signing = True;
00879 srv_sign_info.negotiated_smb_signing = True;
00880 if (lp_server_signing() == Required)
00881 srv_sign_info.mandatory_signing = True;
00882
00883 srv_sign_info.sign_outgoing_message = temp_sign_outgoing_message;
00884 srv_sign_info.check_incoming_message = temp_check_incoming_message;
00885 srv_sign_info.free_signing_context = temp_free_signing_context;
00886 }
00887
00888
00889
00890
00891
00892
00893 BOOL srv_is_signing_active(void)
00894 {
00895 return srv_sign_info.doing_signing;
00896 }
00897
00898
00899
00900
00901
00902
00903
00904 BOOL srv_is_signing_negotiated(void)
00905 {
00906 return srv_sign_info.negotiated_smb_signing;
00907 }
00908
00909
00910
00911
00912
00913 BOOL srv_signing_started(void)
00914 {
00915 struct smb_basic_signing_context *data;
00916
00917 if (!srv_sign_info.doing_signing) {
00918 return False;
00919 }
00920
00921 data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
00922 if (!data)
00923 return False;
00924
00925 if (data->send_seq_num == 0) {
00926 return False;
00927 }
00928
00929 return True;
00930 }
00931
00932
00933
00934
00935
00936 void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response)
00937 {
00938 struct smb_basic_signing_context *data;
00939
00940 if (!user_session_key.length)
00941 return;
00942
00943 if (!srv_sign_info.negotiated_smb_signing && !srv_sign_info.mandatory_signing) {
00944 DEBUG(5,("srv_set_signing: signing negotiated = %u, mandatory_signing = %u. Not allowing smb signing.\n",
00945 (unsigned int)srv_sign_info.negotiated_smb_signing,
00946 (unsigned int)srv_sign_info.mandatory_signing ));
00947 return;
00948 }
00949
00950
00951 if (srv_sign_info.doing_signing) {
00952 return;
00953 }
00954
00955 if (srv_sign_info.free_signing_context)
00956 srv_sign_info.free_signing_context(&srv_sign_info);
00957
00958 srv_sign_info.doing_signing = True;
00959
00960 data = SMB_XMALLOC_P(struct smb_basic_signing_context);
00961 memset(data, '\0', sizeof(*data));
00962
00963 srv_sign_info.signing_context = data;
00964
00965 data->mac_key = data_blob(NULL, response.length + user_session_key.length);
00966
00967 memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length);
00968 if (response.length)
00969 memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length);
00970
00971 dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length);
00972
00973 DEBUG(3,("srv_set_signing: turning on SMB signing: signing negotiated = %s, mandatory_signing = %s.\n",
00974 BOOLSTR(srv_sign_info.negotiated_smb_signing),
00975 BOOLSTR(srv_sign_info.mandatory_signing) ));
00976
00977
00978 data->send_seq_num = 0;
00979
00980
00981 data->outstanding_packet_list = NULL;
00982
00983 srv_sign_info.sign_outgoing_message = srv_sign_outgoing_message;
00984 srv_sign_info.check_incoming_message = srv_check_incoming_message;
00985 srv_sign_info.free_signing_context = simple_free_signing_context;
00986 }