Add channel_set_xtype()
authordjm <djm@openbsd.org>
Fri, 6 Jan 2023 02:42:34 +0000 (02:42 +0000)
committerdjm <djm@openbsd.org>
Fri, 6 Jan 2023 02:42:34 +0000 (02:42 +0000)
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
usr.bin/ssh/channels.h
usr.bin/ssh/session.c

index beeeeb4..1fff7bf 100644 (file)
@@ -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 <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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),
index c9de0ae..c51c104 100644 (file)
@@ -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 <ylo@cs.hut.fi>
@@ -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);
index 95f19d4..8d9bd02 100644 (file)
@@ -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 <ylo@cs.hut.fi>, 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;