diff options
-rw-r--r-- | source3/include/client.h | 13 | ||||
-rw-r--r-- | source3/include/ntlmssp.h | 18 | ||||
-rw-r--r-- | source3/libsmb/cliconnect.c | 94 | ||||
-rw-r--r-- | source3/libsmb/clientgen.c | 12 | ||||
-rw-r--r-- | source3/libsmb/smbencrypt.c | 100 |
5 files changed, 77 insertions, 160 deletions
diff --git a/source3/include/client.h b/source3/include/client.h index 28d6a8c330..0ea793de68 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -58,14 +58,15 @@ struct print_job_info }; typedef struct smb_sign_info { - BOOL use_smb_signing; + void (*sign_outgoing_message)(struct cli_state *cli); + BOOL (*check_incoming_message)(struct cli_state *cli); + void (*free_signing_context)(struct cli_state *cli); + void *signing_context; + BOOL negotiated_smb_signing; - BOOL temp_smb_signing; - size_t mac_key_len; - uint8 mac_key[64]; - uint32 send_seq_num; - uint32 reply_seq_num; BOOL allow_smb_signing; + BOOL doing_signing; + BOOL mandetory_signing; } smb_sign_info; struct cli_state { diff --git a/source3/include/ntlmssp.h b/source3/include/ntlmssp.h index 2fcefaaef3..f0278ffece 100644 --- a/source3/include/ntlmssp.h +++ b/source3/include/ntlmssp.h @@ -110,6 +110,24 @@ typedef struct ntlmssp_client_state DATA_BLOB session_key; uint32 neg_flags; + + /* SMB Signing */ + + uint32 ntlmssp_seq_num; + + /* ntlmv2 */ + char cli_sign_const[16]; + char cli_seal_const[16]; + char srv_sign_const[16]; + char srv_seal_const[16]; + + unsigned char cli_sign_hash[258]; + unsigned char cli_seal_hash[258]; + unsigned char srv_sign_hash[258]; + unsigned char srv_seal_hash[258]; + + /* ntlmv1 */ + unsigned char ntlmssp_hash[258]; } NTLMSSP_CLIENT_STATE; diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 54a282e805..763878f9b3 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -228,39 +228,11 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, return True; } -static void set_signing_on_cli (struct cli_state *cli, uint8 user_session_key[16], DATA_BLOB response) -{ - uint8 zero_sig[8]; - ZERO_STRUCT(zero_sig); - - DEBUG(5, ("Server returned security sig:\n")); - dump_data(5, &cli->inbuf[smb_ss_field], 8); - - if (cli->sign_info.use_smb_signing) { - DEBUG(5, ("smb signing already active on connection\n")); - } else if (memcmp(&cli->inbuf[smb_ss_field], zero_sig, 8) != 0) { - - DEBUG(3, ("smb signing enabled!\n")); - cli->sign_info.use_smb_signing = True; - cli_calculate_mac_key(cli, user_session_key, response); - } else { - DEBUG(5, ("smb signing NOT enabled!\n")); - } -} - static void set_cli_session_key (struct cli_state *cli, DATA_BLOB session_key) { memcpy(cli->user_session_key, session_key.data, MIN(session_key.length, sizeof(cli->user_session_key))); } - -static void set_temp_signing_on_cli(struct cli_state *cli) -{ - if (cli->sign_info.negotiated_smb_signing) - cli->sign_info.temp_smb_signing = True; -} - - /**************************************************************************** do a NT1 NTLM/LM encrypted session setup @param cli client state to create do session setup on @@ -310,8 +282,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, session_key = data_blob(NULL, 16); SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); } - - set_temp_signing_on_cli(cli); + cli_simple_set_signing(cli, session_key.data, nt_response); } else { /* pre-encrypted password supplied. Only used for security=server, can't do @@ -374,26 +345,24 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, if (session_key.data) { /* Have plaintext orginal */ set_cli_session_key(cli, session_key); - set_signing_on_cli(cli, session_key.data, nt_response); } + ret = True; end: data_blob_free(&lm_response); data_blob_free(&nt_response); data_blob_free(&session_key); - return True; + return ret; } /**************************************************************************** - Send a extended security session setup blob, returning a reply blob. + Send a extended security session setup blob ****************************************************************************/ -static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) +static BOOL cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob) { uint32 capabilities = cli_session_setup_capabilities(cli); char *p; - DATA_BLOB blob2 = data_blob(NULL, 0); - uint32 len; capabilities |= CAP_EXTENDED_SECURITY; @@ -403,8 +372,6 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) set_message(cli->outbuf,12,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); - set_temp_signing_on_cli(cli); - cli_setup_packet(cli); SCVAL(cli->outbuf,smb_vwv0,0xFF); @@ -420,7 +387,18 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); - cli_send_smb(cli); + return cli_send_smb(cli); +} + +/**************************************************************************** + Send a extended security session setup blob, returning a reply blob. +****************************************************************************/ + +static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli) +{ + DATA_BLOB blob2 = data_blob(NULL, 0); + char *p; + size_t len; if (!cli_receive_smb(cli)) return blob2; @@ -449,6 +427,20 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) return blob2; } +/**************************************************************************** + Send a extended security session setup blob, returning a reply blob. +****************************************************************************/ + +static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) +{ + DATA_BLOB blob2 = data_blob(NULL, 0); + if (!cli_session_setup_blob_send(cli, blob)) { + return blob2; + } + + return cli_session_setup_blob_receive(cli); +} + #ifdef HAVE_KRB5 /**************************************************************************** Use in-memory credentials cache @@ -502,6 +494,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, DATA_BLOB blob_in = data_blob(NULL, 0); DATA_BLOB blob_out; + cli_temp_set_signing(cli); + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { return False; } @@ -532,8 +526,15 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, } /* now send that blob on its way */ - blob = cli_session_setup_blob(cli, msg1); + if (!cli_session_setup_blob_send(cli, msg1)) { + return False; + } data_blob_free(&msg1); + + cli_ntlmssp_set_signing(cli, ntlmssp_state); + + blob = cli_session_setup_blob_receive(cli); + nt_status = cli_nt_error(cli); } @@ -570,6 +571,9 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, set_cli_session_key(cli, ntlmssp_state->session_key); } + /* we have a reference conter on ntlmssp_state, if we are signing + then the state will be kept by the signing engine */ + if (!NT_STATUS_IS_OK(ntlmssp_client_end(&ntlmssp_state))) { return False; } @@ -883,11 +887,6 @@ BOOL cli_negprot(struct cli_state *cli) int numprots; int plength; - if (cli->sign_info.use_smb_signing) { - DEBUG(0, ("Cannot send negprot again, particularly after setting up SMB Signing\n")); - return False; - } - if (cli->protocol < PROTOCOL_NT1) cli->use_spnego = False; @@ -1013,11 +1012,6 @@ BOOL cli_session_request(struct cli_state *cli, if (cli->port == 445) return True; - if (cli->sign_info.use_smb_signing) { - DEBUG(0, ("Cannot send session resquest again, particularly after setting up SMB Signing\n")); - return False; - } - /* send a session request (RFC 1002) */ /* setup the packet length * Remove four bytes from the length count, since the length diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 9598f4ac96..3cae643c38 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -177,9 +177,6 @@ void cli_setup_packet(struct cli_state *cli) flags2 |= FLAGS2_32_BIT_ERROR_CODES; if (cli->use_spnego) flags2 |= FLAGS2_EXTENDED_SECURITY; - if (cli->sign_info.use_smb_signing - || cli->sign_info.temp_smb_signing) - flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; SSVAL(cli->outbuf,smb_flg2, flags2); } } @@ -200,8 +197,8 @@ void cli_setup_bcc(struct cli_state *cli, void *p) void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) { /* copy_nt_creds(&cli->usr, usr); */ - safe_strcpy(cli->domain , usr->domain , sizeof(usr->domain )-1); - safe_strcpy(cli->user_name, usr->user_name, sizeof(usr->user_name)-1); + fstrcpy(cli->domain , usr->domain); + fstrcpy(cli->user_name, usr->user_name); memcpy(&cli->pwd, &usr->pwd, sizeof(usr->pwd)); cli->ntlmssp_flags = usr->ntlmssp_flags; cli->ntlmssp_cli_flgs = usr != NULL ? usr->ntlmssp_flags : 0; @@ -262,6 +259,9 @@ struct cli_state *cli_initialise(struct cli_state *cli) if (getenv("CLI_FORCE_DOSERR")) cli->force_dos_errors = True; + /* initialise signing */ + cli_null_set_signing(cli); + if (lp_client_signing()) cli->sign_info.allow_smb_signing = True; @@ -303,6 +303,7 @@ void cli_close_connection(struct cli_state *cli) SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); + cli_free_signing_context(cli); data_blob_free(&cli->secblob); if (cli->mem_ctx) { @@ -314,6 +315,7 @@ void cli_close_connection(struct cli_state *cli) close(cli->fd); cli->fd = -1; cli->smb_rw_error = 0; + } /**************************************************************************** diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index aa9391325f..28160d9609 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -295,7 +295,7 @@ void SMBsesskeygen_ntv1(const uchar kr[16], #endif } -DATA_BLOB NTLMv2_generate_response(uchar ntlm_v2_hash[16], +static DATA_BLOB NTLMv2_generate_response(uchar ntlm_v2_hash[16], DATA_BLOB server_chal, size_t client_chal_length) { uchar ntlmv2_response[16]; @@ -416,101 +416,3 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, return True; } - -/*********************************************************** - SMB signing - setup the MAC key. -************************************************************/ - -void cli_calculate_mac_key(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response) -{ - - memcpy(&cli->sign_info.mac_key[0], user_session_key, 16); - memcpy(&cli->sign_info.mac_key[16],response.data, MIN(response.length, 40 - 16)); - cli->sign_info.mac_key_len = MIN(response.length + 16, 40); - cli->sign_info.use_smb_signing = True; - - /* These calls are INCONPATIBLE with SMB signing */ - cli->readbraw_supported = False; - cli->writebraw_supported = False; - - /* Reset the sequence number in case we had a previous (aborted) attempt */ - cli->sign_info.send_seq_num = 2; -} - -/*********************************************************** - SMB signing - calculate a MAC to send. -************************************************************/ - -void cli_caclulate_sign_mac(struct cli_state *cli) -{ - unsigned char calc_md5_mac[16]; - struct MD5Context md5_ctx; - - if (cli->sign_info.temp_smb_signing) { - memcpy(&cli->outbuf[smb_ss_field], "SignRequest", 8); - cli->sign_info.temp_smb_signing = False; - return; - } - - if (!cli->sign_info.use_smb_signing) { - return; - } - - /* - * Firstly put the sequence number into the first 4 bytes. - * and zero out the next 4 bytes. - */ - SIVAL(cli->outbuf, smb_ss_field, cli->sign_info.send_seq_num); - SIVAL(cli->outbuf, smb_ss_field + 4, 0); - - /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ - MD5Init(&md5_ctx); - MD5Update(&md5_ctx, cli->sign_info.mac_key, cli->sign_info.mac_key_len); - MD5Update(&md5_ctx, cli->outbuf + 4, smb_len(cli->outbuf)); - MD5Final(calc_md5_mac, &md5_ctx); - - memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); - -/* cli->outbuf[smb_ss_field+2]=0; - Uncomment this to test if the remote server actually verifies signitures...*/ - cli->sign_info.send_seq_num++; - cli->sign_info.reply_seq_num = cli->sign_info.send_seq_num; - cli->sign_info.send_seq_num++; -} - -/*********************************************************** - SMB signing - check a MAC sent by server. -************************************************************/ - -BOOL cli_check_sign_mac(struct cli_state *cli) -{ - unsigned char calc_md5_mac[16]; - unsigned char server_sent_mac[8]; - struct MD5Context md5_ctx; - - if (cli->sign_info.temp_smb_signing) { - return True; - } - - if (!cli->sign_info.use_smb_signing) { - return True; - } - - /* - * Firstly put the sequence number into the first 4 bytes. - * and zero out the next 4 bytes. - */ - - memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); - - SIVAL(cli->inbuf, smb_ss_field, cli->sign_info.reply_seq_num); - SIVAL(cli->inbuf, smb_ss_field + 4, 0); - - /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ - MD5Init(&md5_ctx); - MD5Update(&md5_ctx, cli->sign_info.mac_key, cli->sign_info.mac_key_len); - MD5Update(&md5_ctx, cli->inbuf + 4, smb_len(cli->inbuf)); - MD5Final(calc_md5_mac, &md5_ctx); - - return (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); -} |