]> andersk Git - openssh.git/commitdiff
20010112
authormouring <mouring>
Thu, 11 Jan 2001 06:20:23 +0000 (06:20 +0000)
committermouring <mouring>
Thu, 11 Jan 2001 06:20:23 +0000 (06:20 +0000)
 - (bal) OpenBSD Sync
   - markus@cvs.openbsd.org 2001/01/10 22:56:22
     [bufaux.h bufaux.c sftp-server.c sftp.h getput.h]
     cleanup sftp-server implementation:
     add buffer_get_int64, buffer_put_int64, GET_64BIT, PUT_64BIT
     parse SSH2_FILEXFER_ATTR_EXTENDED
     send SSH2_FX_EOF if readdir returns no more entries
     reply to SSH2_FXP_EXTENDED message
     use #defines from the draft
     move #definations to sftp.h
     more info:
     http://www.ietf.org/internet-drafts/draft-ietf-secsh-filexfer-00.txt
   - markus@cvs.openbsd.org 2001/01/10 19:43:20
     [sshd.c]
     XXX - generate_empheral_server_key() is not safe against races,
     because it calls log()
   - markus@cvs.openbsd.org 2001/01/09 21:19:50
     [packet.c]
     allow TCP_NDELAY for ipv6; from netbsd via itojun@

ChangeLog
bufaux.c
bufaux.h
getput.h
packet.c
sftp-server.c
sftp.h [new file with mode: 0644]
sshd.c

index 3919f779613a879d5be7dbddd99cc2d25efd75b8..9a92eb1c86d5bcb73aa8046a64e6d93b9edbdafc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+20010112
+ - (bal) OpenBSD Sync
+   - markus@cvs.openbsd.org 2001/01/10 22:56:22
+     [bufaux.h bufaux.c sftp-server.c sftp.h getput.h]
+     cleanup sftp-server implementation:
+            add buffer_get_int64, buffer_put_int64, GET_64BIT, PUT_64BIT
+            parse SSH2_FILEXFER_ATTR_EXTENDED
+            send SSH2_FX_EOF if readdir returns no more entries
+            reply to SSH2_FXP_EXTENDED message
+            use #defines from the draft
+            move #definations to sftp.h
+     more info:
+     http://www.ietf.org/internet-drafts/draft-ietf-secsh-filexfer-00.txt 
+   - markus@cvs.openbsd.org 2001/01/10 19:43:20
+     [sshd.c]
+     XXX - generate_empheral_server_key() is not safe against races,
+     because it calls log()     
+   - markus@cvs.openbsd.org 2001/01/09 21:19:50
+     [packet.c]
+     allow TCP_NDELAY for ipv6; from netbsd via itojun@
+
 20010110
  - (djm) SNI/Reliant Unix needs USE_PIPES and $DISPLAY hack. Report from
    Bladt Norbert <Norbert.Bladt@adi.ch>
index 5853ee6003ddecd0218f0d54d4a1816f4e3a2061..149677f74a89456f783c87e2f7c605a7e029940a 100644 (file)
--- a/bufaux.c
+++ b/bufaux.c
@@ -37,7 +37,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: bufaux.c,v 1.14 2000/12/19 23:17:55 markus Exp $");
+RCSID("$OpenBSD: bufaux.c,v 1.15 2001/01/10 22:56:22 markus Exp $");
 
 #include "ssh.h"
 #include <openssl/bn.h>
@@ -152,6 +152,14 @@ buffer_get_int(Buffer *buffer)
        return GET_32BIT(buf);
 }
 
+u_int64_t
+buffer_get_int64(Buffer *buffer)
+{
+       u_char buf[8];
+       buffer_get(buffer, (char *) buf, 8);
+       return GET_64BIT(buf);
+}
+
 /*
  * Stores an integer in the buffer in 4 bytes, msb first.
  */
@@ -163,6 +171,14 @@ buffer_put_int(Buffer *buffer, u_int value)
        buffer_append(buffer, buf, 4);
 }
 
+void
+buffer_put_int64(Buffer *buffer, u_int64_t value)
+{
+       char buf[8];
+       PUT_64BIT(buf, value);
+       buffer_append(buffer, buf, 8);
+}
+
 /*
  * Returns an arbitrary binary string from the buffer.  The string cannot
  * be longer than 256k.  The returned value points to memory allocated
index 6c73d4fb3c246acae353a67e2c1b0544dcaea39c..ec4300227b52ae570c67862fee457e8e23a05fa9 100644 (file)
--- a/bufaux.h
+++ b/bufaux.h
@@ -10,7 +10,7 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* RCSID("$OpenBSD: bufaux.h,v 1.9 2000/12/19 23:17:55 markus Exp $"); */
+/* RCSID("$OpenBSD: bufaux.h,v 1.10 2001/01/10 22:56:22 markus Exp $"); */
 
 #ifndef BUFAUX_H
 #define BUFAUX_H
@@ -30,9 +30,11 @@ int  buffer_get_bignum2(Buffer *buffer, BIGNUM * value);
 
 /* Returns an integer from the buffer (4 bytes, msb first). */
 u_int buffer_get_int(Buffer * buffer);
+u_int64_t buffer_get_int64(Buffer *buffer);
 
 /* Stores an integer in the buffer in 4 bytes, msb first. */
 void    buffer_put_int(Buffer * buffer, u_int value);
+void   buffer_put_int64(Buffer *buffer, u_int64_t value);
 
 /* Returns a character from the buffer (0 - 255). */
 int     buffer_get_char(Buffer * buffer);
index b8e83453a8b727b86e09da106fa6f7b1bbbfed8e..1a19d22cdb00be49b49a71afc27e9362b0f72da5 100644 (file)
--- a/getput.h
+++ b/getput.h
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* RCSID("$OpenBSD: getput.h,v 1.6 2000/12/19 23:17:56 markus Exp $"); */
+/* RCSID("$OpenBSD: getput.h,v 1.7 2001/01/10 22:56:22 markus Exp $"); */
 
 #ifndef GETPUT_H
 #define GETPUT_H
 
 /*------------ macros for storing/extracting msb first words -------------*/
 
+#define GET_64BIT(cp) (((u_int64_t)(u_char)(cp)[0] << 56) | \
+                      ((u_int64_t)(u_char)(cp)[1] << 48) | \
+                      ((u_int64_t)(u_char)(cp)[2] << 40) | \
+                      ((u_int64_t)(u_char)(cp)[3] << 32) | \
+                      ((u_int64_t)(u_char)(cp)[4] << 24) | \
+                      ((u_int64_t)(u_char)(cp)[5] << 16) | \
+                      ((u_int64_t)(u_char)(cp)[6] << 8) | \
+                      ((u_int64_t)(u_char)(cp)[7]))
+
 #define GET_32BIT(cp) (((u_long)(u_char)(cp)[0] << 24) | \
                       ((u_long)(u_char)(cp)[1] << 16) | \
                       ((u_long)(u_char)(cp)[2] << 8) | \
 #define GET_16BIT(cp) (((u_long)(u_char)(cp)[0] << 8) | \
                       ((u_long)(u_char)(cp)[1]))
 
+#define PUT_64BIT(cp, value) do { \
+  (cp)[0] = (value) >> 56; \
+  (cp)[1] = (value) >> 48; \
+  (cp)[2] = (value) >> 40; \
+  (cp)[3] = (value) >> 32; \
+  (cp)[4] = (value) >> 24; \
+  (cp)[5] = (value) >> 16; \
+  (cp)[6] = (value) >> 8; \
+  (cp)[7] = (value); } while (0)
+
 #define PUT_32BIT(cp, value) do { \
   (cp)[0] = (value) >> 24; \
   (cp)[1] = (value) >> 16; \
   (cp)[0] = (value) >> 8; \
   (cp)[1] = (value); } while (0)
 
-/*------------ macros for storing/extracting lsb first words -------------*/
-
-#define GET_32BIT_LSB_FIRST(cp) \
-  (((u_long)(u_char)(cp)[0]) | \
-  ((u_long)(u_char)(cp)[1] << 8) | \
-  ((u_long)(u_char)(cp)[2] << 16) | \
-  ((u_long)(u_char)(cp)[3] << 24))
-
-#define GET_16BIT_LSB_FIRST(cp) \
-  (((u_long)(u_char)(cp)[0]) | \
-  ((u_long)(u_char)(cp)[1] << 8))
-
-#define PUT_32BIT_LSB_FIRST(cp, value) do { \
-  (cp)[0] = (value); \
-  (cp)[1] = (value) >> 8; \
-  (cp)[2] = (value) >> 16; \
-  (cp)[3] = (value) >> 24; } while (0)
-
-#define PUT_16BIT_LSB_FIRST(cp, value) do { \
-  (cp)[0] = (value); \
-  (cp)[1] = (value) >> 8; } while (0)
-
 #endif                         /* GETPUT_H */
index 5435b07172e5b6073a6b50fe7cb1a676efb93105..cd42f2f75e82cd076383535870368f19598afc18 100644 (file)
--- a/packet.c
+++ b/packet.c
@@ -37,7 +37,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: packet.c,v 1.41 2001/01/02 20:41:02 markus Exp $");
+RCSID("$OpenBSD: packet.c,v 1.42 2001/01/09 21:19:50 markus Exp $");
 
 #include "xmalloc.h"
 #include "buffer.h"
@@ -1247,25 +1247,26 @@ packet_set_interactive(int interactive, int keepalives)
                        error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
        }
        /*
-        * IPTOS_LOWDELAY, TCP_NODELAY and IPTOS_THROUGHPUT are IPv4 only
+        * IPTOS_LOWDELAY and IPTOS_THROUGHPUT are IPv4 only
         */
-       if (!packet_connection_is_ipv4())
-               return;
        if (interactive) {
                /*
                 * Set IP options for an interactive connection.  Use
                 * IPTOS_LOWDELAY and TCP_NODELAY.
                 */
 #if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN)
-               int lowdelay = IPTOS_LOWDELAY;
-               if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &lowdelay,
-                   sizeof(lowdelay)) < 0)
-                       error("setsockopt IPTOS_LOWDELAY: %.100s", strerror(errno));
+               if (packet_connection_is_ipv4()) {
+                       int lowdelay = IPTOS_LOWDELAY;
+                       if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, 
+                           (void *) &lowdelay, sizeof(lowdelay)) < 0)
+                               error("setsockopt IPTOS_LOWDELAY: %.100s", 
+                                   strerror(errno));
+               }
 #endif
                if (setsockopt(connection_in, IPPROTO_TCP, TCP_NODELAY, (void *) &on,
                    sizeof(on)) < 0)
                        error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
-       } else {
+       } else if (packet_connection_is_ipv4()) {
                /*
                 * Set IP options for a non-interactive connection.  Use
                 * IPTOS_THROUGHPUT.
index 7113bce82a292cf886cff7c55adc64e7363215d8..40a5353140804bdea6eec36e00427e8e447090a3 100644 (file)
@@ -22,7 +22,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "includes.h"
-RCSID("$OpenBSD: sftp-server.c,v 1.9 2000/12/19 23:17:58 markus Exp $");
+RCSID("$OpenBSD: sftp-server.c,v 1.10 2001/01/10 22:56:22 markus Exp $");
 
 #include "ssh.h"
 #include "buffer.h"
@@ -30,65 +30,13 @@ RCSID("$OpenBSD: sftp-server.c,v 1.9 2000/12/19 23:17:58 markus Exp $");
 #include "getput.h"
 #include "xmalloc.h"
 
-/* version */
-#define        SSH_FILEXFER_VERSION            2
-
-/* client to server */
-#define        SSH_FXP_INIT                    1
-#define        SSH_FXP_OPEN                    3
-#define        SSH_FXP_CLOSE                   4
-#define        SSH_FXP_READ                    5
-#define        SSH_FXP_WRITE                   6
-#define        SSH_FXP_LSTAT                   7
-#define        SSH_FXP_FSTAT                   8
-#define        SSH_FXP_SETSTAT                 9
-#define        SSH_FXP_FSETSTAT                10
-#define        SSH_FXP_OPENDIR                 11
-#define        SSH_FXP_READDIR                 12
-#define        SSH_FXP_REMOVE                  13
-#define        SSH_FXP_MKDIR                   14
-#define        SSH_FXP_RMDIR                   15
-#define        SSH_FXP_REALPATH                16
-#define        SSH_FXP_STAT                    17
-#define        SSH_FXP_RENAME                  18
-
-/* server to client */
-#define        SSH_FXP_VERSION                 2
-#define        SSH_FXP_STATUS                  101
-#define        SSH_FXP_HANDLE                  102
-#define        SSH_FXP_DATA                    103
-#define        SSH_FXP_NAME                    104
-#define        SSH_FXP_ATTRS                   105
-
-/* portable open modes */
-#define        SSH_FXF_READ                    0x01
-#define        SSH_FXF_WRITE                   0x02
-#define        SSH_FXF_APPEND                  0x04
-#define        SSH_FXF_CREAT                   0x08
-#define        SSH_FXF_TRUNC                   0x10
-#define        SSH_FXF_EXCL                    0x20
-
-/* attributes */
-#define        SSH_FXA_HAVE_SIZE               0x01
-#define        SSH_FXA_HAVE_UGID               0x02
-#define        SSH_FXA_HAVE_PERM               0x04
-#define        SSH_FXA_HAVE_TIME               0x08
-
-/* status messages */
-#define        SSH_FX_OK                       0x00
-#define        SSH_FX_EOF                      0x01
-#define        SSH_FX_NO_SUCH_FILE             0x02
-#define        SSH_FX_PERMISSION_DENIED        0x03
-#define        SSH_FX_FAILURE                  0x04
-#define        SSH_FX_BAD_MESSAGE              0x05
-#define        SSH_FX_NO_CONNECTION            0x06
-#define        SSH_FX_CONNECTION_LOST          0x07
-
+#include "sftp.h"
 
 /* helper */
+#define get_int64()                    buffer_get_int64(&iqueue);
 #define get_int()                      buffer_get_int(&iqueue);
 #define get_string(lenp)               buffer_get_string(&iqueue, lenp);
-#define TRACE                          log
+#define TRACE                          debug
 
 #ifdef HAVE___PROGNAME
 extern char *__progname;
@@ -108,8 +56,6 @@ typedef struct Stat Stat;
 struct Attrib
 {
        u_int32_t       flags;
-       u_int32_t       size_high;
-       u_int32_t       size_low;
        u_int64_t       size;
        u_int32_t       uid;
        u_int32_t       gid;
@@ -131,25 +77,25 @@ errno_to_portable(int unixerrno)
        int ret = 0;
        switch (unixerrno) {
        case 0:
-               ret = SSH_FX_OK;
+               ret = SSH2_FX_OK;
                break;
        case ENOENT:
        case ENOTDIR:
        case EBADF:
        case ELOOP:
-               ret = SSH_FX_NO_SUCH_FILE;
+               ret = SSH2_FX_NO_SUCH_FILE;
                break;
        case EPERM:
        case EACCES:
        case EFAULT:
-               ret = SSH_FX_PERMISSION_DENIED;
+               ret = SSH2_FX_PERMISSION_DENIED;
                break;
        case ENAMETOOLONG:
        case EINVAL:
-               ret = SSH_FX_BAD_MESSAGE;
+               ret = SSH2_FX_BAD_MESSAGE;
                break;
        default:
-               ret = SSH_FX_FAILURE;
+               ret = SSH2_FX_FAILURE;
                break;
        }
        return ret;
@@ -159,19 +105,19 @@ int
 flags_from_portable(int pflags)
 {
        int flags = 0;
-       if (pflags & SSH_FXF_READ &&
-           pflags & SSH_FXF_WRITE) {
+       if (pflags & SSH2_FXF_READ &&
+           pflags & SSH2_FXF_WRITE) {
                flags = O_RDWR;
-       } else if (pflags & SSH_FXF_READ) {
+       } else if (pflags & SSH2_FXF_READ) {
                flags = O_RDONLY;
-       } else if (pflags & SSH_FXF_WRITE) {
+       } else if (pflags & SSH2_FXF_WRITE) {
                flags = O_WRONLY;
        }
-       if (pflags & SSH_FXF_CREAT)
+       if (pflags & SSH2_FXF_CREAT)
                flags |= O_CREAT;
-       if (pflags & SSH_FXF_TRUNC)
+       if (pflags & SSH2_FXF_TRUNC)
                flags |= O_TRUNC;
-       if (pflags & SSH_FXF_EXCL)
+       if (pflags & SSH2_FXF_EXCL)
                flags |= O_EXCL;
        return flags;
 }
@@ -180,8 +126,6 @@ void
 attrib_clear(Attrib *a)
 {
        a->flags = 0;
-       a->size_low = 0;
-       a->size_high = 0;
        a->size = 0;
        a->uid = 0;
        a->gid = 0;
@@ -196,22 +140,32 @@ decode_attrib(Buffer *b)
        static Attrib a;
        attrib_clear(&a);
        a.flags = buffer_get_int(b);
-       if (a.flags & SSH_FXA_HAVE_SIZE) {
-               a.size_high = buffer_get_int(b);
-               a.size_low = buffer_get_int(b);
-               a.size = (((u_int64_t) a.size_high) << 32) + a.size_low;
+       if (a.flags & SSH2_FILEXFER_ATTR_SIZE) {
+               a.size = buffer_get_int64(b);
        }
-       if (a.flags & SSH_FXA_HAVE_UGID) {
+       if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) {
                a.uid = buffer_get_int(b);
                a.gid = buffer_get_int(b);
        }
-       if (a.flags & SSH_FXA_HAVE_PERM) {
+       if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
                a.perm = buffer_get_int(b);
        }
-       if (a.flags & SSH_FXA_HAVE_TIME) {
+       if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
                a.atime = buffer_get_int(b);
                a.mtime = buffer_get_int(b);
        }
+       /* vendor-specific extensions */
+       if (a.flags & SSH2_FILEXFER_ATTR_EXTENDED) {
+               char *type, *data;
+               int i, count;
+               count = buffer_get_int(b);
+               for (i = 0; i < count; i++) {
+                       type = buffer_get_string(b, NULL);
+                       data = buffer_get_string(b, NULL);
+                       xfree(type);
+                       xfree(data);
+               }
+       }
        return &a;
 }
 
@@ -219,18 +173,17 @@ void
 encode_attrib(Buffer *b, Attrib *a)
 {
        buffer_put_int(b, a->flags);
-       if (a->flags & SSH_FXA_HAVE_SIZE) {
-               buffer_put_int(b, a->size_high);
-               buffer_put_int(b, a->size_low);
+       if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
+               buffer_put_int64(b, a->size);
        }
-       if (a->flags & SSH_FXA_HAVE_UGID) {
+       if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
                buffer_put_int(b, a->uid);
                buffer_put_int(b, a->gid);
        }
-       if (a->flags & SSH_FXA_HAVE_PERM) {
+       if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
                buffer_put_int(b, a->perm);
        }
-       if (a->flags & SSH_FXA_HAVE_TIME) {
+       if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
                buffer_put_int(b, a->atime);
                buffer_put_int(b, a->mtime);
        }
@@ -242,16 +195,14 @@ stat_to_attrib(struct stat *st)
        static Attrib a;
        attrib_clear(&a);
        a.flags = 0;
-       a.flags |= SSH_FXA_HAVE_SIZE;
+       a.flags |= SSH2_FILEXFER_ATTR_SIZE;
        a.size = st->st_size;
-       a.size_low = a.size;
-       a.size_high = (u_int32_t) (a.size >> 32);
-       a.flags |= SSH_FXA_HAVE_UGID;
+       a.flags |= SSH2_FILEXFER_ATTR_UIDGID;
        a.uid = st->st_uid;
        a.gid = st->st_gid;
-       a.flags |= SSH_FXA_HAVE_PERM;
+       a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
        a.perm = st->st_mode;
-       a.flags |= SSH_FXA_HAVE_TIME;
+       a.flags |= SSH2_FILEXFER_ATTR_ACMODTIME;
        a.atime = st->st_atime;
        a.mtime = st->st_mtime;
        return &a;
@@ -306,7 +257,8 @@ handle_new(int use, char *name, int fd, DIR *dirp)
 int
 handle_is_ok(int i, int type)
 {
-       return i >= 0 && i < sizeof(handles)/sizeof(Handle) && handles[i].use == type;
+       return i >= 0 && i < sizeof(handles)/sizeof(Handle) &&
+           handles[i].use == type;
 }
 
 int
@@ -381,10 +333,11 @@ int
 get_handle(void)
 {
        char *handle;
-       int val;
+       int val = -1;
        u_int hlen;
        handle = get_string(&hlen);
-       val = handle_from_string(handle, hlen);
+       if (hlen < 256)
+               val = handle_from_string(handle, hlen);
        xfree(handle);
        return val;
 }
@@ -406,7 +359,7 @@ send_status(u_int32_t id, u_int32_t error)
        Buffer msg;
        TRACE("sent status id %d error %d", id, error);
        buffer_init(&msg);
-       buffer_put_char(&msg, SSH_FXP_STATUS);
+       buffer_put_char(&msg, SSH2_FXP_STATUS);
        buffer_put_int(&msg, id);
        buffer_put_int(&msg, error);
        send_msg(&msg);
@@ -428,7 +381,7 @@ void
 send_data(u_int32_t id, char *data, int dlen)
 {
        TRACE("sent data id %d len %d", id, dlen);
-       send_data_or_handle(SSH_FXP_DATA, id, data, dlen);
+       send_data_or_handle(SSH2_FXP_DATA, id, data, dlen);
 }
 
 void
@@ -438,7 +391,7 @@ send_handle(u_int32_t id, int handle)
        int hlen;
        handle_to_string(handle, &string, &hlen);
        TRACE("sent handle id %d handle %d", id, handle);
-       send_data_or_handle(SSH_FXP_HANDLE, id, string, hlen);
+       send_data_or_handle(SSH2_FXP_HANDLE, id, string, hlen);
        xfree(string);
 }
 
@@ -448,7 +401,7 @@ send_names(u_int32_t id, int count, Stat *stats)
        Buffer msg;
        int i;
        buffer_init(&msg);
-       buffer_put_char(&msg, SSH_FXP_NAME);
+       buffer_put_char(&msg, SSH2_FXP_NAME);
        buffer_put_int(&msg, id);
        buffer_put_int(&msg, count);
        TRACE("sent names id %d count %d", id, count);
@@ -467,7 +420,7 @@ send_attrib(u_int32_t id, Attrib *a)
        Buffer msg;
        TRACE("sent attrib id %d have 0x%x", id, a->flags);
        buffer_init(&msg);
-       buffer_put_char(&msg, SSH_FXP_ATTRS);
+       buffer_put_char(&msg, SSH2_FXP_ATTRS);
        buffer_put_int(&msg, id);
        encode_attrib(&msg, a);
        send_msg(&msg);
@@ -484,8 +437,8 @@ process_init(void)
 
        TRACE("client version %d", version);
        buffer_init(&msg);
-       buffer_put_char(&msg, SSH_FXP_VERSION);
-       buffer_put_int(&msg, SSH_FILEXFER_VERSION);
+       buffer_put_char(&msg, SSH2_FXP_VERSION);
+       buffer_put_int(&msg, SSH2_FILEXFER_VERSION);
        send_msg(&msg);
        buffer_free(&msg);
 }
@@ -496,14 +449,14 @@ process_open(void)
        u_int32_t id, pflags;
        Attrib *a;
        char *name;
-       int handle, fd, flags, mode, status = SSH_FX_FAILURE;
+       int handle, fd, flags, mode, status = SSH2_FX_FAILURE;
 
        id = get_int();
        name = get_string(NULL);
-       pflags = get_int();
+       pflags = get_int();             /* portable flags */
        a = get_attrib();
        flags = flags_from_portable(pflags);
-       mode = (a->flags & SSH_FXA_HAVE_PERM) ? a->perm : 0666;
+       mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666;
        TRACE("open id %d name %s flags %d mode 0%o", id, name, pflags, mode);
        fd = open(name, flags, mode);
        if (fd < 0) {
@@ -514,10 +467,10 @@ process_open(void)
                        close(fd);
                } else {
                        send_handle(id, handle);
-                       status = SSH_FX_OK;
+                       status = SSH2_FX_OK;
                }
        }
-       if (status != SSH_FX_OK)
+       if (status != SSH2_FX_OK)
                send_status(id, status);
        xfree(name);
 }
@@ -526,13 +479,13 @@ void
 process_close(void)
 {
        u_int32_t id;
-       int handle, ret, status = SSH_FX_FAILURE;
+       int handle, ret, status = SSH2_FX_FAILURE;
 
        id = get_int();
        handle = get_handle();
        TRACE("close id %d handle %d", id, handle);
        ret = handle_close(handle);
-       status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK;
+       status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
        send_status(id, status);
 }
 
@@ -540,17 +493,15 @@ void
 process_read(void)
 {
        char buf[64*1024];
-       u_int32_t id, off_high, off_low, len;
-       int handle, fd, ret, status = SSH_FX_FAILURE;
+       u_int32_t id, len;
+       int handle, fd, ret, status = SSH2_FX_FAILURE;
        u_int64_t off;
 
        id = get_int();
        handle = get_handle();
-       off_high = get_int();
-       off_low = get_int();
+       off = get_int64();
        len = get_int();
 
-       off = (((u_int64_t) off_high) << 32) + off_low;
        TRACE("read id %d handle %d off %lld len %d", id, handle, off, len);
        if (len > sizeof buf) {
                len = sizeof buf;
@@ -566,33 +517,31 @@ process_read(void)
                        if (ret < 0) {
                                status = errno_to_portable(errno);
                        } else if (ret == 0) {
-                               status = SSH_FX_EOF;
+                               status = SSH2_FX_EOF;
                        } else {
                                send_data(id, buf, ret);
-                               status = SSH_FX_OK;
+                               status = SSH2_FX_OK;
                        }
                }
        }
-       if (status != SSH_FX_OK)
+       if (status != SSH2_FX_OK)
                send_status(id, status);
 }
 
 void
 process_write(void)
 {
-       u_int32_t id, off_high, off_low;
+       u_int32_t id;
        u_int64_t off;
        u_int len;
-       int handle, fd, ret, status = SSH_FX_FAILURE;
+       int handle, fd, ret, status = SSH2_FX_FAILURE;
        char *data;
 
        id = get_int();
        handle = get_handle();
-       off_high = get_int();
-       off_low = get_int();
+       off = get_int64();
        data = get_string(&len);
 
-       off = (((u_int64_t) off_high) << 32) + off_low;
        TRACE("write id %d handle %d off %lld len %d", id, handle, off, len);
        fd = handle_to_fd(handle);
        if (fd >= 0) {
@@ -606,7 +555,7 @@ process_write(void)
                                error("process_write: write failed");
                                status = errno_to_portable(errno);
                        } else if (ret == len) {
-                               status = SSH_FX_OK;
+                               status = SSH2_FX_OK;
                        } else {
                                log("nothing at all written");
                        }
@@ -623,7 +572,7 @@ process_do_stat(int do_lstat)
        struct stat st;
        u_int32_t id;
        char *name;
-       int ret, status = SSH_FX_FAILURE;
+       int ret, status = SSH2_FX_FAILURE;
 
        id = get_int();
        name = get_string(NULL);
@@ -634,9 +583,9 @@ process_do_stat(int do_lstat)
        } else {
                a = stat_to_attrib(&st);
                send_attrib(id, a);
-               status = SSH_FX_OK;
+               status = SSH2_FX_OK;
        }
-       if (status != SSH_FX_OK)
+       if (status != SSH2_FX_OK)
                send_status(id, status);
        xfree(name);
 }
@@ -659,7 +608,7 @@ process_fstat(void)
        Attrib *a;
        struct stat st;
        u_int32_t id;
-       int fd, ret, handle, status = SSH_FX_FAILURE;
+       int fd, ret, handle, status = SSH2_FX_FAILURE;
 
        id = get_int();
        handle = get_handle();
@@ -672,10 +621,10 @@ process_fstat(void)
                } else {
                        a = stat_to_attrib(&st);
                        send_attrib(id, a);
-                       status = SSH_FX_OK;
+                       status = SSH2_FX_OK;
                }
        }
-       if (status != SSH_FX_OK)
+       if (status != SSH2_FX_OK)
                send_status(id, status);
 }
 
@@ -697,18 +646,18 @@ process_setstat(void)
        u_int32_t id;
        char *name;
        int ret;
-       int status = SSH_FX_OK;
+       int status = SSH2_FX_OK;
 
        id = get_int();
        name = get_string(NULL);
        a = get_attrib();
        TRACE("setstat id %d name %s", id, name);
-       if (a->flags & SSH_FXA_HAVE_PERM) {
+       if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
                ret = chmod(name, a->perm & 0777);
                if (ret == -1)
                        status = errno_to_portable(errno);
        }
-       if (a->flags & SSH_FXA_HAVE_TIME) {
+       if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
                ret = utimes(name, attrib_to_tv(a));
                if (ret == -1)
                        status = errno_to_portable(errno);
@@ -723,7 +672,7 @@ process_fsetstat(void)
        Attrib *a;
        u_int32_t id;
        int handle, fd, ret;
-       int status = SSH_FX_OK;
+       int status = SSH2_FX_OK;
        char *name;
        
        id = get_int();
@@ -733,14 +682,14 @@ process_fsetstat(void)
        fd = handle_to_fd(handle);
        name = handle_to_name(handle);
        if ((fd < 0) || (name == NULL)) {
-               status = SSH_FX_FAILURE;
+               status = SSH2_FX_FAILURE;
        } else {
-               if (a->flags & SSH_FXA_HAVE_PERM) {
+               if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
                        ret = fchmod(fd, a->perm & 0777);
                        if (ret == -1)
                                status = errno_to_portable(errno);
                }
-               if (a->flags & SSH_FXA_HAVE_TIME) {
+               if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
 #ifdef HAVE_FUTIMES
                        ret = futimes(fd, attrib_to_tv(a));
 #else
@@ -758,7 +707,7 @@ process_opendir(void)
 {
        DIR *dirp = NULL;
        char *path;
-       int handle, status = SSH_FX_FAILURE;
+       int handle, status = SSH2_FX_FAILURE;
        u_int32_t id;
 
        id = get_int();
@@ -773,22 +722,28 @@ process_opendir(void)
                        closedir(dirp);
                } else {
                        send_handle(id, handle);
-                       status = SSH_FX_OK;
+                       status = SSH2_FX_OK;
                }
                
        }
-       if (status != SSH_FX_OK)
+       if (status != SSH2_FX_OK)
                send_status(id, status);
        xfree(path);
 }
 
+/*
+ * XXX, draft-ietf-secsh-filexfer-00.txt says: 
+ * The recommended format for the longname field is as follows:
+ * -rwxr-xr-x   1 mjos     staff      348911 Mar 25 14:29 t-filexfer
+ * 1234567890 123 12345678 12345678 12345678 123456789012
+ */
 char *
 ls_file(char *name, struct stat *st)
 {
        char buf[1024];
        snprintf(buf, sizeof buf, "0%o %d %d %lld %d %s",
-           st->st_mode, st->st_uid, st->st_gid, (long long)st->st_size,(int) st->st_mtime,
-           name);
+           st->st_mode, st->st_uid, st->st_gid, (long long)st->st_size,
+           (int)st->st_mtime, name);
        return xstrdup(buf);
 }
 
@@ -807,7 +762,7 @@ process_readdir(void)
        dirp = handle_to_dir(handle);
        path = handle_to_name(handle);
        if (dirp == NULL || path == NULL) {
-               send_status(id, SSH_FX_FAILURE);
+               send_status(id, SSH2_FX_FAILURE);
        } else {
                Attrib *a;
                struct stat st;
@@ -834,10 +789,14 @@ process_readdir(void)
                        if (count == 100)
                                break;
                }
-               send_names(id, count, stats);
-               for(i = 0; i < count; i++) {
-                       xfree(stats[i].name);
-                       xfree(stats[i].long_name);
+               if (count > 0) {
+                       send_names(id, count, stats);
+                       for(i = 0; i < count; i++) {
+                               xfree(stats[i].name);
+                               xfree(stats[i].long_name);
+                       }
+               } else {
+                       send_status(id, SSH2_FX_EOF);
                }
                xfree(stats);
        }
@@ -848,14 +807,14 @@ process_remove(void)
 {
        char *name;
        u_int32_t id;
-       int status = SSH_FX_FAILURE;
+       int status = SSH2_FX_FAILURE;
        int ret;
 
        id = get_int();
        name = get_string(NULL);
        TRACE("remove id %d name %s", id, name);
        ret = unlink(name);
-       status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK;
+       status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
        send_status(id, status);
        xfree(name);
 }
@@ -866,15 +825,16 @@ process_mkdir(void)
        Attrib *a;
        u_int32_t id;
        char *name;
-       int ret, mode, status = SSH_FX_FAILURE;
+       int ret, mode, status = SSH2_FX_FAILURE;
 
        id = get_int();
        name = get_string(NULL);
        a = get_attrib();
-       mode = (a->flags & SSH_FXA_HAVE_PERM) ? a->perm & 0777 : 0777;
+       mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ?
+           a->perm & 0777 : 0777;
        TRACE("mkdir id %d name %s mode 0%o", id, name, mode);
        ret = mkdir(name, mode);
-       status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK;
+       status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
        send_status(id, status);
        xfree(name);
 }
@@ -890,7 +850,7 @@ process_rmdir(void)
        name = get_string(NULL);
        TRACE("rmdir id %d name %s", id, name);
        ret = rmdir(name);
-       status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK;
+       status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
        send_status(id, status);
        xfree(name);
 }
@@ -932,12 +892,23 @@ process_rename(void)
        newpath = get_string(NULL);
        TRACE("rename id %d old %s new %s", id, oldpath, newpath);
        ret = rename(oldpath, newpath);
-       status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK;
+       status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
        send_status(id, status);
        xfree(oldpath);
        xfree(newpath);
 }
 
+void
+process_extended(void)
+{
+       u_int32_t id;
+       char *request;
+
+       id = get_int();
+       request = get_string(NULL);
+       send_status(id, SSH2_FX_OP_UNSUPPORTED);                /* MUST */
+       xfree(request);
+}
 
 /* stolen from ssh-agent */
 
@@ -961,57 +932,60 @@ process(void)
        buffer_consume(&iqueue, 4);
        type = buffer_get_char(&iqueue);
        switch (type) {
-       case SSH_FXP_INIT:
+       case SSH2_FXP_INIT:
                process_init();
                break;
-       case SSH_FXP_OPEN:
+       case SSH2_FXP_OPEN:
                process_open();
                break;
-       case SSH_FXP_CLOSE:
+       case SSH2_FXP_CLOSE:
                process_close();
                break;
-       case SSH_FXP_READ:
+       case SSH2_FXP_READ:
                process_read();
                break;
-       case SSH_FXP_WRITE:
+       case SSH2_FXP_WRITE:
                process_write();
                break;
-       case SSH_FXP_LSTAT:
+       case SSH2_FXP_LSTAT:
                process_lstat();
                break;
-       case SSH_FXP_FSTAT:
+       case SSH2_FXP_FSTAT:
                process_fstat();
                break;
-       case SSH_FXP_SETSTAT:
+       case SSH2_FXP_SETSTAT:
                process_setstat();
                break;
-       case SSH_FXP_FSETSTAT:
+       case SSH2_FXP_FSETSTAT:
                process_fsetstat();
                break;
-       case SSH_FXP_OPENDIR:
+       case SSH2_FXP_OPENDIR:
                process_opendir();
                break;
-       case SSH_FXP_READDIR:
+       case SSH2_FXP_READDIR:
                process_readdir();
                break;
-       case SSH_FXP_REMOVE:
+       case SSH2_FXP_REMOVE:
                process_remove();
                break;
-       case SSH_FXP_MKDIR:
+       case SSH2_FXP_MKDIR:
                process_mkdir();
                break;
-       case SSH_FXP_RMDIR:
+       case SSH2_FXP_RMDIR:
                process_rmdir();
                break;
-       case SSH_FXP_REALPATH:
+       case SSH2_FXP_REALPATH:
                process_realpath();
                break;
-       case SSH_FXP_STAT:
+       case SSH2_FXP_STAT:
                process_stat();
                break;
-       case SSH_FXP_RENAME:
+       case SSH2_FXP_RENAME:
                process_rename();
                break;
+       case SSH2_FXP_EXTENDED:
+               process_extended();
+               break;
        default:
                error("Unknown message %d", type);
                break;
@@ -1028,6 +1002,8 @@ main(int ac, char **av)
        __progname = get_progname(av[0]);
        handle_init();
 
+        log_init("sftp-server", SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH, 0);
+
        in = dup(STDIN_FILENO);
        out = dup(STDOUT_FILENO);
 
diff --git a/sftp.h b/sftp.h
new file mode 100644 (file)
index 0000000..4fdc2b6
--- /dev/null
+++ b/sftp.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2001 Markus Friedl.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * draft-ietf-secsh-filexfer-00.txt
+ */
+
+/* version */
+#define        SSH2_FILEXFER_VERSION           2
+
+/* client to server */
+#define SSH2_FXP_INIT                  1
+#define SSH2_FXP_OPEN                  3
+#define SSH2_FXP_CLOSE                 4
+#define SSH2_FXP_READ                  5
+#define SSH2_FXP_WRITE                 6
+#define SSH2_FXP_LSTAT                 7
+#define SSH2_FXP_FSTAT                 8
+#define SSH2_FXP_SETSTAT               9
+#define SSH2_FXP_FSETSTAT              10
+#define SSH2_FXP_OPENDIR               11
+#define SSH2_FXP_READDIR               12
+#define SSH2_FXP_REMOVE                        13
+#define SSH2_FXP_MKDIR                 14
+#define SSH2_FXP_RMDIR                 15
+#define SSH2_FXP_REALPATH              16
+#define SSH2_FXP_STAT                  17
+#define SSH2_FXP_RENAME                        18
+
+/* server to client */
+#define SSH2_FXP_VERSION               2
+#define SSH2_FXP_STATUS                        101
+#define SSH2_FXP_HANDLE                        102
+#define SSH2_FXP_DATA                  103
+#define SSH2_FXP_NAME                  104
+#define SSH2_FXP_ATTRS                 105
+
+#define SSH2_FXP_EXTENDED              200
+#define SSH2_FXP_EXTENDED_REPLY                201
+
+/* attributes */
+#define SSH2_FILEXFER_ATTR_SIZE                0x00000001
+#define SSH2_FILEXFER_ATTR_UIDGID      0x00000002
+#define SSH2_FILEXFER_ATTR_PERMISSIONS 0x00000004
+#define SSH2_FILEXFER_ATTR_ACMODTIME   0x00000008
+#define SSH2_FILEXFER_ATTR_EXTENDED    0x80000000
+
+/* portable open modes */
+#define SSH2_FXF_READ                  0x00000001
+#define SSH2_FXF_WRITE                 0x00000002
+#define SSH2_FXF_APPEND                        0x00000004
+#define SSH2_FXF_CREAT                 0x00000008
+#define SSH2_FXF_TRUNC                 0x00000010
+#define SSH2_FXF_EXCL                  0x00000020
+
+/* status messages */
+#define SSH2_FX_OK                     0
+#define SSH2_FX_EOF                    1
+#define SSH2_FX_NO_SUCH_FILE           2
+#define SSH2_FX_PERMISSION_DENIED      3
+#define SSH2_FX_FAILURE                        4
+#define SSH2_FX_BAD_MESSAGE            5
+#define SSH2_FX_NO_CONNECTION          6
+#define SSH2_FX_CONNECTION_LOST                7
+#define SSH2_FX_OP_UNSUPPORTED         8
diff --git a/sshd.c b/sshd.c
index aa7e016bfe8fd4cd2c1f8629d958659e2325792f..298a1b6bdd58955415451935bfed80da954941a9 100644 (file)
--- a/sshd.c
+++ b/sshd.c
@@ -40,7 +40,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.146 2001/01/07 11:28:07 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.147 2001/01/10 19:43:20 deraadt Exp $");
 
 #include "xmalloc.h"
 #include "rsa.h"
@@ -266,8 +266,8 @@ grace_alarm_handler(int sig)
  * do anything with the private key or random state before forking.
  * Thus there should be no concurrency control/asynchronous execution
  * problems.
+ * XXX calling log() is not safe from races.
  */
-/* XXX do we really want this work to be done in a signal handler ? -m */
 void
 generate_empheral_server_key(void)
 {
@@ -279,6 +279,7 @@ generate_empheral_server_key(void)
        arc4random_stir();
        log("RSA key generation complete.");
 }
+
 void
 key_regeneration_alarm(int sig)
 {
This page took 0.096198 seconds and 5 git commands to generate.