1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-12 09:18:10 +03:00

Add API framework for server SMB signing.

Jeremy.
This commit is contained in:
Jeremy Allison 0001-01-01 00:00:00 +00:00
parent dd46f8b22d
commit 61fc9a7b2e
5 changed files with 126 additions and 84 deletions

View File

@ -176,7 +176,7 @@ LIB_OBJ = lib/charcnv.o lib/debug.o lib/fault.o \
lib/util.o lib/util_sock.o lib/sock_exec.o lib/util_sec.o \
lib/talloc.o lib/hash.o lib/substitute.o lib/fsusage.o \
lib/ms_fnmatch.o lib/select.o lib/messages.o \
lib/tallocmsg.o lib/dmallocmsg.o \
lib/tallocmsg.o lib/dmallocmsg.o libsmb/smb_signing.o \
lib/md5.o lib/hmacmd5.o lib/iconv.o lib/smbpasswd.o \
nsswitch/wb_client.o nsswitch/wb_common.o \
lib/pam_errors.o intl/lang_tdb.o lib/account_pol.o \
@ -216,7 +216,7 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \
libsmb/clirap.o libsmb/clierror.o libsmb/climessage.o \
libsmb/clireadwrite.o libsmb/clilist.o libsmb/cliprint.o \
libsmb/clitrans.o libsmb/clisecdesc.o libsmb/clidgram.o \
libsmb/clistr.o libsmb/smb_signing.o \
libsmb/clistr.o \
libsmb/cliquota.o libsmb/clifsinfo.o \
libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \
libsmb/clioplock.o libsmb/errormap.o libsmb/clirap2.o \

View File

@ -289,7 +289,7 @@ ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,un
}
/****************************************************************************
read data from the client, reading exactly N bytes.
Read data from the client, reading exactly N bytes.
****************************************************************************/
ssize_t read_data(int fd,char *buffer,size_t N)
@ -397,7 +397,7 @@ static ssize_t write_socket_data(int fd,char *buffer,size_t N)
}
/****************************************************************************
write to a socket
Write to a socket.
****************************************************************************/
ssize_t write_socket(int fd,char *buf,size_t len)
@ -416,7 +416,7 @@ ssize_t write_socket(int fd,char *buf,size_t len)
}
/****************************************************************************
send a keepalive packet (rfc1002)
Send a keepalive packet (rfc1002).
****************************************************************************/
BOOL send_keepalive(int client)
@ -431,11 +431,11 @@ BOOL send_keepalive(int client)
/****************************************************************************
read 4 bytes of a smb packet and return the smb length of the packet
store the result in the buffer
This version of the function will return a length of zero on receiving
a keepalive packet.
timeout is in milliseconds.
Read 4 bytes of a smb packet and return the smb length of the packet.
Store the result in the buffer.
This version of the function will return a length of zero on receiving
a keepalive packet.
Timeout is in milliseconds.
****************************************************************************/
static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout)
@ -466,10 +466,10 @@ static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int
}
/****************************************************************************
read 4 bytes of a smb packet and return the smb length of the packet
store the result in the buffer. This version of the function will
never return a session keepalive (length of zero).
timeout is in milliseconds.
Read 4 bytes of a smb packet and return the smb length of the packet.
Store the result in the buffer. This version of the function will
never return a session keepalive (length of zero).
Timeout is in milliseconds.
****************************************************************************/
ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
@ -493,11 +493,10 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
}
/****************************************************************************
read an smb from a fd. Note that the buffer *MUST* be of size
BUFFER_SIZE+SAFETY_MARGIN.
The timeout is in milliseconds.
This function will return on a
receipt of a session keepalive packet.
Read an smb from a fd. Note that the buffer *MUST* be of size
BUFFER_SIZE+SAFETY_MARGIN.
The timeout is in milliseconds.
This function will return on receipt of a session keepalive packet.
****************************************************************************/
BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
@ -553,11 +552,19 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
}
}
/* Check the incoming SMB signature. */
if (!srv_check_sign_mac(buffer)) {
DEBUG(0, ("receive_smb: SMB Signature verification failed on incoming packet!\n"));
if (smb_read_error == 0)
smb_read_error = READ_BAD_SIG;
return False;
};
return(True);
}
/****************************************************************************
send an smb to a fd
Send an smb to a fd.
****************************************************************************/
BOOL send_smb(int fd,char *buffer)
@ -565,6 +572,10 @@ BOOL send_smb(int fd,char *buffer)
size_t len;
size_t nwritten=0;
ssize_t ret;
/* Sign the outgoing packet if required. */
srv_calculate_sign_mac(buffer);
len = smb_len(buffer) + 4;
while (nwritten < len) {
@ -647,80 +658,86 @@ int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL reb
}
/****************************************************************************
create an outgoing socket. timeout is in milliseconds.
**************************************************************************/
Create an outgoing socket. timeout is in milliseconds.
**************************************************************************/
int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
{
struct sockaddr_in sock_out;
int res,ret;
int connect_loop = 10;
int increment = 10;
struct sockaddr_in sock_out;
int res,ret;
int connect_loop = 10;
int increment = 10;
/* create a socket to write to */
res = socket(PF_INET, type, 0);
if (res == -1)
{ DEBUG(0,("socket error\n")); return -1; }
/* create a socket to write to */
res = socket(PF_INET, type, 0);
if (res == -1) {
DEBUG(0,("socket error\n"));
return -1;
}
if (type != SOCK_STREAM) return(res);
if (type != SOCK_STREAM)
return(res);
memset((char *)&sock_out,'\0',sizeof(sock_out));
putip((char *)&sock_out.sin_addr,(char *)addr);
memset((char *)&sock_out,'\0',sizeof(sock_out));
putip((char *)&sock_out.sin_addr,(char *)addr);
sock_out.sin_port = htons( port );
sock_out.sin_family = PF_INET;
sock_out.sin_port = htons( port );
sock_out.sin_family = PF_INET;
/* set it non-blocking */
set_blocking(res,False);
/* set it non-blocking */
set_blocking(res,False);
DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
/* and connect it to the destination */
connect_again:
ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
/* and connect it to the destination */
connect_again:
/* Some systems return EAGAIN when they mean EINPROGRESS */
if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
errno == EAGAIN) && (connect_loop < timeout) ) {
msleep(connect_loop);
connect_loop += increment;
if (increment < 250) {
/* After 8 rounds we end up at a max of 255 msec */
increment *= 1.5;
}
goto connect_again;
}
ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
errno == EAGAIN)) {
DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
close(res);
return -1;
}
/* Some systems return EAGAIN when they mean EINPROGRESS */
if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
errno == EAGAIN) && (connect_loop < timeout) ) {
msleep(connect_loop);
connect_loop += increment;
if (increment < 250) {
/* After 8 rounds we end up at a max of 255 msec */
increment *= 1.5;
}
goto connect_again;
}
if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
errno == EAGAIN)) {
DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
close(res);
return -1;
}
#ifdef EISCONN
if (ret < 0 && errno == EISCONN) {
errno = 0;
ret = 0;
}
if (ret < 0 && errno == EISCONN) {
errno = 0;
ret = 0;
}
#endif
if (ret < 0) {
DEBUG(2,("error connecting to %s:%d (%s)\n",
inet_ntoa(*addr),port,strerror(errno)));
close(res);
return -1;
}
if (ret < 0) {
DEBUG(2,("error connecting to %s:%d (%s)\n",
inet_ntoa(*addr),port,strerror(errno)));
close(res);
return -1;
}
/* set it blocking again */
set_blocking(res,True);
/* set it blocking again */
set_blocking(res,True);
return res;
return res;
}
/*
open a connected UDP socket to host on port
*/
/****************************************************************************
Open a connected UDP socket to host on port
**************************************************************************/
int open_udp_socket(const char *host, int port)
{
int type = SOCK_DGRAM;
@ -783,9 +800,10 @@ struct in_addr *client_inaddr(struct sockaddr *sa)
}
/*******************************************************************
matchname - determine if host name matches IP address. Used to
confirm a hostname lookup to prevent spoof attacks
******************************************************************/
Matchname - determine if host name matches IP address. Used to
confirm a hostname lookup to prevent spoof attacks.
******************************************************************/
static BOOL matchname(char *remotehost,struct in_addr addr)
{
struct hostent *hp;
@ -828,10 +846,10 @@ static BOOL matchname(char *remotehost,struct in_addr addr)
return False;
}
/*******************************************************************
return the DNS name of the remote end of a socket
******************************************************************/
Return the DNS name of the remote end of a socket.
******************************************************************/
char *get_socket_name(int fd, BOOL force_lookup)
{
static pstring name_buf;
@ -881,8 +899,9 @@ char *get_socket_name(int fd, BOOL force_lookup)
}
/*******************************************************************
return the IP addr of the remote end of a socket as a string
Return the IP addr of the remote end of a socket as a string.
******************************************************************/
char *get_socket_addr(int fd)
{
struct sockaddr sa;
@ -906,7 +925,6 @@ char *get_socket_addr(int fd)
return addr_buf;
}
/*******************************************************************
Create protected unix domain socket.

View File

@ -458,3 +458,24 @@ BOOL cli_check_sign_mac(struct cli_state *cli)
return True;
}
/***********************************************************
SMB signing - server API's.
************************************************************/
void srv_enable_signing(void)
{
}
void srv_disable_signing(void)
{
}
BOOL srv_check_sign_mac(char *buf)
{
return True;
}
void srv_calculate_sign_mac(char *buf)
{
}

View File

@ -742,8 +742,12 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id,
/* Remember if we just sent a break to level II on this file. */
fsp->sent_oplock_break = using_levelII? LEVEL_II_BREAK_SENT:EXCLUSIVE_BREAK_SENT;
if (!send_smb(smbd_server_fd(), outbuf))
srv_disable_signing();
if (!send_smb(smbd_server_fd(), outbuf)) {
srv_enable_signing();
exit_server("oplock_break: send_smb failed.");
}
srv_enable_signing();
/* We need this in case a readraw crosses on the wire. */
global_oplock_break = True;

View File

@ -49,7 +49,6 @@ static int show_brl;
void become_root(void) {}
void unbecome_root(void) {}
/* added by OH */
static void Ucrit_addUsername(const char *username)
{