summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog21
-rw-r--r--bufaux.c18
-rw-r--r--bufaux.h4
-rw-r--r--getput.h43
-rw-r--r--packet.c19
-rw-r--r--sftp-server.c314
-rw-r--r--sftp.h86
-rw-r--r--sshd.c5
8 files changed, 305 insertions, 205 deletions
diff --git a/ChangeLog b/ChangeLog
index 3919f7796..9a92eb1c8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
120010112
2 - (bal) OpenBSD Sync
3 - markus@cvs.openbsd.org 2001/01/10 22:56:22
4 [bufaux.h bufaux.c sftp-server.c sftp.h getput.h]
5 cleanup sftp-server implementation:
6 add buffer_get_int64, buffer_put_int64, GET_64BIT, PUT_64BIT
7 parse SSH2_FILEXFER_ATTR_EXTENDED
8 send SSH2_FX_EOF if readdir returns no more entries
9 reply to SSH2_FXP_EXTENDED message
10 use #defines from the draft
11 move #definations to sftp.h
12 more info:
13 http://www.ietf.org/internet-drafts/draft-ietf-secsh-filexfer-00.txt
14 - markus@cvs.openbsd.org 2001/01/10 19:43:20
15 [sshd.c]
16 XXX - generate_empheral_server_key() is not safe against races,
17 because it calls log()
18 - markus@cvs.openbsd.org 2001/01/09 21:19:50
19 [packet.c]
20 allow TCP_NDELAY for ipv6; from netbsd via itojun@
21
120010110 2220010110
2 - (djm) SNI/Reliant Unix needs USE_PIPES and $DISPLAY hack. Report from 23 - (djm) SNI/Reliant Unix needs USE_PIPES and $DISPLAY hack. Report from
3 Bladt Norbert <Norbert.Bladt@adi.ch> 24 Bladt Norbert <Norbert.Bladt@adi.ch>
diff --git a/bufaux.c b/bufaux.c
index 5853ee600..149677f74 100644
--- a/bufaux.c
+++ b/bufaux.c
@@ -37,7 +37,7 @@
37 */ 37 */
38 38
39#include "includes.h" 39#include "includes.h"
40RCSID("$OpenBSD: bufaux.c,v 1.14 2000/12/19 23:17:55 markus Exp $"); 40RCSID("$OpenBSD: bufaux.c,v 1.15 2001/01/10 22:56:22 markus Exp $");
41 41
42#include "ssh.h" 42#include "ssh.h"
43#include <openssl/bn.h> 43#include <openssl/bn.h>
@@ -152,6 +152,14 @@ buffer_get_int(Buffer *buffer)
152 return GET_32BIT(buf); 152 return GET_32BIT(buf);
153} 153}
154 154
155u_int64_t
156buffer_get_int64(Buffer *buffer)
157{
158 u_char buf[8];
159 buffer_get(buffer, (char *) buf, 8);
160 return GET_64BIT(buf);
161}
162
155/* 163/*
156 * Stores an integer in the buffer in 4 bytes, msb first. 164 * Stores an integer in the buffer in 4 bytes, msb first.
157 */ 165 */
@@ -163,6 +171,14 @@ buffer_put_int(Buffer *buffer, u_int value)
163 buffer_append(buffer, buf, 4); 171 buffer_append(buffer, buf, 4);
164} 172}
165 173
174void
175buffer_put_int64(Buffer *buffer, u_int64_t value)
176{
177 char buf[8];
178 PUT_64BIT(buf, value);
179 buffer_append(buffer, buf, 8);
180}
181
166/* 182/*
167 * Returns an arbitrary binary string from the buffer. The string cannot 183 * Returns an arbitrary binary string from the buffer. The string cannot
168 * be longer than 256k. The returned value points to memory allocated 184 * be longer than 256k. The returned value points to memory allocated
diff --git a/bufaux.h b/bufaux.h
index 6c73d4fb3..ec4300227 100644
--- a/bufaux.h
+++ b/bufaux.h
@@ -10,7 +10,7 @@
10 * called by a name other than "ssh" or "Secure Shell". 10 * called by a name other than "ssh" or "Secure Shell".
11 */ 11 */
12 12
13/* RCSID("$OpenBSD: bufaux.h,v 1.9 2000/12/19 23:17:55 markus Exp $"); */ 13/* RCSID("$OpenBSD: bufaux.h,v 1.10 2001/01/10 22:56:22 markus Exp $"); */
14 14
15#ifndef BUFAUX_H 15#ifndef BUFAUX_H
16#define BUFAUX_H 16#define BUFAUX_H
@@ -30,9 +30,11 @@ int buffer_get_bignum2(Buffer *buffer, BIGNUM * value);
30 30
31/* Returns an integer from the buffer (4 bytes, msb first). */ 31/* Returns an integer from the buffer (4 bytes, msb first). */
32u_int buffer_get_int(Buffer * buffer); 32u_int buffer_get_int(Buffer * buffer);
33u_int64_t buffer_get_int64(Buffer *buffer);
33 34
34/* Stores an integer in the buffer in 4 bytes, msb first. */ 35/* Stores an integer in the buffer in 4 bytes, msb first. */
35void buffer_put_int(Buffer * buffer, u_int value); 36void buffer_put_int(Buffer * buffer, u_int value);
37void buffer_put_int64(Buffer *buffer, u_int64_t value);
36 38
37/* Returns a character from the buffer (0 - 255). */ 39/* Returns a character from the buffer (0 - 255). */
38int buffer_get_char(Buffer * buffer); 40int buffer_get_char(Buffer * buffer);
diff --git a/getput.h b/getput.h
index b8e83453a..1a19d22cd 100644
--- a/getput.h
+++ b/getput.h
@@ -11,13 +11,22 @@
11 * called by a name other than "ssh" or "Secure Shell". 11 * called by a name other than "ssh" or "Secure Shell".
12 */ 12 */
13 13
14/* RCSID("$OpenBSD: getput.h,v 1.6 2000/12/19 23:17:56 markus Exp $"); */ 14/* RCSID("$OpenBSD: getput.h,v 1.7 2001/01/10 22:56:22 markus Exp $"); */
15 15
16#ifndef GETPUT_H 16#ifndef GETPUT_H
17#define GETPUT_H 17#define GETPUT_H
18 18
19/*------------ macros for storing/extracting msb first words -------------*/ 19/*------------ macros for storing/extracting msb first words -------------*/
20 20
21#define GET_64BIT(cp) (((u_int64_t)(u_char)(cp)[0] << 56) | \
22 ((u_int64_t)(u_char)(cp)[1] << 48) | \
23 ((u_int64_t)(u_char)(cp)[2] << 40) | \
24 ((u_int64_t)(u_char)(cp)[3] << 32) | \
25 ((u_int64_t)(u_char)(cp)[4] << 24) | \
26 ((u_int64_t)(u_char)(cp)[5] << 16) | \
27 ((u_int64_t)(u_char)(cp)[6] << 8) | \
28 ((u_int64_t)(u_char)(cp)[7]))
29
21#define GET_32BIT(cp) (((u_long)(u_char)(cp)[0] << 24) | \ 30#define GET_32BIT(cp) (((u_long)(u_char)(cp)[0] << 24) | \
22 ((u_long)(u_char)(cp)[1] << 16) | \ 31 ((u_long)(u_char)(cp)[1] << 16) | \
23 ((u_long)(u_char)(cp)[2] << 8) | \ 32 ((u_long)(u_char)(cp)[2] << 8) | \
@@ -26,6 +35,16 @@
26#define GET_16BIT(cp) (((u_long)(u_char)(cp)[0] << 8) | \ 35#define GET_16BIT(cp) (((u_long)(u_char)(cp)[0] << 8) | \
27 ((u_long)(u_char)(cp)[1])) 36 ((u_long)(u_char)(cp)[1]))
28 37
38#define PUT_64BIT(cp, value) do { \
39 (cp)[0] = (value) >> 56; \
40 (cp)[1] = (value) >> 48; \
41 (cp)[2] = (value) >> 40; \
42 (cp)[3] = (value) >> 32; \
43 (cp)[4] = (value) >> 24; \
44 (cp)[5] = (value) >> 16; \
45 (cp)[6] = (value) >> 8; \
46 (cp)[7] = (value); } while (0)
47
29#define PUT_32BIT(cp, value) do { \ 48#define PUT_32BIT(cp, value) do { \
30 (cp)[0] = (value) >> 24; \ 49 (cp)[0] = (value) >> 24; \
31 (cp)[1] = (value) >> 16; \ 50 (cp)[1] = (value) >> 16; \
@@ -36,26 +55,4 @@
36 (cp)[0] = (value) >> 8; \ 55 (cp)[0] = (value) >> 8; \
37 (cp)[1] = (value); } while (0) 56 (cp)[1] = (value); } while (0)
38 57
39/*------------ macros for storing/extracting lsb first words -------------*/
40
41#define GET_32BIT_LSB_FIRST(cp) \
42 (((u_long)(u_char)(cp)[0]) | \
43 ((u_long)(u_char)(cp)[1] << 8) | \
44 ((u_long)(u_char)(cp)[2] << 16) | \
45 ((u_long)(u_char)(cp)[3] << 24))
46
47#define GET_16BIT_LSB_FIRST(cp) \
48 (((u_long)(u_char)(cp)[0]) | \
49 ((u_long)(u_char)(cp)[1] << 8))
50
51#define PUT_32BIT_LSB_FIRST(cp, value) do { \
52 (cp)[0] = (value); \
53 (cp)[1] = (value) >> 8; \
54 (cp)[2] = (value) >> 16; \
55 (cp)[3] = (value) >> 24; } while (0)
56
57#define PUT_16BIT_LSB_FIRST(cp, value) do { \
58 (cp)[0] = (value); \
59 (cp)[1] = (value) >> 8; } while (0)
60
61#endif /* GETPUT_H */ 58#endif /* GETPUT_H */
diff --git a/packet.c b/packet.c
index 5435b0717..cd42f2f75 100644
--- a/packet.c
+++ b/packet.c
@@ -37,7 +37,7 @@
37 */ 37 */
38 38
39#include "includes.h" 39#include "includes.h"
40RCSID("$OpenBSD: packet.c,v 1.41 2001/01/02 20:41:02 markus Exp $"); 40RCSID("$OpenBSD: packet.c,v 1.42 2001/01/09 21:19:50 markus Exp $");
41 41
42#include "xmalloc.h" 42#include "xmalloc.h"
43#include "buffer.h" 43#include "buffer.h"
@@ -1247,25 +1247,26 @@ packet_set_interactive(int interactive, int keepalives)
1247 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); 1247 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
1248 } 1248 }
1249 /* 1249 /*
1250 * IPTOS_LOWDELAY, TCP_NODELAY and IPTOS_THROUGHPUT are IPv4 only 1250 * IPTOS_LOWDELAY and IPTOS_THROUGHPUT are IPv4 only
1251 */ 1251 */
1252 if (!packet_connection_is_ipv4())
1253 return;
1254 if (interactive) { 1252 if (interactive) {
1255 /* 1253 /*
1256 * Set IP options for an interactive connection. Use 1254 * Set IP options for an interactive connection. Use
1257 * IPTOS_LOWDELAY and TCP_NODELAY. 1255 * IPTOS_LOWDELAY and TCP_NODELAY.
1258 */ 1256 */
1259#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN) 1257#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN)
1260 int lowdelay = IPTOS_LOWDELAY; 1258 if (packet_connection_is_ipv4()) {
1261 if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &lowdelay, 1259 int lowdelay = IPTOS_LOWDELAY;
1262 sizeof(lowdelay)) < 0) 1260 if (setsockopt(connection_in, IPPROTO_IP, IP_TOS,
1263 error("setsockopt IPTOS_LOWDELAY: %.100s", strerror(errno)); 1261 (void *) &lowdelay, sizeof(lowdelay)) < 0)
1262 error("setsockopt IPTOS_LOWDELAY: %.100s",
1263 strerror(errno));
1264 }
1264#endif 1265#endif
1265 if (setsockopt(connection_in, IPPROTO_TCP, TCP_NODELAY, (void *) &on, 1266 if (setsockopt(connection_in, IPPROTO_TCP, TCP_NODELAY, (void *) &on,
1266 sizeof(on)) < 0) 1267 sizeof(on)) < 0)
1267 error("setsockopt TCP_NODELAY: %.100s", strerror(errno)); 1268 error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
1268 } else { 1269 } else if (packet_connection_is_ipv4()) {
1269 /* 1270 /*
1270 * Set IP options for a non-interactive connection. Use 1271 * Set IP options for a non-interactive connection. Use
1271 * IPTOS_THROUGHPUT. 1272 * IPTOS_THROUGHPUT.
diff --git a/sftp-server.c b/sftp-server.c
index 7113bce82..40a535314 100644
--- a/sftp-server.c
+++ b/sftp-server.c
@@ -22,7 +22,7 @@
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */ 23 */
24#include "includes.h" 24#include "includes.h"
25RCSID("$OpenBSD: sftp-server.c,v 1.9 2000/12/19 23:17:58 markus Exp $"); 25RCSID("$OpenBSD: sftp-server.c,v 1.10 2001/01/10 22:56:22 markus Exp $");
26 26
27#include "ssh.h" 27#include "ssh.h"
28#include "buffer.h" 28#include "buffer.h"
@@ -30,65 +30,13 @@ RCSID("$OpenBSD: sftp-server.c,v 1.9 2000/12/19 23:17:58 markus Exp $");
30#include "getput.h" 30#include "getput.h"
31#include "xmalloc.h" 31#include "xmalloc.h"
32 32
33/* version */ 33#include "sftp.h"
34#define SSH_FILEXFER_VERSION 2
35
36/* client to server */
37#define SSH_FXP_INIT 1
38#define SSH_FXP_OPEN 3
39#define SSH_FXP_CLOSE 4
40#define SSH_FXP_READ 5
41#define SSH_FXP_WRITE 6
42#define SSH_FXP_LSTAT 7
43#define SSH_FXP_FSTAT 8
44#define SSH_FXP_SETSTAT 9
45#define SSH_FXP_FSETSTAT 10
46#define SSH_FXP_OPENDIR 11
47#define SSH_FXP_READDIR 12
48#define SSH_FXP_REMOVE 13
49#define SSH_FXP_MKDIR 14
50#define SSH_FXP_RMDIR 15
51#define SSH_FXP_REALPATH 16
52#define SSH_FXP_STAT 17
53#define SSH_FXP_RENAME 18
54
55/* server to client */
56#define SSH_FXP_VERSION 2
57#define SSH_FXP_STATUS 101
58#define SSH_FXP_HANDLE 102
59#define SSH_FXP_DATA 103
60#define SSH_FXP_NAME 104
61#define SSH_FXP_ATTRS 105
62
63/* portable open modes */
64#define SSH_FXF_READ 0x01
65#define SSH_FXF_WRITE 0x02
66#define SSH_FXF_APPEND 0x04
67#define SSH_FXF_CREAT 0x08
68#define SSH_FXF_TRUNC 0x10
69#define SSH_FXF_EXCL 0x20
70
71/* attributes */
72#define SSH_FXA_HAVE_SIZE 0x01
73#define SSH_FXA_HAVE_UGID 0x02
74#define SSH_FXA_HAVE_PERM 0x04
75#define SSH_FXA_HAVE_TIME 0x08
76
77/* status messages */
78#define SSH_FX_OK 0x00
79#define SSH_FX_EOF 0x01
80#define SSH_FX_NO_SUCH_FILE 0x02
81#define SSH_FX_PERMISSION_DENIED 0x03
82#define SSH_FX_FAILURE 0x04
83#define SSH_FX_BAD_MESSAGE 0x05
84#define SSH_FX_NO_CONNECTION 0x06
85#define SSH_FX_CONNECTION_LOST 0x07
86
87 34
88/* helper */ 35/* helper */
36#define get_int64() buffer_get_int64(&iqueue);
89#define get_int() buffer_get_int(&iqueue); 37#define get_int() buffer_get_int(&iqueue);
90#define get_string(lenp) buffer_get_string(&iqueue, lenp); 38#define get_string(lenp) buffer_get_string(&iqueue, lenp);
91#define TRACE log 39#define TRACE debug
92 40
93#ifdef HAVE___PROGNAME 41#ifdef HAVE___PROGNAME
94extern char *__progname; 42extern char *__progname;
@@ -108,8 +56,6 @@ typedef struct Stat Stat;
108struct Attrib 56struct Attrib
109{ 57{
110 u_int32_t flags; 58 u_int32_t flags;
111 u_int32_t size_high;
112 u_int32_t size_low;
113 u_int64_t size; 59 u_int64_t size;
114 u_int32_t uid; 60 u_int32_t uid;
115 u_int32_t gid; 61 u_int32_t gid;
@@ -131,25 +77,25 @@ errno_to_portable(int unixerrno)
131 int ret = 0; 77 int ret = 0;
132 switch (unixerrno) { 78 switch (unixerrno) {
133 case 0: 79 case 0:
134 ret = SSH_FX_OK; 80 ret = SSH2_FX_OK;
135 break; 81 break;
136 case ENOENT: 82 case ENOENT:
137 case ENOTDIR: 83 case ENOTDIR:
138 case EBADF: 84 case EBADF:
139 case ELOOP: 85 case ELOOP:
140 ret = SSH_FX_NO_SUCH_FILE; 86 ret = SSH2_FX_NO_SUCH_FILE;
141 break; 87 break;
142 case EPERM: 88 case EPERM:
143 case EACCES: 89 case EACCES:
144 case EFAULT: 90 case EFAULT:
145 ret = SSH_FX_PERMISSION_DENIED; 91 ret = SSH2_FX_PERMISSION_DENIED;
146 break; 92 break;
147 case ENAMETOOLONG: 93 case ENAMETOOLONG:
148 case EINVAL: 94 case EINVAL:
149 ret = SSH_FX_BAD_MESSAGE; 95 ret = SSH2_FX_BAD_MESSAGE;
150 break; 96 break;
151 default: 97 default:
152 ret = SSH_FX_FAILURE; 98 ret = SSH2_FX_FAILURE;
153 break; 99 break;
154 } 100 }
155 return ret; 101 return ret;
@@ -159,19 +105,19 @@ int
159flags_from_portable(int pflags) 105flags_from_portable(int pflags)
160{ 106{
161 int flags = 0; 107 int flags = 0;
162 if (pflags & SSH_FXF_READ && 108 if (pflags & SSH2_FXF_READ &&
163 pflags & SSH_FXF_WRITE) { 109 pflags & SSH2_FXF_WRITE) {
164 flags = O_RDWR; 110 flags = O_RDWR;
165 } else if (pflags & SSH_FXF_READ) { 111 } else if (pflags & SSH2_FXF_READ) {
166 flags = O_RDONLY; 112 flags = O_RDONLY;
167 } else if (pflags & SSH_FXF_WRITE) { 113 } else if (pflags & SSH2_FXF_WRITE) {
168 flags = O_WRONLY; 114 flags = O_WRONLY;
169 } 115 }
170 if (pflags & SSH_FXF_CREAT) 116 if (pflags & SSH2_FXF_CREAT)
171 flags |= O_CREAT; 117 flags |= O_CREAT;
172 if (pflags & SSH_FXF_TRUNC) 118 if (pflags & SSH2_FXF_TRUNC)
173 flags |= O_TRUNC; 119 flags |= O_TRUNC;
174 if (pflags & SSH_FXF_EXCL) 120 if (pflags & SSH2_FXF_EXCL)
175 flags |= O_EXCL; 121 flags |= O_EXCL;
176 return flags; 122 return flags;
177} 123}
@@ -180,8 +126,6 @@ void
180attrib_clear(Attrib *a) 126attrib_clear(Attrib *a)
181{ 127{
182 a->flags = 0; 128 a->flags = 0;
183 a->size_low = 0;
184 a->size_high = 0;
185 a->size = 0; 129 a->size = 0;
186 a->uid = 0; 130 a->uid = 0;
187 a->gid = 0; 131 a->gid = 0;
@@ -196,22 +140,32 @@ decode_attrib(Buffer *b)
196 static Attrib a; 140 static Attrib a;
197 attrib_clear(&a); 141 attrib_clear(&a);
198 a.flags = buffer_get_int(b); 142 a.flags = buffer_get_int(b);
199 if (a.flags & SSH_FXA_HAVE_SIZE) { 143 if (a.flags & SSH2_FILEXFER_ATTR_SIZE) {
200 a.size_high = buffer_get_int(b); 144 a.size = buffer_get_int64(b);
201 a.size_low = buffer_get_int(b);
202 a.size = (((u_int64_t) a.size_high) << 32) + a.size_low;
203 } 145 }
204 if (a.flags & SSH_FXA_HAVE_UGID) { 146 if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) {
205 a.uid = buffer_get_int(b); 147 a.uid = buffer_get_int(b);
206 a.gid = buffer_get_int(b); 148 a.gid = buffer_get_int(b);
207 } 149 }
208 if (a.flags & SSH_FXA_HAVE_PERM) { 150 if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
209 a.perm = buffer_get_int(b); 151 a.perm = buffer_get_int(b);
210 } 152 }
211 if (a.flags & SSH_FXA_HAVE_TIME) { 153 if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
212 a.atime = buffer_get_int(b); 154 a.atime = buffer_get_int(b);
213 a.mtime = buffer_get_int(b); 155 a.mtime = buffer_get_int(b);
214 } 156 }
157 /* vendor-specific extensions */
158 if (a.flags & SSH2_FILEXFER_ATTR_EXTENDED) {
159 char *type, *data;
160 int i, count;
161 count = buffer_get_int(b);
162 for (i = 0; i < count; i++) {
163 type = buffer_get_string(b, NULL);
164 data = buffer_get_string(b, NULL);
165 xfree(type);
166 xfree(data);
167 }
168 }
215 return &a; 169 return &a;
216} 170}
217 171
@@ -219,18 +173,17 @@ void
219encode_attrib(Buffer *b, Attrib *a) 173encode_attrib(Buffer *b, Attrib *a)
220{ 174{
221 buffer_put_int(b, a->flags); 175 buffer_put_int(b, a->flags);
222 if (a->flags & SSH_FXA_HAVE_SIZE) { 176 if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
223 buffer_put_int(b, a->size_high); 177 buffer_put_int64(b, a->size);
224 buffer_put_int(b, a->size_low);
225 } 178 }
226 if (a->flags & SSH_FXA_HAVE_UGID) { 179 if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
227 buffer_put_int(b, a->uid); 180 buffer_put_int(b, a->uid);
228 buffer_put_int(b, a->gid); 181 buffer_put_int(b, a->gid);
229 } 182 }
230 if (a->flags & SSH_FXA_HAVE_PERM) { 183 if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
231 buffer_put_int(b, a->perm); 184 buffer_put_int(b, a->perm);
232 } 185 }
233 if (a->flags & SSH_FXA_HAVE_TIME) { 186 if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
234 buffer_put_int(b, a->atime); 187 buffer_put_int(b, a->atime);
235 buffer_put_int(b, a->mtime); 188 buffer_put_int(b, a->mtime);
236 } 189 }
@@ -242,16 +195,14 @@ stat_to_attrib(struct stat *st)
242 static Attrib a; 195 static Attrib a;
243 attrib_clear(&a); 196 attrib_clear(&a);
244 a.flags = 0; 197 a.flags = 0;
245 a.flags |= SSH_FXA_HAVE_SIZE; 198 a.flags |= SSH2_FILEXFER_ATTR_SIZE;
246 a.size = st->st_size; 199 a.size = st->st_size;
247 a.size_low = a.size; 200 a.flags |= SSH2_FILEXFER_ATTR_UIDGID;
248 a.size_high = (u_int32_t) (a.size >> 32);
249 a.flags |= SSH_FXA_HAVE_UGID;
250 a.uid = st->st_uid; 201 a.uid = st->st_uid;
251 a.gid = st->st_gid; 202 a.gid = st->st_gid;
252 a.flags |= SSH_FXA_HAVE_PERM; 203 a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
253 a.perm = st->st_mode; 204 a.perm = st->st_mode;
254 a.flags |= SSH_FXA_HAVE_TIME; 205 a.flags |= SSH2_FILEXFER_ATTR_ACMODTIME;
255 a.atime = st->st_atime; 206 a.atime = st->st_atime;
256 a.mtime = st->st_mtime; 207 a.mtime = st->st_mtime;
257 return &a; 208 return &a;
@@ -306,7 +257,8 @@ handle_new(int use, char *name, int fd, DIR *dirp)
306int 257int
307handle_is_ok(int i, int type) 258handle_is_ok(int i, int type)
308{ 259{
309 return i >= 0 && i < sizeof(handles)/sizeof(Handle) && handles[i].use == type; 260 return i >= 0 && i < sizeof(handles)/sizeof(Handle) &&
261 handles[i].use == type;
310} 262}
311 263
312int 264int
@@ -381,10 +333,11 @@ int
381get_handle(void) 333get_handle(void)
382{ 334{
383 char *handle; 335 char *handle;
384 int val; 336 int val = -1;
385 u_int hlen; 337 u_int hlen;
386 handle = get_string(&hlen); 338 handle = get_string(&hlen);
387 val = handle_from_string(handle, hlen); 339 if (hlen < 256)
340 val = handle_from_string(handle, hlen);
388 xfree(handle); 341 xfree(handle);
389 return val; 342 return val;
390} 343}
@@ -406,7 +359,7 @@ send_status(u_int32_t id, u_int32_t error)
406 Buffer msg; 359 Buffer msg;
407 TRACE("sent status id %d error %d", id, error); 360 TRACE("sent status id %d error %d", id, error);
408 buffer_init(&msg); 361 buffer_init(&msg);
409 buffer_put_char(&msg, SSH_FXP_STATUS); 362 buffer_put_char(&msg, SSH2_FXP_STATUS);
410 buffer_put_int(&msg, id); 363 buffer_put_int(&msg, id);
411 buffer_put_int(&msg, error); 364 buffer_put_int(&msg, error);
412 send_msg(&msg); 365 send_msg(&msg);
@@ -428,7 +381,7 @@ void
428send_data(u_int32_t id, char *data, int dlen) 381send_data(u_int32_t id, char *data, int dlen)
429{ 382{
430 TRACE("sent data id %d len %d", id, dlen); 383 TRACE("sent data id %d len %d", id, dlen);
431 send_data_or_handle(SSH_FXP_DATA, id, data, dlen); 384 send_data_or_handle(SSH2_FXP_DATA, id, data, dlen);
432} 385}
433 386
434void 387void
@@ -438,7 +391,7 @@ send_handle(u_int32_t id, int handle)
438 int hlen; 391 int hlen;
439 handle_to_string(handle, &string, &hlen); 392 handle_to_string(handle, &string, &hlen);
440 TRACE("sent handle id %d handle %d", id, handle); 393 TRACE("sent handle id %d handle %d", id, handle);
441 send_data_or_handle(SSH_FXP_HANDLE, id, string, hlen); 394 send_data_or_handle(SSH2_FXP_HANDLE, id, string, hlen);
442 xfree(string); 395 xfree(string);
443} 396}
444 397
@@ -448,7 +401,7 @@ send_names(u_int32_t id, int count, Stat *stats)
448 Buffer msg; 401 Buffer msg;
449 int i; 402 int i;
450 buffer_init(&msg); 403 buffer_init(&msg);
451 buffer_put_char(&msg, SSH_FXP_NAME); 404 buffer_put_char(&msg, SSH2_FXP_NAME);
452 buffer_put_int(&msg, id); 405 buffer_put_int(&msg, id);
453 buffer_put_int(&msg, count); 406 buffer_put_int(&msg, count);
454 TRACE("sent names id %d count %d", id, count); 407 TRACE("sent names id %d count %d", id, count);
@@ -467,7 +420,7 @@ send_attrib(u_int32_t id, Attrib *a)
467 Buffer msg; 420 Buffer msg;
468 TRACE("sent attrib id %d have 0x%x", id, a->flags); 421 TRACE("sent attrib id %d have 0x%x", id, a->flags);
469 buffer_init(&msg); 422 buffer_init(&msg);
470 buffer_put_char(&msg, SSH_FXP_ATTRS); 423 buffer_put_char(&msg, SSH2_FXP_ATTRS);
471 buffer_put_int(&msg, id); 424 buffer_put_int(&msg, id);
472 encode_attrib(&msg, a); 425 encode_attrib(&msg, a);
473 send_msg(&msg); 426 send_msg(&msg);
@@ -484,8 +437,8 @@ process_init(void)
484 437
485 TRACE("client version %d", version); 438 TRACE("client version %d", version);
486 buffer_init(&msg); 439 buffer_init(&msg);
487 buffer_put_char(&msg, SSH_FXP_VERSION); 440 buffer_put_char(&msg, SSH2_FXP_VERSION);
488 buffer_put_int(&msg, SSH_FILEXFER_VERSION); 441 buffer_put_int(&msg, SSH2_FILEXFER_VERSION);
489 send_msg(&msg); 442 send_msg(&msg);
490 buffer_free(&msg); 443 buffer_free(&msg);
491} 444}
@@ -496,14 +449,14 @@ process_open(void)
496 u_int32_t id, pflags; 449 u_int32_t id, pflags;
497 Attrib *a; 450 Attrib *a;
498 char *name; 451 char *name;
499 int handle, fd, flags, mode, status = SSH_FX_FAILURE; 452 int handle, fd, flags, mode, status = SSH2_FX_FAILURE;
500 453
501 id = get_int(); 454 id = get_int();
502 name = get_string(NULL); 455 name = get_string(NULL);
503 pflags = get_int(); 456 pflags = get_int(); /* portable flags */
504 a = get_attrib(); 457 a = get_attrib();
505 flags = flags_from_portable(pflags); 458 flags = flags_from_portable(pflags);
506 mode = (a->flags & SSH_FXA_HAVE_PERM) ? a->perm : 0666; 459 mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666;
507 TRACE("open id %d name %s flags %d mode 0%o", id, name, pflags, mode); 460 TRACE("open id %d name %s flags %d mode 0%o", id, name, pflags, mode);
508 fd = open(name, flags, mode); 461 fd = open(name, flags, mode);
509 if (fd < 0) { 462 if (fd < 0) {
@@ -514,10 +467,10 @@ process_open(void)
514 close(fd); 467 close(fd);
515 } else { 468 } else {
516 send_handle(id, handle); 469 send_handle(id, handle);
517 status = SSH_FX_OK; 470 status = SSH2_FX_OK;
518 } 471 }
519 } 472 }
520 if (status != SSH_FX_OK) 473 if (status != SSH2_FX_OK)
521 send_status(id, status); 474 send_status(id, status);
522 xfree(name); 475 xfree(name);
523} 476}
@@ -526,13 +479,13 @@ void
526process_close(void) 479process_close(void)
527{ 480{
528 u_int32_t id; 481 u_int32_t id;
529 int handle, ret, status = SSH_FX_FAILURE; 482 int handle, ret, status = SSH2_FX_FAILURE;
530 483
531 id = get_int(); 484 id = get_int();
532 handle = get_handle(); 485 handle = get_handle();
533 TRACE("close id %d handle %d", id, handle); 486 TRACE("close id %d handle %d", id, handle);
534 ret = handle_close(handle); 487 ret = handle_close(handle);
535 status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK; 488 status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
536 send_status(id, status); 489 send_status(id, status);
537} 490}
538 491
@@ -540,17 +493,15 @@ void
540process_read(void) 493process_read(void)
541{ 494{
542 char buf[64*1024]; 495 char buf[64*1024];
543 u_int32_t id, off_high, off_low, len; 496 u_int32_t id, len;
544 int handle, fd, ret, status = SSH_FX_FAILURE; 497 int handle, fd, ret, status = SSH2_FX_FAILURE;
545 u_int64_t off; 498 u_int64_t off;
546 499
547 id = get_int(); 500 id = get_int();
548 handle = get_handle(); 501 handle = get_handle();
549 off_high = get_int(); 502 off = get_int64();
550 off_low = get_int();
551 len = get_int(); 503 len = get_int();
552 504
553 off = (((u_int64_t) off_high) << 32) + off_low;
554 TRACE("read id %d handle %d off %lld len %d", id, handle, off, len); 505 TRACE("read id %d handle %d off %lld len %d", id, handle, off, len);
555 if (len > sizeof buf) { 506 if (len > sizeof buf) {
556 len = sizeof buf; 507 len = sizeof buf;
@@ -566,33 +517,31 @@ process_read(void)
566 if (ret < 0) { 517 if (ret < 0) {
567 status = errno_to_portable(errno); 518 status = errno_to_portable(errno);
568 } else if (ret == 0) { 519 } else if (ret == 0) {
569 status = SSH_FX_EOF; 520 status = SSH2_FX_EOF;
570 } else { 521 } else {
571 send_data(id, buf, ret); 522 send_data(id, buf, ret);
572 status = SSH_FX_OK; 523 status = SSH2_FX_OK;
573 } 524 }
574 } 525 }
575 } 526 }
576 if (status != SSH_FX_OK) 527 if (status != SSH2_FX_OK)
577 send_status(id, status); 528 send_status(id, status);
578} 529}
579 530
580void 531void
581process_write(void) 532process_write(void)
582{ 533{
583 u_int32_t id, off_high, off_low; 534 u_int32_t id;
584 u_int64_t off; 535 u_int64_t off;
585 u_int len; 536 u_int len;
586 int handle, fd, ret, status = SSH_FX_FAILURE; 537 int handle, fd, ret, status = SSH2_FX_FAILURE;
587 char *data; 538 char *data;
588 539
589 id = get_int(); 540 id = get_int();
590 handle = get_handle(); 541 handle = get_handle();
591 off_high = get_int(); 542 off = get_int64();
592 off_low = get_int();
593 data = get_string(&len); 543 data = get_string(&len);
594 544
595 off = (((u_int64_t) off_high) << 32) + off_low;
596 TRACE("write id %d handle %d off %lld len %d", id, handle, off, len); 545 TRACE("write id %d handle %d off %lld len %d", id, handle, off, len);
597 fd = handle_to_fd(handle); 546 fd = handle_to_fd(handle);
598 if (fd >= 0) { 547 if (fd >= 0) {
@@ -606,7 +555,7 @@ process_write(void)
606 error("process_write: write failed"); 555 error("process_write: write failed");
607 status = errno_to_portable(errno); 556 status = errno_to_portable(errno);
608 } else if (ret == len) { 557 } else if (ret == len) {
609 status = SSH_FX_OK; 558 status = SSH2_FX_OK;
610 } else { 559 } else {
611 log("nothing at all written"); 560 log("nothing at all written");
612 } 561 }
@@ -623,7 +572,7 @@ process_do_stat(int do_lstat)
623 struct stat st; 572 struct stat st;
624 u_int32_t id; 573 u_int32_t id;
625 char *name; 574 char *name;
626 int ret, status = SSH_FX_FAILURE; 575 int ret, status = SSH2_FX_FAILURE;
627 576
628 id = get_int(); 577 id = get_int();
629 name = get_string(NULL); 578 name = get_string(NULL);
@@ -634,9 +583,9 @@ process_do_stat(int do_lstat)
634 } else { 583 } else {
635 a = stat_to_attrib(&st); 584 a = stat_to_attrib(&st);
636 send_attrib(id, a); 585 send_attrib(id, a);
637 status = SSH_FX_OK; 586 status = SSH2_FX_OK;
638 } 587 }
639 if (status != SSH_FX_OK) 588 if (status != SSH2_FX_OK)
640 send_status(id, status); 589 send_status(id, status);
641 xfree(name); 590 xfree(name);
642} 591}
@@ -659,7 +608,7 @@ process_fstat(void)
659 Attrib *a; 608 Attrib *a;
660 struct stat st; 609 struct stat st;
661 u_int32_t id; 610 u_int32_t id;
662 int fd, ret, handle, status = SSH_FX_FAILURE; 611 int fd, ret, handle, status = SSH2_FX_FAILURE;
663 612
664 id = get_int(); 613 id = get_int();
665 handle = get_handle(); 614 handle = get_handle();
@@ -672,10 +621,10 @@ process_fstat(void)
672 } else { 621 } else {
673 a = stat_to_attrib(&st); 622 a = stat_to_attrib(&st);
674 send_attrib(id, a); 623 send_attrib(id, a);
675 status = SSH_FX_OK; 624 status = SSH2_FX_OK;
676 } 625 }
677 } 626 }
678 if (status != SSH_FX_OK) 627 if (status != SSH2_FX_OK)
679 send_status(id, status); 628 send_status(id, status);
680} 629}
681 630
@@ -697,18 +646,18 @@ process_setstat(void)
697 u_int32_t id; 646 u_int32_t id;
698 char *name; 647 char *name;
699 int ret; 648 int ret;
700 int status = SSH_FX_OK; 649 int status = SSH2_FX_OK;
701 650
702 id = get_int(); 651 id = get_int();
703 name = get_string(NULL); 652 name = get_string(NULL);
704 a = get_attrib(); 653 a = get_attrib();
705 TRACE("setstat id %d name %s", id, name); 654 TRACE("setstat id %d name %s", id, name);
706 if (a->flags & SSH_FXA_HAVE_PERM) { 655 if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
707 ret = chmod(name, a->perm & 0777); 656 ret = chmod(name, a->perm & 0777);
708 if (ret == -1) 657 if (ret == -1)
709 status = errno_to_portable(errno); 658 status = errno_to_portable(errno);
710 } 659 }
711 if (a->flags & SSH_FXA_HAVE_TIME) { 660 if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
712 ret = utimes(name, attrib_to_tv(a)); 661 ret = utimes(name, attrib_to_tv(a));
713 if (ret == -1) 662 if (ret == -1)
714 status = errno_to_portable(errno); 663 status = errno_to_portable(errno);
@@ -723,7 +672,7 @@ process_fsetstat(void)
723 Attrib *a; 672 Attrib *a;
724 u_int32_t id; 673 u_int32_t id;
725 int handle, fd, ret; 674 int handle, fd, ret;
726 int status = SSH_FX_OK; 675 int status = SSH2_FX_OK;
727 char *name; 676 char *name;
728 677
729 id = get_int(); 678 id = get_int();
@@ -733,14 +682,14 @@ process_fsetstat(void)
733 fd = handle_to_fd(handle); 682 fd = handle_to_fd(handle);
734 name = handle_to_name(handle); 683 name = handle_to_name(handle);
735 if ((fd < 0) || (name == NULL)) { 684 if ((fd < 0) || (name == NULL)) {
736 status = SSH_FX_FAILURE; 685 status = SSH2_FX_FAILURE;
737 } else { 686 } else {
738 if (a->flags & SSH_FXA_HAVE_PERM) { 687 if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
739 ret = fchmod(fd, a->perm & 0777); 688 ret = fchmod(fd, a->perm & 0777);
740 if (ret == -1) 689 if (ret == -1)
741 status = errno_to_portable(errno); 690 status = errno_to_portable(errno);
742 } 691 }
743 if (a->flags & SSH_FXA_HAVE_TIME) { 692 if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
744#ifdef HAVE_FUTIMES 693#ifdef HAVE_FUTIMES
745 ret = futimes(fd, attrib_to_tv(a)); 694 ret = futimes(fd, attrib_to_tv(a));
746#else 695#else
@@ -758,7 +707,7 @@ process_opendir(void)
758{ 707{
759 DIR *dirp = NULL; 708 DIR *dirp = NULL;
760 char *path; 709 char *path;
761 int handle, status = SSH_FX_FAILURE; 710 int handle, status = SSH2_FX_FAILURE;
762 u_int32_t id; 711 u_int32_t id;
763 712
764 id = get_int(); 713 id = get_int();
@@ -773,22 +722,28 @@ process_opendir(void)
773 closedir(dirp); 722 closedir(dirp);
774 } else { 723 } else {
775 send_handle(id, handle); 724 send_handle(id, handle);
776 status = SSH_FX_OK; 725 status = SSH2_FX_OK;
777 } 726 }
778 727
779 } 728 }
780 if (status != SSH_FX_OK) 729 if (status != SSH2_FX_OK)
781 send_status(id, status); 730 send_status(id, status);
782 xfree(path); 731 xfree(path);
783} 732}
784 733
734/*
735 * XXX, draft-ietf-secsh-filexfer-00.txt says:
736 * The recommended format for the longname field is as follows:
737 * -rwxr-xr-x 1 mjos staff 348911 Mar 25 14:29 t-filexfer
738 * 1234567890 123 12345678 12345678 12345678 123456789012
739 */
785char * 740char *
786ls_file(char *name, struct stat *st) 741ls_file(char *name, struct stat *st)
787{ 742{
788 char buf[1024]; 743 char buf[1024];
789 snprintf(buf, sizeof buf, "0%o %d %d %lld %d %s", 744 snprintf(buf, sizeof buf, "0%o %d %d %lld %d %s",
790 st->st_mode, st->st_uid, st->st_gid, (long long)st->st_size,(int) st->st_mtime, 745 st->st_mode, st->st_uid, st->st_gid, (long long)st->st_size,
791 name); 746 (int)st->st_mtime, name);
792 return xstrdup(buf); 747 return xstrdup(buf);
793} 748}
794 749
@@ -807,7 +762,7 @@ process_readdir(void)
807 dirp = handle_to_dir(handle); 762 dirp = handle_to_dir(handle);
808 path = handle_to_name(handle); 763 path = handle_to_name(handle);
809 if (dirp == NULL || path == NULL) { 764 if (dirp == NULL || path == NULL) {
810 send_status(id, SSH_FX_FAILURE); 765 send_status(id, SSH2_FX_FAILURE);
811 } else { 766 } else {
812 Attrib *a; 767 Attrib *a;
813 struct stat st; 768 struct stat st;
@@ -834,10 +789,14 @@ process_readdir(void)
834 if (count == 100) 789 if (count == 100)
835 break; 790 break;
836 } 791 }
837 send_names(id, count, stats); 792 if (count > 0) {
838 for(i = 0; i < count; i++) { 793 send_names(id, count, stats);
839 xfree(stats[i].name); 794 for(i = 0; i < count; i++) {
840 xfree(stats[i].long_name); 795 xfree(stats[i].name);
796 xfree(stats[i].long_name);
797 }
798 } else {
799 send_status(id, SSH2_FX_EOF);
841 } 800 }
842 xfree(stats); 801 xfree(stats);
843 } 802 }
@@ -848,14 +807,14 @@ process_remove(void)
848{ 807{
849 char *name; 808 char *name;
850 u_int32_t id; 809 u_int32_t id;
851 int status = SSH_FX_FAILURE; 810 int status = SSH2_FX_FAILURE;
852 int ret; 811 int ret;
853 812
854 id = get_int(); 813 id = get_int();
855 name = get_string(NULL); 814 name = get_string(NULL);
856 TRACE("remove id %d name %s", id, name); 815 TRACE("remove id %d name %s", id, name);
857 ret = unlink(name); 816 ret = unlink(name);
858 status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK; 817 status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
859 send_status(id, status); 818 send_status(id, status);
860 xfree(name); 819 xfree(name);
861} 820}
@@ -866,15 +825,16 @@ process_mkdir(void)
866 Attrib *a; 825 Attrib *a;
867 u_int32_t id; 826 u_int32_t id;
868 char *name; 827 char *name;
869 int ret, mode, status = SSH_FX_FAILURE; 828 int ret, mode, status = SSH2_FX_FAILURE;
870 829
871 id = get_int(); 830 id = get_int();
872 name = get_string(NULL); 831 name = get_string(NULL);
873 a = get_attrib(); 832 a = get_attrib();
874 mode = (a->flags & SSH_FXA_HAVE_PERM) ? a->perm & 0777 : 0777; 833 mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ?
834 a->perm & 0777 : 0777;
875 TRACE("mkdir id %d name %s mode 0%o", id, name, mode); 835 TRACE("mkdir id %d name %s mode 0%o", id, name, mode);
876 ret = mkdir(name, mode); 836 ret = mkdir(name, mode);
877 status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK; 837 status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
878 send_status(id, status); 838 send_status(id, status);
879 xfree(name); 839 xfree(name);
880} 840}
@@ -890,7 +850,7 @@ process_rmdir(void)
890 name = get_string(NULL); 850 name = get_string(NULL);
891 TRACE("rmdir id %d name %s", id, name); 851 TRACE("rmdir id %d name %s", id, name);
892 ret = rmdir(name); 852 ret = rmdir(name);
893 status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK; 853 status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
894 send_status(id, status); 854 send_status(id, status);
895 xfree(name); 855 xfree(name);
896} 856}
@@ -932,12 +892,23 @@ process_rename(void)
932 newpath = get_string(NULL); 892 newpath = get_string(NULL);
933 TRACE("rename id %d old %s new %s", id, oldpath, newpath); 893 TRACE("rename id %d old %s new %s", id, oldpath, newpath);
934 ret = rename(oldpath, newpath); 894 ret = rename(oldpath, newpath);
935 status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK; 895 status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
936 send_status(id, status); 896 send_status(id, status);
937 xfree(oldpath); 897 xfree(oldpath);
938 xfree(newpath); 898 xfree(newpath);
939} 899}
940 900
901void
902process_extended(void)
903{
904 u_int32_t id;
905 char *request;
906
907 id = get_int();
908 request = get_string(NULL);
909 send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */
910 xfree(request);
911}
941 912
942/* stolen from ssh-agent */ 913/* stolen from ssh-agent */
943 914
@@ -961,57 +932,60 @@ process(void)
961 buffer_consume(&iqueue, 4); 932 buffer_consume(&iqueue, 4);
962 type = buffer_get_char(&iqueue); 933 type = buffer_get_char(&iqueue);
963 switch (type) { 934 switch (type) {
964 case SSH_FXP_INIT: 935 case SSH2_FXP_INIT:
965 process_init(); 936 process_init();
966 break; 937 break;
967 case SSH_FXP_OPEN: 938 case SSH2_FXP_OPEN:
968 process_open(); 939 process_open();
969 break; 940 break;
970 case SSH_FXP_CLOSE: 941 case SSH2_FXP_CLOSE:
971 process_close(); 942 process_close();
972 break; 943 break;
973 case SSH_FXP_READ: 944 case SSH2_FXP_READ:
974 process_read(); 945 process_read();
975 break; 946 break;
976 case SSH_FXP_WRITE: 947 case SSH2_FXP_WRITE:
977 process_write(); 948 process_write();
978 break; 949 break;
979 case SSH_FXP_LSTAT: 950 case SSH2_FXP_LSTAT:
980 process_lstat(); 951 process_lstat();
981 break; 952 break;
982 case SSH_FXP_FSTAT: 953 case SSH2_FXP_FSTAT:
983 process_fstat(); 954 process_fstat();
984 break; 955 break;
985 case SSH_FXP_SETSTAT: 956 case SSH2_FXP_SETSTAT:
986 process_setstat(); 957 process_setstat();
987 break; 958 break;
988 case SSH_FXP_FSETSTAT: 959 case SSH2_FXP_FSETSTAT:
989 process_fsetstat(); 960 process_fsetstat();
990 break; 961 break;
991 case SSH_FXP_OPENDIR: 962 case SSH2_FXP_OPENDIR:
992 process_opendir(); 963 process_opendir();
993 break; 964 break;
994 case SSH_FXP_READDIR: 965 case SSH2_FXP_READDIR:
995 process_readdir(); 966 process_readdir();
996 break; 967 break;
997 case SSH_FXP_REMOVE: 968 case SSH2_FXP_REMOVE:
998 process_remove(); 969 process_remove();
999 break; 970 break;
1000 case SSH_FXP_MKDIR: 971 case SSH2_FXP_MKDIR:
1001 process_mkdir(); 972 process_mkdir();
1002 break; 973 break;
1003 case SSH_FXP_RMDIR: 974 case SSH2_FXP_RMDIR:
1004 process_rmdir(); 975 process_rmdir();
1005 break; 976 break;
1006 case SSH_FXP_REALPATH: 977 case SSH2_FXP_REALPATH:
1007 process_realpath(); 978 process_realpath();
1008 break; 979 break;
1009 case SSH_FXP_STAT: 980 case SSH2_FXP_STAT:
1010 process_stat(); 981 process_stat();
1011 break; 982 break;
1012 case SSH_FXP_RENAME: 983 case SSH2_FXP_RENAME:
1013 process_rename(); 984 process_rename();
1014 break; 985 break;
986 case SSH2_FXP_EXTENDED:
987 process_extended();
988 break;
1015 default: 989 default:
1016 error("Unknown message %d", type); 990 error("Unknown message %d", type);
1017 break; 991 break;
@@ -1028,6 +1002,8 @@ main(int ac, char **av)
1028 __progname = get_progname(av[0]); 1002 __progname = get_progname(av[0]);
1029 handle_init(); 1003 handle_init();
1030 1004
1005 log_init("sftp-server", SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH, 0);
1006
1031 in = dup(STDIN_FILENO); 1007 in = dup(STDIN_FILENO);
1032 out = dup(STDOUT_FILENO); 1008 out = dup(STDOUT_FILENO);
1033 1009
diff --git a/sftp.h b/sftp.h
new file mode 100644
index 000000000..4fdc2b6de
--- /dev/null
+++ b/sftp.h
@@ -0,0 +1,86 @@
1/*
2 * Copyright (c) 2001 Markus Friedl. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25/*
26 * draft-ietf-secsh-filexfer-00.txt
27 */
28
29/* version */
30#define SSH2_FILEXFER_VERSION 2
31
32/* client to server */
33#define SSH2_FXP_INIT 1
34#define SSH2_FXP_OPEN 3
35#define SSH2_FXP_CLOSE 4
36#define SSH2_FXP_READ 5
37#define SSH2_FXP_WRITE 6
38#define SSH2_FXP_LSTAT 7
39#define SSH2_FXP_FSTAT 8
40#define SSH2_FXP_SETSTAT 9
41#define SSH2_FXP_FSETSTAT 10
42#define SSH2_FXP_OPENDIR 11
43#define SSH2_FXP_READDIR 12
44#define SSH2_FXP_REMOVE 13
45#define SSH2_FXP_MKDIR 14
46#define SSH2_FXP_RMDIR 15
47#define SSH2_FXP_REALPATH 16
48#define SSH2_FXP_STAT 17
49#define SSH2_FXP_RENAME 18
50
51/* server to client */
52#define SSH2_FXP_VERSION 2
53#define SSH2_FXP_STATUS 101
54#define SSH2_FXP_HANDLE 102
55#define SSH2_FXP_DATA 103
56#define SSH2_FXP_NAME 104
57#define SSH2_FXP_ATTRS 105
58
59#define SSH2_FXP_EXTENDED 200
60#define SSH2_FXP_EXTENDED_REPLY 201
61
62/* attributes */
63#define SSH2_FILEXFER_ATTR_SIZE 0x00000001
64#define SSH2_FILEXFER_ATTR_UIDGID 0x00000002
65#define SSH2_FILEXFER_ATTR_PERMISSIONS 0x00000004
66#define SSH2_FILEXFER_ATTR_ACMODTIME 0x00000008
67#define SSH2_FILEXFER_ATTR_EXTENDED 0x80000000
68
69/* portable open modes */
70#define SSH2_FXF_READ 0x00000001
71#define SSH2_FXF_WRITE 0x00000002
72#define SSH2_FXF_APPEND 0x00000004
73#define SSH2_FXF_CREAT 0x00000008
74#define SSH2_FXF_TRUNC 0x00000010
75#define SSH2_FXF_EXCL 0x00000020
76
77/* status messages */
78#define SSH2_FX_OK 0
79#define SSH2_FX_EOF 1
80#define SSH2_FX_NO_SUCH_FILE 2
81#define SSH2_FX_PERMISSION_DENIED 3
82#define SSH2_FX_FAILURE 4
83#define SSH2_FX_BAD_MESSAGE 5
84#define SSH2_FX_NO_CONNECTION 6
85#define SSH2_FX_CONNECTION_LOST 7
86#define SSH2_FX_OP_UNSUPPORTED 8
diff --git a/sshd.c b/sshd.c
index aa7e016bf..298a1b6bd 100644
--- a/sshd.c
+++ b/sshd.c
@@ -40,7 +40,7 @@
40 */ 40 */
41 41
42#include "includes.h" 42#include "includes.h"
43RCSID("$OpenBSD: sshd.c,v 1.146 2001/01/07 11:28:07 markus Exp $"); 43RCSID("$OpenBSD: sshd.c,v 1.147 2001/01/10 19:43:20 deraadt Exp $");
44 44
45#include "xmalloc.h" 45#include "xmalloc.h"
46#include "rsa.h" 46#include "rsa.h"
@@ -266,8 +266,8 @@ grace_alarm_handler(int sig)
266 * do anything with the private key or random state before forking. 266 * do anything with the private key or random state before forking.
267 * Thus there should be no concurrency control/asynchronous execution 267 * Thus there should be no concurrency control/asynchronous execution
268 * problems. 268 * problems.
269 * XXX calling log() is not safe from races.
269 */ 270 */
270/* XXX do we really want this work to be done in a signal handler ? -m */
271void 271void
272generate_empheral_server_key(void) 272generate_empheral_server_key(void)
273{ 273{
@@ -279,6 +279,7 @@ generate_empheral_server_key(void)
279 arc4random_stir(); 279 arc4random_stir();
280 log("RSA key generation complete."); 280 log("RSA key generation complete.");
281} 281}
282
282void 283void
283key_regeneration_alarm(int sig) 284key_regeneration_alarm(int sig)
284{ 285{