summaryrefslogtreecommitdiff
path: root/source3/libsmb/clientgen.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2007-12-26 17:12:36 -0800
committerJeremy Allison <jra@samba.org>2007-12-26 17:12:36 -0800
commitafc93255d183eefb68e45b8ec6275f6a62cf9795 (patch)
tree712efc0cd3c95d30c0e44055b25807c41533bc1f /source3/libsmb/clientgen.c
parent23c965d9472058c566a1b9f8a44964acd5c8a446 (diff)
downloadsamba-afc93255d183eefb68e45b8ec6275f6a62cf9795.tar.gz
samba-afc93255d183eefb68e45b8ec6275f6a62cf9795.tar.bz2
samba-afc93255d183eefb68e45b8ec6275f6a62cf9795.zip
Add SMB encryption. Still fixing client decrypt but
negotiation works. Jeremy. (This used to be commit d78045601af787731f0737b8627450018902b104)
Diffstat (limited to 'source3/libsmb/clientgen.c')
-rw-r--r--source3/libsmb/clientgen.c108
1 files changed, 73 insertions, 35 deletions
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<num_echos; i++) {
if (!cli_receive_smb(cli)) {
- return False;
+ return false;
}
if (cli_is_error(cli)) {
- return False;
+ return false;
}
}
- return True;
+ return true;
}