sftp-server: support home-directory request
authordjm <djm@openbsd.org>
Fri, 12 Aug 2022 05:20:28 +0000 (05:20 +0000)
committerdjm <djm@openbsd.org>
Fri, 12 Aug 2022 05:20:28 +0000 (05:20 +0000)
Add support to the sftp-server for the home-directory extension defined
in draft-ietf-secsh-filexfer-extensions-00. This overlaps a bit with the
existing expand-path@openssh.com, but uses a more official protocol name,
and so is a bit more likely to be implemented by non-OpenSSH clients.

From Mike Frysinger, ok dtucker@

usr.bin/ssh/PROTOCOL
usr.bin/ssh/sftp-server.c

index 424ae5c..f27073d 100644 (file)
@@ -615,6 +615,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@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
@@ -651,4 +671,4 @@ master instance and later clients.
 OpenSSH extends the usual agent protocol. These changes are documented
 in the PROTOCOL.agent file.
 
-$OpenBSD: PROTOCOL,v 1.45 2022/04/08 05:43:39 dtucker Exp $
+$OpenBSD: PROTOCOL,v 1.46 2022/08/12 05:20:28 djm Exp $
index b8cddb4..22f3e99 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-server.c,v 1.140 2022/03/31 03:05:49 djm Exp $ */
+/* $OpenBSD: sftp-server.c,v 1.141 2022/08/12 05:20:28 djm Exp $ */
 /*
  * Copyright (c) 2000-2004 Markus Friedl.  All rights reserved.
  *
@@ -111,6 +111,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 {
@@ -157,6 +158,8 @@ static const struct sftp_handler extended_handlers[] = {
        { "expand-path", "expand-path@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 }
 };
 
@@ -714,6 +717,7 @@ process_init(void)
        compose_extension(msg, "limits@openssh.com", "1");
        compose_extension(msg, "expand-path@openssh.com", "1");
        compose_extension(msg, "copy-data", "1");
+       compose_extension(msg, "home-directory", "1");
 
        send_msg(msg);
        sshbuf_free(msg);
@@ -1651,6 +1655,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)
 {