forked from rpms/openssh
		
	import openssh-8.7p1-7.el9
This commit is contained in:
		
							parent
							
								
									04aa69c7cb
								
							
						
					
					
						commit
						83dfc89e61
					
				
							
								
								
									
										173
									
								
								SOURCES/openssh-8.7p1-recursive-scp.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								SOURCES/openssh-8.7p1-recursive-scp.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,173 @@ | ||||
| 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,37 @@ 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)  {
 | ||||
| +			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); | ||||
							
								
								
									
										167
									
								
								SOURCES/openssh-8.7p1-sftpscp-dir-create.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								SOURCES/openssh-8.7p1-sftpscp-dir-create.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,167 @@ | ||||
| diff -up openssh-8.7p1/scp.c.sftpdirs openssh-8.7p1/scp.c
 | ||||
| --- openssh-8.7p1/scp.c.sftpdirs	2022-02-02 14:11:12.553447509 +0100
 | ||||
| +++ openssh-8.7p1/scp.c	2022-02-02 14:12:56.081316414 +0100
 | ||||
| @@ -130,6 +130,7 @@
 | ||||
|  #include "misc.h" | ||||
|  #include "progressmeter.h" | ||||
|  #include "utf8.h" | ||||
| +#include "sftp.h"
 | ||||
|   | ||||
|  #include "sftp-common.h" | ||||
|  #include "sftp-client.h" | ||||
| @@ -660,7 +661,7 @@ main(int argc, char **argv)
 | ||||
|  	 * Finally check the exit status of the ssh process, if one was forked | ||||
|  	 * and no error has occurred yet | ||||
|  	 */ | ||||
| -	if (do_cmd_pid != -1 && errs == 0) {
 | ||||
| +	if (do_cmd_pid != -1 && (mode == MODE_SFTP || errs == 0)) {
 | ||||
|  		if (remin != -1) | ||||
|  		    (void) close(remin); | ||||
|  		if (remout != -1) | ||||
| @@ -1264,13 +1265,18 @@ tolocal(int argc, char **argv, enum scp_
 | ||||
|  static char * | ||||
|  prepare_remote_path(struct sftp_conn *conn, const char *path) | ||||
|  { | ||||
| +	size_t nslash;
 | ||||
| +
 | ||||
|  	/* Handle ~ prefixed paths */ | ||||
| -	if (*path != '~')
 | ||||
| -		return xstrdup(path);
 | ||||
|  	if (*path == '\0' || strcmp(path, "~") == 0) | ||||
|  		return xstrdup("."); | ||||
| -	if (strncmp(path, "~/", 2) == 0)
 | ||||
| -		return xstrdup(path + 2);
 | ||||
| +	if (*path != '~')
 | ||||
| +		return xstrdup(path);
 | ||||
| +	if (strncmp(path, "~/", 2) == 0) {
 | ||||
| +		if ((nslash = strspn(path + 2, "/")) == strlen(path + 2))
 | ||||
| +			return xstrdup(".");
 | ||||
| +		return xstrdup(path + 2 + nslash);
 | ||||
| +	}
 | ||||
|  	if (can_expand_path(conn)) | ||||
|  		return do_expand_path(conn, path); | ||||
|  	/* No protocol extension */ | ||||
| @@ -1282,10 +1288,16 @@ void
 | ||||
|  source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn) | ||||
|  { | ||||
|  	char *target = NULL, *filename = NULL, *abs_dst = NULL; | ||||
| -	int target_is_dir;
 | ||||
| -
 | ||||
| +	int src_is_dir, target_is_dir;
 | ||||
| +	Attrib a;
 | ||||
| +	struct stat st;
 | ||||
| +
 | ||||
| +	memset(&a, '\0', sizeof(a));
 | ||||
| +	if (stat(src, &st) != 0)
 | ||||
| +		fatal("stat local \"%s\": %s", src, strerror(errno));
 | ||||
| +	src_is_dir = S_ISDIR(st.st_mode);
 | ||||
|  	if ((filename = basename(src)) == NULL) | ||||
| -		fatal("basename %s: %s", src, strerror(errno));
 | ||||
| +		fatal("basename \"%s\": %s", src, strerror(errno));
 | ||||
|   | ||||
|  	/* | ||||
|  	 * No need to glob here - the local shell already took care of | ||||
| @@ -1295,8 +1307,12 @@ source_sftp(int argc, char *src, char *t
 | ||||
|  		cleanup_exit(255); | ||||
|  	target_is_dir = remote_is_dir(conn, target); | ||||
|  	if (targetshouldbedirectory && !target_is_dir) { | ||||
| -		fatal("Target is not a directory, but more files selected "
 | ||||
| -		    "for upload");
 | ||||
| +		debug("target directory \"%s\" does not exist", target);
 | ||||
| +		a.flags = SSH2_FILEXFER_ATTR_PERMISSIONS;
 | ||||
| +		a.perm = st.st_mode | 0700; /* ensure writable */
 | ||||
| +		if (do_mkdir(conn, target, &a, 1) != 0)
 | ||||
| +			cleanup_exit(255); /* error already logged */
 | ||||
| +		target_is_dir = 1;
 | ||||
|  	} | ||||
|  	if (target_is_dir) | ||||
|  		abs_dst = path_append(target, filename); | ||||
| @@ -1306,14 +1322,17 @@ source_sftp(int argc, char *src, char *t
 | ||||
|  	} | ||||
|  	debug3_f("copying local %s to remote %s", src, abs_dst); | ||||
|   | ||||
| -	if (local_is_dir(src) && iamrecursive) {
 | ||||
| +	if (src_is_dir && iamrecursive) {
 | ||||
|  		if (upload_dir(conn, src, abs_dst, pflag, | ||||
|  		    SFTP_PROGRESS_ONLY, 0, 0, 1) != 0) { | ||||
| -			fatal("failed to upload directory %s to %s",
 | ||||
| +			error("failed to upload directory %s to %s",
 | ||||
|  				src, abs_dst); | ||||
| +			errs = 1;
 | ||||
|  		} | ||||
| -	} else if (do_upload(conn, src, abs_dst, pflag, 0, 0) != 0)
 | ||||
| -		fatal("failed to upload file %s to %s", src, abs_dst);
 | ||||
| +	} else if (do_upload(conn, src, abs_dst, pflag, 0, 0) != 0) {
 | ||||
| +		error("failed to upload file %s to %s", src, abs_dst);
 | ||||
| +		errs = 1;
 | ||||
| +	}
 | ||||
|   | ||||
|  	free(abs_dst); | ||||
|  	free(target); | ||||
| @@ -1487,14 +1506,15 @@ sink_sftp(int argc, char *dst, const cha
 | ||||
|  	char *abs_dst = NULL; | ||||
|  	glob_t g; | ||||
|  	char *filename, *tmp = NULL; | ||||
| -	int i, r, err = 0;
 | ||||
| +	int i, r, err = 0, dst_is_dir;
 | ||||
| +	struct stat st;
 | ||||
|   | ||||
|  	memset(&g, 0, sizeof(g)); | ||||
| +
 | ||||
|  	/* | ||||
|  	 * Here, we need remote glob as SFTP can not depend on remote shell | ||||
|  	 * expansions | ||||
|  	 */ | ||||
| -
 | ||||
|  	if ((abs_src = prepare_remote_path(conn, src)) == NULL) { | ||||
|  		err = -1; | ||||
|  		goto out; | ||||
| @@ -1510,11 +1530,24 @@ sink_sftp(int argc, char *dst, const cha
 | ||||
|  		goto out; | ||||
|  	} | ||||
|   | ||||
| -	if (g.gl_matchc > 1 && !local_is_dir(dst)) {
 | ||||
| -		error("Multiple files match pattern, but destination "
 | ||||
| -		    "\"%s\" is not a directory", dst);
 | ||||
| -		err = -1;
 | ||||
| -		goto out;
 | ||||
| +	if ((r = stat(dst, &st)) != 0)
 | ||||
| +		debug2_f("stat local \"%s\": %s", dst, strerror(errno));
 | ||||
| +	dst_is_dir = r == 0 && S_ISDIR(st.st_mode);
 | ||||
| +
 | ||||
| +	if (g.gl_matchc > 1 && !dst_is_dir) {
 | ||||
| +		if (r == 0) {
 | ||||
| +			error("Multiple files match pattern, but destination "
 | ||||
| +			    "\"%s\" is not a directory", dst);
 | ||||
| +			err = -1;
 | ||||
| +			goto out;
 | ||||
| +		}
 | ||||
| +		debug2_f("creating destination \"%s\"", dst);
 | ||||
| +		if (mkdir(dst, 0777) != 0) {
 | ||||
| +			error("local mkdir \"%s\": %s", dst, strerror(errno));
 | ||||
| +			err = -1;
 | ||||
| +			goto out;
 | ||||
| +		}
 | ||||
| +		dst_is_dir = 1;
 | ||||
|  	} | ||||
|   | ||||
|  	for (i = 0; g.gl_pathv[i] && !interrupted; i++) { | ||||
| @@ -1525,7 +1558,7 @@ sink_sftp(int argc, char *dst, const cha
 | ||||
|  			goto out; | ||||
|  		} | ||||
|   | ||||
| -		if (local_is_dir(dst))
 | ||||
| +		if (dst_is_dir)
 | ||||
|  			abs_dst = path_append(dst, filename); | ||||
|  		else | ||||
|  			abs_dst = xstrdup(dst); | ||||
| @@ -1551,7 +1584,8 @@ out:
 | ||||
|  	free(tmp); | ||||
|  	globfree(&g); | ||||
|  	if (err == -1) { | ||||
| -		fatal("Failed to download file '%s'", src);
 | ||||
| +		error("Failed to download '%s'", src);
 | ||||
| +		errs = 1;
 | ||||
|  	} | ||||
|  } | ||||
|   | ||||
| @ -51,7 +51,7 @@ | ||||
| 
 | ||||
| # Do not forget to bump pam_ssh_agent_auth release if you rewind the main package release to 1 | ||||
| %global openssh_ver 8.7p1 | ||||
| %global openssh_rel 6 | ||||
| %global openssh_rel 7 | ||||
| %global pam_ssh_agent_ver 0.10.4 | ||||
| %global pam_ssh_agent_rel 4 | ||||
| 
 | ||||
| @ -201,6 +201,17 @@ Patch977: openssh-8.7p1-scp-kill-switch.patch | ||||
| Patch978: openssh-8.7p1-upstream-cve-2021-41617.patch | ||||
| # fix for `ssh-keygen -Y find-principals -f /dev/null -s /dev/null` (#2024902) | ||||
| Patch979: openssh-8.7p1-find-principals-fix.patch | ||||
| # Create non-existent directories when scp works in sftp mode and some more minor fixes | ||||
| # upstream commits: | ||||
| # ba61123eef9c6356d438c90c1199a57a0d7bcb0a | ||||
| # 63670d4e9030bcee490d5a9cce561373ac5b3b23 | ||||
| # ac7c9ec894ed0825d04ef69c55babb49bab1d32e | ||||
| Patch980: openssh-8.7p1-sftpscp-dir-create.patch | ||||
| # Workaround for lack of sftp_realpath in older versions of RHEL | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=2038854 | ||||
| # https://github.com/openssh/openssh-portable/pull/299 | ||||
| # downstream only | ||||
| Patch981: openssh-8.7p1-recursive-scp.patch | ||||
| 
 | ||||
| Patch1000: openssh-8.7p1-minimize-sha1-use.patch | ||||
| 
 | ||||
| @ -382,6 +393,8 @@ popd | ||||
| %patch977 -p1 -b .kill-scp | ||||
| %patch978 -p1 -b .cve-2021-41617 | ||||
| %patch979 -p1 -b .find-principals | ||||
| %patch980 -p1 -b .sftpdirs | ||||
| %patch981 -p1 -b .scp-sftpdirs | ||||
| 
 | ||||
| %patch200 -p1 -b .audit | ||||
| %patch201 -p1 -b .audit-race | ||||
| @ -668,6 +681,12 @@ test -f %{sysconfig_anaconda} && \ | ||||
| %endif | ||||
| 
 | ||||
| %changelog | ||||
| * Mon Feb 07 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.7p1-7 | ||||
| - Switch to SFTP protocol in scp utility by default - upstream fixes | ||||
|   Related: rhbz#2001002 | ||||
| - Workaround for RHEL 8 incompatibility in scp utility in SFTP mode | ||||
|   Related: rhbz#2038854 | ||||
| 
 | ||||
| * Tue Dec 21 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.7p1-6 | ||||
| - Fix SSH connection to localhost not possible in FIPS | ||||
|   Related: rhbz#2031868 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user