From e425622f263d3336f7ab701c8e33efa3b8fb87c1 Mon Sep 17 00:00:00 2001 From: djm Date: Fri, 6 Jan 2023 02:42:34 +0000 Subject: [PATCH] Add channel_set_xtype() This sets an "extended" channel type after channel creation (e.g. "session:subsystem:sftp") that will be used for setting channel inactivity timeouts. ok markus dtucker --- usr.bin/ssh/channels.c | 26 +++++++++++++++++++++++--- usr.bin/ssh/channels.h | 6 ++++-- usr.bin/ssh/session.c | 13 +++++++++++-- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/usr.bin/ssh/channels.c b/usr.bin/ssh/channels.c index beeeeb4c658..1fff7bf3ef4 100644 --- a/usr.bin/ssh/channels.c +++ b/usr.bin/ssh/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.424 2023/01/06 02:41:49 djm Exp $ */ +/* $OpenBSD: channels.c,v 1.425 2023/01/06 02:42:34 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -288,6 +288,24 @@ channel_lookup(struct ssh *ssh, int id) return NULL; } +/* + * Sets "extended type" of a channel; used by session layer to add additional + * information about channel types (e.g. shell, login, subsystem) that can then + * be used to select timeouts. + */ +void +channel_set_xtype(struct ssh *ssh, int id, const char *xctype) +{ + Channel *c; + + if ((c = channel_by_id(ssh, id)) == NULL) + fatal_f("missing channel %d", id); + if (c->xctype != NULL) + free(c->xctype); + c->xctype = xstrdup(xctype); + debug2_f("labeled channel %d as %s", id, xctype); +} + /* * Register filedescriptors for a channel, used when allocating a channel or * when the channel consumer/producer is ready, e.g. shell exec'd @@ -644,6 +662,8 @@ channel_free(struct ssh *ssh, Channel *c) c->path = NULL; free(c->listening_addr); c->listening_addr = NULL; + free(c->xctype); + c->xctype = NULL; while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) { if (cc->abandon_cb != NULL) cc->abandon_cb(ssh, c, cc->ctx); @@ -859,9 +879,9 @@ channel_format_status(const Channel *c) { char *ret = NULL; - xasprintf(&ret, "t%d %s%u i%u/%zu o%u/%zu e[%s]/%zu " + xasprintf(&ret, "t%d [%s] %s%u i%u/%zu o%u/%zu e[%s]/%zu " "fd %d/%d/%d sock %d cc %d io 0x%02x/0x%02x", - c->type, + c->type, c->xctype != NULL ? c->xctype : c->ctype, c->have_remote_id ? "r" : "nr", c->remote_id, c->istate, sshbuf_len(c->input), c->ostate, sshbuf_len(c->output), diff --git a/usr.bin/ssh/channels.h b/usr.bin/ssh/channels.h index c9de0aed2d4..c51c104af6a 100644 --- a/usr.bin/ssh/channels.h +++ b/usr.bin/ssh/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.145 2023/01/06 02:39:59 djm Exp $ */ +/* $OpenBSD: channels.h,v 1.146 2023/01/06 02:42:34 djm Exp $ */ /* * Author: Tatu Ylonen @@ -172,7 +172,8 @@ struct Channel { int extended_usage; int single_connection; - char *ctype; /* type */ + char *ctype; /* const type - NB. not freed on channel_free */ + char *xctype; /* extended type */ /* callback */ channel_open_fn *open_confirm; @@ -279,6 +280,7 @@ void channel_free(struct ssh *, Channel *); void channel_free_all(struct ssh *); void channel_stop_listening(struct ssh *); void channel_force_close(struct ssh *, Channel *, int); +void channel_set_xtype(struct ssh *, int, const char *); void channel_send_open(struct ssh *, int); void channel_request_start(struct ssh *, int, char *, int); diff --git a/usr.bin/ssh/session.c b/usr.bin/ssh/session.c index 95f19d44c85..8d9bd02d45c 100644 --- a/usr.bin/ssh/session.c +++ b/usr.bin/ssh/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.332 2023/01/06 02:41:49 djm Exp $ */ +/* $OpenBSD: session.c,v 1.333 2023/01/06 02:42:34 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -1637,7 +1637,7 @@ session_subsystem_req(struct ssh *ssh, Session *s) { struct stat st; int r, success = 0; - char *prog, *cmd; + char *prog, *cmd, *type; u_int i; if ((r = sshpkt_get_cstring(ssh, &s->subsys, NULL)) != 0 || @@ -1660,6 +1660,10 @@ session_subsystem_req(struct ssh *ssh, Session *s) s->is_subsystem = SUBSYSTEM_EXT; debug("subsystem: exec() %s", cmd); } + xasprintf(&type, "session:subsystem:%s", + options.subsystem_name[i]); + channel_set_xtype(ssh, s->chanid, type); + free(type); success = do_exec(ssh, s, cmd) == 0; break; } @@ -1715,6 +1719,9 @@ session_shell_req(struct ssh *ssh, Session *s) if ((r = sshpkt_get_end(ssh)) != 0) sshpkt_fatal(ssh, r, "%s: parse packet", __func__); + + channel_set_xtype(ssh, s->chanid, "session:shell"); + return do_exec(ssh, s, NULL) == 0; } @@ -1729,6 +1736,8 @@ session_exec_req(struct ssh *ssh, Session *s) (r = sshpkt_get_end(ssh)) != 0) sshpkt_fatal(ssh, r, "%s: parse packet", __func__); + channel_set_xtype(ssh, s->chanid, "session:command"); + success = do_exec(ssh, s, command) == 0; free(command); return success; -- 2.20.1