From afc93255d183eefb68e45b8ec6275f6a62cf9795 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 26 Dec 2007 17:12:36 -0800 Subject: Add SMB encryption. Still fixing client decrypt but negotiation works. Jeremy. (This used to be commit d78045601af787731f0737b8627450018902b104) --- source3/libsmb/clientgen.c | 108 ++++++++++++++++++++++++++++++--------------- 1 file changed, 73 insertions(+), 35 deletions(-) (limited to 'source3/libsmb/clientgen.c') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0544b3d879..da225ebc24 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -20,6 +20,21 @@ #include "includes.h" +/******************************************************************* + Setup the word count and byte count for a client smb message. +********************************************************************/ + +int cli_set_message(char *buf,int num_words,int num_bytes,bool zero) +{ + if (zero && (num_words || num_bytes)) { + memset(buf + smb_size,'\0',num_words*2 + num_bytes); + } + SCVAL(buf,smb_wct,num_words); + SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes); + smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4); + return (smb_size + num_words*2 + num_bytes); +} + /**************************************************************************** Change the timeout (in milliseconds). ****************************************************************************/ @@ -85,7 +100,7 @@ bool cli_receive_smb(struct cli_state *cli) /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ if (cli->fd == -1) - return False; + return false; again: len = client_receive_smb(cli, 0); @@ -100,7 +115,7 @@ bool cli_receive_smb(struct cli_state *cli) int fnum = SVAL(cli->inbuf,smb_vwv2); unsigned char level = CVAL(cli->inbuf,smb_vwv3+1); if (!cli->oplock_handler(cli, fnum, level)) { - return False; + return false; } } /* try to prevent loops */ @@ -114,7 +129,7 @@ bool cli_receive_smb(struct cli_state *cli) DEBUG(0, ("Receiving SMB: Server stopped responding\n")); close(cli->fd); cli->fd = -1; - return False; + return false; } if (!cli_check_sign_mac(cli)) { @@ -135,16 +150,16 @@ bool cli_receive_smb(struct cli_state *cli) * Set bad sig but don't close fd. */ cli->smb_rw_error = SMB_READ_BAD_SIG; - return True; + return true; } DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); cli->smb_rw_error = SMB_READ_BAD_SIG; close(cli->fd); cli->fd = -1; - return False; + return false; }; - return True; + return true; } /**************************************************************************** @@ -164,6 +179,7 @@ ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len) /**************************************************************************** Read a smb readX header. + We can only use this if encryption and signing are off. ****************************************************************************/ bool cli_receive_smb_readX_header(struct cli_state *cli) @@ -171,7 +187,7 @@ bool cli_receive_smb_readX_header(struct cli_state *cli) ssize_t len, offset; if (cli->fd == -1) - return False; + return false; again: @@ -199,7 +215,7 @@ bool cli_receive_smb_readX_header(struct cli_state *cli) if (cli->oplock_handler) { int fnum = SVAL(cli->inbuf,smb_vwv2); unsigned char level = CVAL(cli->inbuf,smb_vwv3+1); - if (!cli->oplock_handler(cli, fnum, level)) return False; + if (!cli->oplock_handler(cli, fnum, level)) return false; } /* try to prevent loops */ SCVAL(cli->inbuf,smb_com,0xFF); @@ -238,14 +254,14 @@ bool cli_receive_smb_readX_header(struct cli_state *cli) } } - return True; + return true; read_err: cli->smb_rw_error = SMB_READ_ERROR; close(cli->fd); cli->fd = -1; - return False; + return false; } static ssize_t write_socket(int fd, const char *buf, size_t len) @@ -272,32 +288,54 @@ bool cli_send_smb(struct cli_state *cli) size_t len; size_t nwritten=0; ssize_t ret; + char *buf_out = cli->outbuf; + bool enc_on = cli_encryption_on(cli); /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ if (cli->fd == -1) - return False; + return false; cli_calculate_sign_mac(cli); - len = smb_len(cli->outbuf) + 4; + if (enc_on) { + NTSTATUS status = cli_encrypt_message(cli, &buf_out); + if (!NT_STATUS_IS_OK(status)) { + close(cli->fd); + cli->fd = -1; + cli->smb_rw_error = SMB_WRITE_ERROR; + DEBUG(0,("Error in encrypting client message. Error %s\n", + nt_errstr(status) )); + return false; + } + } + + len = smb_len(buf_out) + 4; while (nwritten < len) { - ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); + ret = write_socket(cli->fd,buf_out+nwritten,len - nwritten); if (ret <= 0) { + if (enc_on) { + cli_free_enc_buffer(cli, buf_out); + } close(cli->fd); cli->fd = -1; cli->smb_rw_error = SMB_WRITE_ERROR; DEBUG(0,("Error writing %d bytes to client. %d (%s)\n", (int)len,(int)ret, strerror(errno) )); - return False; + return false; } nwritten += ret; } + + if (enc_on) { + cli_free_enc_buffer(cli, buf_out); + } + /* Increment the mid so we can tell between responses. */ cli->mid++; if (!cli->mid) cli->mid++; - return True; + return true; } /**************************************************************************** @@ -347,7 +385,7 @@ bool cli_send_smb_direct_writeX(struct cli_state *cli, DEBUG(0,("Error writing %d extradata " "bytes to client. %d (%s)\n", (int)extradata,(int)ret, strerror(errno) )); - return False; + return false; } nwritten += ret; } @@ -409,7 +447,7 @@ void cli_init_creds(struct cli_state *cli, const char *username, const char *dom fstrcpy(cli->user_name, username); pwd_set_cleartext(&cli->pwd, password); if (!*username) { - cli->pwd.null_pwd = True; + cli->pwd.null_pwd = true; } DEBUG(10,("cli_init_creds: user %s domain %s\n", cli->user_name, cli->domain)); @@ -424,16 +462,16 @@ void cli_setup_signing_state(struct cli_state *cli, int signing_state) if (signing_state == Undefined) return; - if (signing_state == False) { - cli->sign_info.allow_smb_signing = False; - cli->sign_info.mandatory_signing = False; + if (signing_state == false) { + cli->sign_info.allow_smb_signing = false; + cli->sign_info.mandatory_signing = false; return; } - cli->sign_info.allow_smb_signing = True; + cli->sign_info.allow_smb_signing = true; if (signing_state == Required) - cli->sign_info.mandatory_signing = True; + cli->sign_info.mandatory_signing = true; } /**************************************************************************** @@ -470,7 +508,7 @@ struct cli_state *cli_initialise(void) cli->outbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); cli->inbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); cli->oplock_handler = cli_oplock_ack; - cli->case_sensitive = False; + cli->case_sensitive = false; cli->smb_rw_error = SMB_READ_OK; cli->use_spnego = lp_client_use_spnego(); @@ -481,13 +519,13 @@ struct cli_state *cli_initialise(void) client routines using DOS errors instead of STATUS32 ones. This intended only as a temporary hack. */ if (getenv("CLI_FORCE_DOSERR")) - cli->force_dos_errors = True; + cli->force_dos_errors = true; if (lp_client_signing()) - cli->sign_info.allow_smb_signing = True; + cli->sign_info.allow_smb_signing = true; if (lp_client_signing() == Required) - cli->sign_info.mandatory_signing = True; + cli->sign_info.mandatory_signing = true; if (!cli->outbuf || !cli->inbuf) goto error; @@ -522,7 +560,7 @@ struct cli_state *cli_initialise(void) /**************************************************************************** External interface. Close an open named pipe over SMB. Free any authentication data. - Returns False if the cli_close call failed. + Returns false if the cli_close call failed. ****************************************************************************/ bool cli_rpc_pipe_close(struct rpc_pipe_client *cli) @@ -530,7 +568,7 @@ bool cli_rpc_pipe_close(struct rpc_pipe_client *cli) bool ret; if (!cli) { - return False; + return false; } ret = cli_close(cli->cli, cli->fnum); @@ -650,15 +688,15 @@ bool cli_send_keepalive(struct cli_state *cli) { if (cli->fd == -1) { DEBUG(3, ("cli_send_keepalive: fd == -1\n")); - return False; + return false; } if (!send_keepalive(cli->fd)) { close(cli->fd); cli->fd = -1; DEBUG(0,("Error sending keepalive packet to client.\n")); - return False; + return false; } - return True; + return true; } /**************************************************************************** @@ -674,7 +712,7 @@ bool cli_echo(struct cli_state *cli, uint16 num_echos, SMB_ASSERT(length < 1024); memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,1,length,True); + cli_set_message(cli->outbuf,1,length,true); SCVAL(cli->outbuf,smb_com,SMBecho); SSVAL(cli->outbuf,smb_tid,65535); SSVAL(cli->outbuf,smb_vwv0,num_echos); @@ -689,13 +727,13 @@ bool cli_echo(struct cli_state *cli, uint16 num_echos, for (i=0; i