[PATCH] sftp-server: support home-directory request

Mike Frysinger vapier at gentoo.org
Thu Mar 31 17:20:16 AEDT 2022


Add support to the sftp-server for the home-directory extension defined
in [1].  This overlaps a bit with the existing expand-path at openssh.com,
but uses a more official protocol name, and so is a bit more likely to
be implemented by clients.

I wrote this before expand-path at openssh.com existed, so posting it if
only to not be totally wasted effort.  I'd understand if people would
prefer not to implement this at all, but if there is interest, I can
see about unifying the two functions a bit.

[1] https://tools.ietf.org/html/draft-ietf-secsh-filexfer-extensions-00#section-7
---
 PROTOCOL      | 20 ++++++++++++++++++++
 sftp-server.c | 29 +++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+)

diff --git a/PROTOCOL b/PROTOCOL
index 2d50b5cb0528..7a035994489b 100644
--- a/PROTOCOL
+++ b/PROTOCOL
@@ -613,6 +613,26 @@ This request is identical to the "copy-data" request documented in:
 
 https://tools.ietf.org/html/draft-ietf-secsh-filexfer-extensions-00#section-7
 
+4.11. sftp: Extension request "home-directory"
+
+This request asks the server to expand the specified user's home directory.
+An empty username implies the current user.  This can be used by the client
+to expand ~/ type paths locally.
+
+	byte		SSH_FXP_EXTENDED
+	uint32		id
+	string		"home-directory"
+	string		username
+
+This extension is advertised in the SSH_FXP_VERSION hello with version
+"1".
+
+This provides similar information as the "expand-path at openssh.com" extension.
+
+This request is identical to the "home-directory" request documented in:
+
+https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-extensions-00#section-5
+
 5. Miscellaneous changes
 
 5.1 Public key format
diff --git a/sftp-server.c b/sftp-server.c
index 3dd19d4c81db..3aea751a9d67 100644
--- a/sftp-server.c
+++ b/sftp-server.c
@@ -121,6 +121,7 @@ static void process_extended_lsetstat(u_int32_t id);
 static void process_extended_limits(u_int32_t id);
 static void process_extended_expand(u_int32_t id);
 static void process_extended_copy_data(u_int32_t id);
+static void process_extended_home_directory(u_int32_t id);
 static void process_extended(u_int32_t id);
 
 struct sftp_handler {
@@ -167,6 +168,8 @@ static const struct sftp_handler extended_handlers[] = {
 	{ "expand-path", "expand-path at openssh.com", 0,
 	    process_extended_expand, 0 },
 	{ "copy-data", "copy-data", 0, process_extended_copy_data, 1 },
+	{ "home-directory", "home-directory", 0,
+	    process_extended_home_directory, 0 },
 	{ NULL, NULL, 0, NULL, 0 }
 };
 
@@ -724,6 +727,7 @@ process_init(void)
 	compose_extension(msg, "limits at openssh.com", "1");
 	compose_extension(msg, "expand-path at openssh.com", "1");
 	compose_extension(msg, "copy-data", "1");
+	compose_extension(msg, "home-directory", "1");
 
 	send_msg(msg);
 	sshbuf_free(msg);
@@ -1684,6 +1688,31 @@ process_extended_copy_data(u_int32_t id)
 	send_status(id, status);
 }
 
+static void
+process_extended_home_directory(u_int32_t id)
+{
+	char *username;
+	struct passwd *user_pw;
+	int r;
+	Stat s;
+
+	if ((r = sshbuf_get_cstring(iqueue, &username, NULL)) != 0)
+		fatal_fr(r, "parse");
+
+	debug3("request %u: home-directory \"%s\"", id, username);
+	if ((user_pw = getpwnam(username)) == NULL) {
+		send_status(id, errno_to_portable(errno));
+		goto out;
+	}
+
+	verbose("home-directory \"%s\"", pw->pw_dir);
+	attrib_clear(&s.attrib);
+	s.name = s.long_name = pw->pw_dir;
+	send_names(id, 1, &s);
+ out:
+	free(username);
+}
+
 static void
 process_extended(u_int32_t id)
 {
-- 
2.34.1



More information about the openssh-unix-dev mailing list