Add API framework for server SMB signing.
authorJeremy Allison <jra@samba.org>
Wed, 16 Jul 2003 21:06:21 +0000 (21:06 +0000)
committerJeremy Allison <jra@samba.org>
Wed, 16 Jul 2003 21:06:21 +0000 (21:06 +0000)
Jeremy.
(This used to be commit 61fc9a7b2eafdf8cbed1f8d9aae016b828c91a08)

source3/Makefile.in
source3/lib/util_sock.c
source3/libsmb/smb_signing.c
source3/smbd/oplock.c
source3/utils/status.c

index 73ff436c6f50bcb642789ab23c680a698058022e..e2cf94f55af53d6e35a6bbb159282cd2a5f9ba0c 100644 (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 \
index 1bd4c3a96beb45a261b9dbe99967f63e5f2493b9..5320b504eb6257759528d6424d60d7d3cc77d5f4 100644 (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));
-
-  /* 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;
-  }
+       /* and connect it to the destination */
+  connect_again:
+
+       ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
+
+       /* 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.
 
index f4ee6c00e048312eb0d4a0138bcab8bd5dea200b..e18d1ed42aaa7febe6a8f4735e6ecd9619ab5b46 100644 (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)
+{
+}
index 8525687793739cb1bd42bed9a63a7dac15207866..bd52b0066d6ce043fd39f973401100d6f7bbd7bf 100644 (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;
index bbaeecdd6bb2686ef6ca4db7518b2b0b349748fb..8e2cf87478995feaad7f4507603309bdc7873320 100644 (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)
 {