vishalmishra434 / rpms / openssh

Forked from rpms/openssh a month ago
Clone
Dmitry Belyavskiy f23830
diff --git a/scp.c b/scp.c
Dmitry Belyavskiy f23830
--- a/scp.c	(revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99)
Dmitry Belyavskiy f23830
+++ b/scp.c	(date 1703111453316)
Dmitry Belyavskiy f23830
@@ -1372,7 +1372,7 @@
Dmitry Belyavskiy f23830
Dmitry Belyavskiy 9fd698
 	if (src_is_dir && iamrecursive) {
Dmitry Belyavskiy f23830
 		if (sftp_upload_dir(conn, src, abs_dst, pflag,
Dmitry Belyavskiy f561c6
-		    SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) {
Dmitry Belyavskiy f561c6
+		    SFTP_PROGRESS_ONLY, 0, 0, 1, 1, 1) != 0) {
Dmitry Belyavskiy f23830
 			error("failed to upload directory %s to %s", src, targ);
Dmitry Belyavskiy f23830
 			errs = 1;
Dmitry Belyavskiy f23830
 		}
Dmitry Belyavskiy f23830
diff --git a/sftp-client.c b/sftp-client.c
Dmitry Belyavskiy f23830
--- a/sftp-client.c	(revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99)
Dmitry Belyavskiy f23830
+++ b/sftp-client.c	(date 1703169614263)
Dmitry Belyavskiy f23830
@@ -1003,7 +1003,7 @@
Dmitry Belyavskiy f23830
Dmitry Belyavskiy 9fd698
 /* Implements both the realpath and expand-path operations */
Dmitry Belyavskiy 9fd698
 static char *
Dmitry Belyavskiy f23830
-sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
Dmitry Belyavskiy f23830
+sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand, int create_dir)
Dmitry Belyavskiy 9fd698
 {
Dmitry Belyavskiy 9fd698
 	struct sshbuf *msg;
Dmitry Belyavskiy 9fd698
 	u_int expected_id, count, id;
Dmitry Belyavskiy f23830
@@ -1049,11 +1049,43 @@
Dmitry Belyavskiy 03150f
 		if ((r = sshbuf_get_u32(msg, &status)) != 0 ||
Dmitry Belyavskiy 03150f
 		    (r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0)
Dmitry Belyavskiy 9fd698
 			fatal_fr(r, "parse status");
Dmitry Belyavskiy 03150f
-		error("%s %s: %s", expand ? "expand" : "realpath",
Dmitry Belyavskiy 03150f
-		    path, *errmsg == '\0' ? fx2txt(status) : errmsg);
Dmitry Belyavskiy 03150f
-		free(errmsg);
Dmitry Belyavskiy 9fd698
-		sshbuf_free(msg);
Dmitry Belyavskiy 9fd698
-		return NULL;
Dmitry Belyavskiy 9fd698
+		if ((status == SSH2_FX_NO_SUCH_FILE) && create_dir)  {
Dmitry Belyavskiy 9fd698
+			memset(&a, '\0', sizeof(a));
Dmitry Belyavskiy f23830
+			if ((r = sftp_mkdir(conn, path, &a, 0)) != 0) {
Dmitry Belyavskiy 9fd698
+				sshbuf_free(msg);
Dmitry Belyavskiy 9fd698
+				return NULL;
Dmitry Belyavskiy 9fd698
+			}
Dmitry Belyavskiy 03150f
+			debug2("Sending SSH2_FXP_REALPATH \"%s\" - create dir", path);
Dmitry Belyavskiy 9fd698
+			send_string_request(conn, id, SSH2_FXP_REALPATH,
Dmitry Belyavskiy 9fd698
+					path, strlen(path));
Dmitry Belyavskiy 9fd698
+
Dmitry Belyavskiy 9fd698
+			get_msg(conn, msg);
Dmitry Belyavskiy 9fd698
+			if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
Dmitry Belyavskiy 03150f
+			    (r = sshbuf_get_u32(msg, &id)) != 0)
Dmitry Belyavskiy 9fd698
+				fatal_fr(r, "parse");
Dmitry Belyavskiy 9fd698
+
Dmitry Belyavskiy 9fd698
+			if (id != expected_id)
Dmitry Belyavskiy 9fd698
+				fatal("ID mismatch (%u != %u)", id, expected_id);
Dmitry Belyavskiy 9fd698
+
Dmitry Belyavskiy 9fd698
+			if (type == SSH2_FXP_STATUS) {
Dmitry Belyavskiy 03150f
+				free(errmsg);
Dmitry Belyavskiy 9fd698
+
Dmitry Belyavskiy 03150f
+				if ((r = sshbuf_get_u32(msg, &status)) != 0 ||
Dmitry Belyavskiy 03150f
+				    (r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0)
Dmitry Belyavskiy 9fd698
+					fatal_fr(r, "parse status");
Dmitry Belyavskiy 03150f
+				error("%s %s: %s", expand ? "expand" : "realpath",
Dmitry Belyavskiy 03150f
+				    path, *errmsg == '\0' ? fx2txt(status) : errmsg);
Dmitry Belyavskiy 03150f
+				free(errmsg);
Dmitry Belyavskiy 9fd698
+				sshbuf_free(msg);
Dmitry Belyavskiy 9fd698
+				return NULL;
Dmitry Belyavskiy 9fd698
+			}
Dmitry Belyavskiy 9fd698
+		} else {
Dmitry Belyavskiy 03150f
+			error("%s %s: %s", expand ? "expand" : "realpath",
Dmitry Belyavskiy 03150f
+			    path, *errmsg == '\0' ? fx2txt(status) : errmsg);
Dmitry Belyavskiy 03150f
+			free(errmsg);
Dmitry Belyavskiy 9fd698
+			sshbuf_free(msg);
Dmitry Belyavskiy 9fd698
+			return NULL;
Dmitry Belyavskiy 9fd698
+		}
Dmitry Belyavskiy 9fd698
 	} else if (type != SSH2_FXP_NAME)
Dmitry Belyavskiy 9fd698
 		fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
Dmitry Belyavskiy 9fd698
 		    SSH2_FXP_NAME, type);
Dmitry Belyavskiy f23830
@@ -1078,9 +1110,9 @@
Dmitry Belyavskiy 9fd698
 }
Dmitry Belyavskiy f23830
Dmitry Belyavskiy 9fd698
 char *
Dmitry Belyavskiy f23830
-sftp_realpath(struct sftp_conn *conn, const char *path)
Dmitry Belyavskiy f23830
+sftp_realpath(struct sftp_conn *conn, const char *path, int create_dir)
Dmitry Belyavskiy 9fd698
 {
Dmitry Belyavskiy f23830
-	return sftp_realpath_expand(conn, path, 0);
Dmitry Belyavskiy f23830
+	return sftp_realpath_expand(conn, path, 0, create_dir);
Dmitry Belyavskiy 9fd698
 }
Dmitry Belyavskiy f23830
Dmitry Belyavskiy 9fd698
 int
Dmitry Belyavskiy f23830
@@ -1094,9 +1126,9 @@
Dmitry Belyavskiy 9fd698
 {
Dmitry Belyavskiy f23830
 	if (!sftp_can_expand_path(conn)) {
Dmitry Belyavskiy 9fd698
 		debug3_f("no server support, fallback to realpath");
Dmitry Belyavskiy f23830
-		return sftp_realpath_expand(conn, path, 0);
Dmitry Belyavskiy f23830
+		return sftp_realpath_expand(conn, path, 0, 0);
Dmitry Belyavskiy 9fd698
 	}
Dmitry Belyavskiy f23830
-	return sftp_realpath_expand(conn, path, 1);
Dmitry Belyavskiy f23830
+	return sftp_realpath_expand(conn, path, 1, 0);
Dmitry Belyavskiy 9fd698
 }
Dmitry Belyavskiy f23830
Dmitry Belyavskiy 9fd698
 int
Dmitry Belyavskiy f23830
@@ -2016,7 +2048,7 @@
Dmitry Belyavskiy 9fd698
 	char *src_canon;
Dmitry Belyavskiy 9fd698
 	int ret;
Dmitry Belyavskiy f23830
Dmitry Belyavskiy f23830
-	if ((src_canon = sftp_realpath(conn, src)) == NULL) {
Dmitry Belyavskiy f23830
+	if ((src_canon = sftp_realpath(conn, src, 0)) == NULL) {
Dmitry Belyavskiy f23830
 		error("download \"%s\": path canonicalization failed", src);
Dmitry Belyavskiy f23830
 		return -1;
Dmitry Belyavskiy f23830
 	}
Dmitry Belyavskiy f23830
@@ -2365,12 +2397,12 @@
Dmitry Belyavskiy 9fd698
 int
Dmitry Belyavskiy f23830
 sftp_upload_dir(struct sftp_conn *conn, const char *src, const char *dst,
Dmitry Belyavskiy 9fd698
     int preserve_flag, int print_flag, int resume, int fsync_flag,
Dmitry Belyavskiy f561c6
-    int follow_link_flag, int inplace_flag)
Dmitry Belyavskiy f561c6
+    int follow_link_flag, int inplace_flag, int create_dir)
Dmitry Belyavskiy 9fd698
 {
Dmitry Belyavskiy 9fd698
 	char *dst_canon;
Dmitry Belyavskiy 9fd698
 	int ret;
Dmitry Belyavskiy f23830
Dmitry Belyavskiy f23830
-	if ((dst_canon = sftp_realpath(conn, dst)) == NULL) {
Dmitry Belyavskiy f23830
+	if ((dst_canon = sftp_realpath(conn, dst, create_dir)) == NULL) {
Dmitry Belyavskiy f23830
 		error("upload \"%s\": path canonicalization failed", dst);
Dmitry Belyavskiy f23830
 		return -1;
Dmitry Belyavskiy f23830
 	}
Dmitry Belyavskiy f23830
@@ -2825,7 +2857,7 @@
Dmitry Belyavskiy 9fd698
 	char *from_path_canon;
Dmitry Belyavskiy 9fd698
 	int ret;
Dmitry Belyavskiy f23830
Dmitry Belyavskiy f23830
-	if ((from_path_canon = sftp_realpath(from, from_path)) == NULL) {
Dmitry Belyavskiy f23830
+	if ((from_path_canon = sftp_realpath(from, from_path, 0)) == NULL) {
Dmitry Belyavskiy f23830
 		error("crossload \"%s\": path canonicalization failed",
Dmitry Belyavskiy f23830
 		    from_path);
Dmitry Belyavskiy f23830
 		return -1;
Dmitry Belyavskiy f23830
diff --git a/sftp-client.h b/sftp-client.h
Dmitry Belyavskiy f23830
--- a/sftp-client.h	(revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99)
Dmitry Belyavskiy f23830
+++ b/sftp-client.h	(date 1703111691284)
Dmitry Belyavskiy f23830
@@ -111,7 +111,7 @@
Dmitry Belyavskiy f23830
 int sftp_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a);
Dmitry Belyavskiy f23830
Dmitry Belyavskiy 9fd698
 /* Canonicalise 'path' - caller must free result */
Dmitry Belyavskiy f23830
-char *sftp_realpath(struct sftp_conn *, const char *);
Dmitry Belyavskiy f23830
+char *sftp_realpath(struct sftp_conn *, const char *, int);
Dmitry Belyavskiy f23830
Dmitry Belyavskiy 9fd698
 /* Canonicalisation with tilde expansion (requires server extension) */
Dmitry Belyavskiy f23830
 char *sftp_expand_path(struct sftp_conn *, const char *);
Dmitry Belyavskiy f23830
@@ -163,7 +163,7 @@
Dmitry Belyavskiy 9fd698
  * times if 'pflag' is set
Dmitry Belyavskiy 9fd698
  */
Dmitry Belyavskiy f23830
 int sftp_upload_dir(struct sftp_conn *, const char *, const char *,
Dmitry Belyavskiy f561c6
-    int, int, int, int, int, int);
Dmitry Belyavskiy f561c6
+    int, int, int, int, int, int, int);
Dmitry Belyavskiy f23830
Dmitry Belyavskiy 9fd698
 /*
Dmitry Belyavskiy 9fd698
  * Download a 'from_path' from the 'from' connection and upload it to
Dmitry Belyavskiy f23830
Dmitry Belyavskiy f23830
diff --git a/sftp.c b/sftp.c
Dmitry Belyavskiy f23830
--- a/sftp.c	(revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99)
Dmitry Belyavskiy f23830
+++ b/sftp.c	(date 1703168795365)
Dmitry Belyavskiy f23830
@@ -807,7 +807,7 @@
Dmitry Belyavskiy f23830
 		    (rflag || global_rflag)) {
Dmitry Belyavskiy f23830
 			if (sftp_upload_dir(conn, g.gl_pathv[i], abs_dst,
Dmitry Belyavskiy 9fd698
 			    pflag || global_pflag, 1, resume,
Dmitry Belyavskiy f561c6
-			    fflag || global_fflag, 0, 0) == -1)
Dmitry Belyavskiy f561c6
+			    fflag || global_fflag, 0, 0, 0) == -1)
Dmitry Belyavskiy 9fd698
 				err = -1;
Dmitry Belyavskiy 9fd698
 		} else {
Dmitry Belyavskiy f23830
 			if (sftp_upload(conn, g.gl_pathv[i], abs_dst,
Dmitry Belyavskiy f23830
@@ -1642,7 +1642,7 @@
Dmitry Belyavskiy 9fd698
 		if (path1 == NULL || *path1 == '\0')
Dmitry Belyavskiy 9fd698
 			path1 = xstrdup(startdir);
Dmitry Belyavskiy f23830
 		path1 = sftp_make_absolute(path1, *pwd);
Dmitry Belyavskiy f23830
-		if ((tmp = sftp_realpath(conn, path1)) == NULL) {
Dmitry Belyavskiy f23830
+		if ((tmp = sftp_realpath(conn, path1, 0)) == NULL) {
Dmitry Belyavskiy 9fd698
 			err = 1;
Dmitry Belyavskiy 9fd698
 			break;
Dmitry Belyavskiy 9fd698
 		}
Dmitry Belyavskiy f23830
@@ -2247,7 +2247,7 @@
Dmitry Belyavskiy 9fd698
 	}
Dmitry Belyavskiy 9fd698
 #endif /* USE_LIBEDIT */
Dmitry Belyavskiy f23830
Dmitry Belyavskiy f23830
-	if ((remote_path = sftp_realpath(conn, ".")) == NULL)
Dmitry Belyavskiy f23830
+	if ((remote_path = sftp_realpath(conn, ".", 0)) == NULL)
Dmitry Belyavskiy 9fd698
 		fatal("Need cwd");
Dmitry Belyavskiy 9fd698
 	startdir = xstrdup(remote_path);
Dmitry Belyavskiy f23830