You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
6.0 KiB
174 lines
6.0 KiB
diff -up openssh-8.7p1/scp.c.scp-sftpdirs openssh-8.7p1/scp.c |
|
--- openssh-8.7p1/scp.c.scp-sftpdirs 2022-02-07 12:31:07.407740407 +0100 |
|
+++ openssh-8.7p1/scp.c 2022-02-07 12:31:07.409740424 +0100 |
|
@@ -1324,7 +1324,7 @@ source_sftp(int argc, char *src, char *t |
|
|
|
if (src_is_dir && iamrecursive) { |
|
if (upload_dir(conn, src, abs_dst, pflag, |
|
- SFTP_PROGRESS_ONLY, 0, 0, 1) != 0) { |
|
+ SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) { |
|
error("failed to upload directory %s to %s", |
|
src, abs_dst); |
|
errs = 1; |
|
diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c |
|
--- openssh-8.7p1/sftp-client.c.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200 |
|
+++ openssh-8.7p1/sftp-client.c 2022-02-07 12:47:59.117516131 +0100 |
|
@@ -971,7 +971,7 @@ do_fsetstat(struct sftp_conn *conn, cons |
|
|
|
/* Implements both the realpath and expand-path operations */ |
|
static char * |
|
-do_realpath_expand(struct sftp_conn *conn, const char *path, int expand) |
|
+do_realpath_expand(struct sftp_conn *conn, const char *path, int expand, int create_dir) |
|
{ |
|
struct sshbuf *msg; |
|
u_int expected_id, count, id; |
|
@@ -1012,9 +1012,38 @@ do_realpath_expand(struct sftp_conn *con |
|
|
|
if ((r = sshbuf_get_u32(msg, &status)) != 0) |
|
fatal_fr(r, "parse status"); |
|
- error("Couldn't canonicalize: %s", fx2txt(status)); |
|
- sshbuf_free(msg); |
|
- return NULL; |
|
+ if ((status == SSH2_FX_NO_SUCH_FILE) && create_dir) { |
|
+ memset(&a, '\0', sizeof(a)); |
|
+ if ((r = do_mkdir(conn, path, &a, 0)) != 0) { |
|
+ sshbuf_free(msg); |
|
+ return NULL; |
|
+ } |
|
+ |
|
+ send_string_request(conn, id, SSH2_FXP_REALPATH, |
|
+ path, strlen(path)); |
|
+ |
|
+ get_msg(conn, msg); |
|
+ if ((r = sshbuf_get_u8(msg, &type)) != 0 || |
|
+ (r = sshbuf_get_u32(msg, &id)) != 0) |
|
+ fatal_fr(r, "parse"); |
|
+ |
|
+ if (id != expected_id) |
|
+ fatal("ID mismatch (%u != %u)", id, expected_id); |
|
+ |
|
+ if (type == SSH2_FXP_STATUS) { |
|
+ u_int status; |
|
+ |
|
+ if ((r = sshbuf_get_u32(msg, &status)) != 0) |
|
+ fatal_fr(r, "parse status"); |
|
+ error("Couldn't canonicalize: %s", fx2txt(status)); |
|
+ sshbuf_free(msg); |
|
+ return NULL; |
|
+ } |
|
+ } else { |
|
+ error("Couldn't canonicalize: %s", fx2txt(status)); |
|
+ sshbuf_free(msg); |
|
+ return NULL; |
|
+ } |
|
} else if (type != SSH2_FXP_NAME) |
|
fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", |
|
SSH2_FXP_NAME, type); |
|
@@ -1039,9 +1067,9 @@ do_realpath_expand(struct sftp_conn *con |
|
} |
|
|
|
char * |
|
-do_realpath(struct sftp_conn *conn, const char *path) |
|
+do_realpath(struct sftp_conn *conn, const char *path, int create_dir) |
|
{ |
|
- return do_realpath_expand(conn, path, 0); |
|
+ return do_realpath_expand(conn, path, 0, create_dir); |
|
} |
|
|
|
int |
|
@@ -1055,9 +1083,9 @@ do_expand_path(struct sftp_conn *conn, c |
|
{ |
|
if (!can_expand_path(conn)) { |
|
debug3_f("no server support, fallback to realpath"); |
|
- return do_realpath_expand(conn, path, 0); |
|
+ return do_realpath_expand(conn, path, 0, 0); |
|
} |
|
- return do_realpath_expand(conn, path, 1); |
|
+ return do_realpath_expand(conn, path, 1, 0); |
|
} |
|
|
|
int |
|
@@ -1807,7 +1835,7 @@ download_dir(struct sftp_conn *conn, con |
|
char *src_canon; |
|
int ret; |
|
|
|
- if ((src_canon = do_realpath(conn, src)) == NULL) { |
|
+ if ((src_canon = do_realpath(conn, src, 0)) == NULL) { |
|
error("Unable to canonicalize path \"%s\"", src); |
|
return -1; |
|
} |
|
@@ -2115,12 +2143,12 @@ upload_dir_internal(struct sftp_conn *co |
|
int |
|
upload_dir(struct sftp_conn *conn, const char *src, const char *dst, |
|
int preserve_flag, int print_flag, int resume, int fsync_flag, |
|
- int follow_link_flag) |
|
+ int follow_link_flag, int create_dir) |
|
{ |
|
char *dst_canon; |
|
int ret; |
|
|
|
- if ((dst_canon = do_realpath(conn, dst)) == NULL) { |
|
+ if ((dst_canon = do_realpath(conn, dst, create_dir)) == NULL) { |
|
error("Unable to canonicalize path \"%s\"", dst); |
|
return -1; |
|
} |
|
@@ -2557,7 +2585,7 @@ crossload_dir(struct sftp_conn *from, st |
|
char *from_path_canon; |
|
int ret; |
|
|
|
- if ((from_path_canon = do_realpath(from, from_path)) == NULL) { |
|
+ if ((from_path_canon = do_realpath(from, from_path, 0)) == NULL) { |
|
error("Unable to canonicalize path \"%s\"", from_path); |
|
return -1; |
|
} |
|
diff -up openssh-8.7p1/sftp-client.h.scp-sftpdirs openssh-8.7p1/sftp-client.h |
|
--- openssh-8.7p1/sftp-client.h.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200 |
|
+++ openssh-8.7p1/sftp-client.h 2022-02-07 12:31:07.410740433 +0100 |
|
@@ -111,7 +111,7 @@ int do_fsetstat(struct sftp_conn *, cons |
|
int do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a); |
|
|
|
/* Canonicalise 'path' - caller must free result */ |
|
-char *do_realpath(struct sftp_conn *, const char *); |
|
+char *do_realpath(struct sftp_conn *, const char *, int); |
|
|
|
/* Canonicalisation with tilde expansion (requires server extension) */ |
|
char *do_expand_path(struct sftp_conn *, const char *); |
|
@@ -159,7 +159,7 @@ int do_upload(struct sftp_conn *, const |
|
* times if 'pflag' is set |
|
*/ |
|
int upload_dir(struct sftp_conn *, const char *, const char *, int, int, int, |
|
- int, int); |
|
+ int, int, int); |
|
|
|
/* |
|
* Download a 'from_path' from the 'from' connection and upload it to |
|
diff -up openssh-8.7p1/sftp.c.scp-sftpdirs openssh-8.7p1/sftp.c |
|
--- openssh-8.7p1/sftp.c.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200 |
|
+++ openssh-8.7p1/sftp.c 2022-02-07 12:31:07.411740442 +0100 |
|
@@ -760,7 +760,7 @@ process_put(struct sftp_conn *conn, cons |
|
if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { |
|
if (upload_dir(conn, g.gl_pathv[i], abs_dst, |
|
pflag || global_pflag, 1, resume, |
|
- fflag || global_fflag, 0) == -1) |
|
+ fflag || global_fflag, 0, 0) == -1) |
|
err = -1; |
|
} else { |
|
if (do_upload(conn, g.gl_pathv[i], abs_dst, |
|
@@ -1577,7 +1577,7 @@ parse_dispatch_command(struct sftp_conn |
|
if (path1 == NULL || *path1 == '\0') |
|
path1 = xstrdup(startdir); |
|
path1 = make_absolute(path1, *pwd); |
|
- if ((tmp = do_realpath(conn, path1)) == NULL) { |
|
+ if ((tmp = do_realpath(conn, path1, 0)) == NULL) { |
|
err = 1; |
|
break; |
|
} |
|
@@ -2160,7 +2160,7 @@ interactive_loop(struct sftp_conn *conn, |
|
} |
|
#endif /* USE_LIBEDIT */ |
|
|
|
- remote_path = do_realpath(conn, "."); |
|
+ remote_path = do_realpath(conn, ".", 0); |
|
if (remote_path == NULL) |
|
fatal("Need cwd"); |
|
startdir = xstrdup(remote_path);
|
|
|