diff options
Diffstat (limited to 'sftp-server.c')
-rw-r--r-- | sftp-server.c | 75 |
1 files changed, 73 insertions, 2 deletions
diff --git a/sftp-server.c b/sftp-server.c index 6575eb941..178084577 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" |
25 | RCSID("$OpenBSD: sftp-server.c,v 1.22 2001/03/03 22:07:50 deraadt Exp $"); | 25 | RCSID("$OpenBSD: sftp-server.c,v 1.23 2001/03/07 10:11:23 djm Exp $"); |
26 | 26 | ||
27 | #include "buffer.h" | 27 | #include "buffer.h" |
28 | #include "bufaux.h" | 28 | #include "bufaux.h" |
@@ -49,6 +49,9 @@ char *__progname; | |||
49 | Buffer iqueue; | 49 | Buffer iqueue; |
50 | Buffer oqueue; | 50 | Buffer oqueue; |
51 | 51 | ||
52 | /* Version of client */ | ||
53 | int version; | ||
54 | |||
52 | /* portable attibutes, etc. */ | 55 | /* portable attibutes, etc. */ |
53 | 56 | ||
54 | typedef struct Stat Stat; | 57 | typedef struct Stat Stat; |
@@ -266,12 +269,29 @@ void | |||
266 | send_status(u_int32_t id, u_int32_t error) | 269 | send_status(u_int32_t id, u_int32_t error) |
267 | { | 270 | { |
268 | Buffer msg; | 271 | Buffer msg; |
272 | const char *status_messages[] = { | ||
273 | "Success", /* SSH_FX_OK */ | ||
274 | "End of file", /* SSH_FX_EOF */ | ||
275 | "No such file", /* SSH_FX_NO_SUCH_FILE */ | ||
276 | "Permission denied", /* SSH_FX_PERMISSION_DENIED */ | ||
277 | "Failure", /* SSH_FX_FAILURE */ | ||
278 | "Bad message", /* SSH_FX_BAD_MESSAGE */ | ||
279 | "No connection", /* SSH_FX_NO_CONNECTION */ | ||
280 | "Connection lost", /* SSH_FX_CONNECTION_LOST */ | ||
281 | "Operation unsupported", /* SSH_FX_OP_UNSUPPORTED */ | ||
282 | "Unknown error" /* Others */ | ||
283 | }; | ||
269 | 284 | ||
270 | TRACE("sent status id %d error %d", id, error); | 285 | TRACE("sent status id %d error %d", id, error); |
271 | buffer_init(&msg); | 286 | buffer_init(&msg); |
272 | buffer_put_char(&msg, SSH2_FXP_STATUS); | 287 | buffer_put_char(&msg, SSH2_FXP_STATUS); |
273 | buffer_put_int(&msg, id); | 288 | buffer_put_int(&msg, id); |
274 | buffer_put_int(&msg, error); | 289 | buffer_put_int(&msg, error); |
290 | if (version >= 3) { | ||
291 | buffer_put_cstring(&msg, | ||
292 | status_messages[MIN(error,SSH2_FX_MAX)]); | ||
293 | buffer_put_cstring(&msg, ""); | ||
294 | } | ||
275 | send_msg(&msg); | 295 | send_msg(&msg); |
276 | buffer_free(&msg); | 296 | buffer_free(&msg); |
277 | } | 297 | } |
@@ -347,8 +367,8 @@ void | |||
347 | process_init(void) | 367 | process_init(void) |
348 | { | 368 | { |
349 | Buffer msg; | 369 | Buffer msg; |
350 | int version = buffer_get_int(&iqueue); | ||
351 | 370 | ||
371 | version = buffer_get_int(&iqueue); | ||
352 | TRACE("client version %d", version); | 372 | TRACE("client version %d", version); |
353 | buffer_init(&msg); | 373 | buffer_init(&msg); |
354 | buffer_put_char(&msg, SSH2_FXP_VERSION); | 374 | buffer_put_char(&msg, SSH2_FXP_VERSION); |
@@ -860,6 +880,51 @@ process_rename(void) | |||
860 | } | 880 | } |
861 | 881 | ||
862 | void | 882 | void |
883 | process_readlink(void) | ||
884 | { | ||
885 | u_int32_t id; | ||
886 | char link[MAXPATHLEN]; | ||
887 | char *path; | ||
888 | |||
889 | id = get_int(); | ||
890 | path = get_string(NULL); | ||
891 | TRACE("readlink id %d path %s", id, path); | ||
892 | if (readlink(path, link, sizeof(link) - 1) == -1) | ||
893 | send_status(id, errno_to_portable(errno)); | ||
894 | else { | ||
895 | Stat s; | ||
896 | |||
897 | link[sizeof(link) - 1] = '\0'; | ||
898 | attrib_clear(&s.attrib); | ||
899 | s.name = s.long_name = link; | ||
900 | send_names(id, 1, &s); | ||
901 | } | ||
902 | xfree(path); | ||
903 | } | ||
904 | |||
905 | void | ||
906 | process_symlink(void) | ||
907 | { | ||
908 | u_int32_t id; | ||
909 | struct stat st; | ||
910 | char *oldpath, *newpath; | ||
911 | int ret, status = SSH2_FX_FAILURE; | ||
912 | |||
913 | id = get_int(); | ||
914 | oldpath = get_string(NULL); | ||
915 | newpath = get_string(NULL); | ||
916 | TRACE("symlink id %d old %s new %s", id, oldpath, newpath); | ||
917 | /* fail if 'newpath' exists */ | ||
918 | if (stat(newpath, &st) == -1) { | ||
919 | ret = symlink(oldpath, newpath); | ||
920 | status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; | ||
921 | } | ||
922 | send_status(id, status); | ||
923 | xfree(oldpath); | ||
924 | xfree(newpath); | ||
925 | } | ||
926 | |||
927 | void | ||
863 | process_extended(void) | 928 | process_extended(void) |
864 | { | 929 | { |
865 | u_int32_t id; | 930 | u_int32_t id; |
@@ -944,6 +1009,12 @@ process(void) | |||
944 | case SSH2_FXP_RENAME: | 1009 | case SSH2_FXP_RENAME: |
945 | process_rename(); | 1010 | process_rename(); |
946 | break; | 1011 | break; |
1012 | case SSH2_FXP_READLINK: | ||
1013 | process_readlink(); | ||
1014 | break; | ||
1015 | case SSH2_FXP_SYMLINK: | ||
1016 | process_symlink(); | ||
1017 | break; | ||
947 | case SSH2_FXP_EXTENDED: | 1018 | case SSH2_FXP_EXTENDED: |
948 | process_extended(); | 1019 | process_extended(); |
949 | break; | 1020 | break; |