upstream: sftp-server: support home-directory request

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@

OpenBSD-Commit-ID: bfc580d05cc0c817831ae7ecbac4a481c23566ab
This commit is contained in:
djm@openbsd.org 2022-08-12 05:20:28 +00:00 committed by Damien Miller
parent 5e820bf79c
commit 730a806094
2 changed files with 51 additions and 2 deletions

View 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 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. Miscellaneous changes
5.1 Public key format 5.1 Public key format
@ -651,4 +671,4 @@ master instance and later clients.
OpenSSH extends the usual agent protocol. These changes are documented OpenSSH extends the usual agent protocol. These changes are documented
in the PROTOCOL.agent file. 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 $

View 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. * Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
* *
@ -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_limits(u_int32_t id);
static void process_extended_expand(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_copy_data(u_int32_t id);
static void process_extended_home_directory(u_int32_t id);
static void process_extended(u_int32_t id); static void process_extended(u_int32_t id);
struct sftp_handler { struct sftp_handler {
@ -167,6 +168,8 @@ static const struct sftp_handler extended_handlers[] = {
{ "expand-path", "expand-path@openssh.com", 0, { "expand-path", "expand-path@openssh.com", 0,
process_extended_expand, 0 }, process_extended_expand, 0 },
{ "copy-data", "copy-data", 0, process_extended_copy_data, 1 }, { "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 } { NULL, NULL, 0, NULL, 0 }
}; };
@ -724,6 +727,7 @@ process_init(void)
compose_extension(msg, "limits@openssh.com", "1"); compose_extension(msg, "limits@openssh.com", "1");
compose_extension(msg, "expand-path@openssh.com", "1"); compose_extension(msg, "expand-path@openssh.com", "1");
compose_extension(msg, "copy-data", "1"); compose_extension(msg, "copy-data", "1");
compose_extension(msg, "home-directory", "1");
send_msg(msg); send_msg(msg);
sshbuf_free(msg); sshbuf_free(msg);
@ -1684,6 +1688,31 @@ process_extended_copy_data(u_int32_t id)
send_status(id, status); 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 static void
process_extended(u_int32_t id) process_extended(u_int32_t id)
{ {