Skip to content

Commit 52037ed

Browse files
committed
upstream: Add Escape option ~I that shows information about the current
SSH connection. ok djm@, "I like/want" sthen@ florian@ OpenBSD-Commit-ID: 0483fc0188ec899077e4bc8e1e353f7dfa9f5c1d
1 parent 0fb1f3c commit 52037ed

File tree

4 files changed

+125
-5
lines changed

4 files changed

+125
-5
lines changed

clientloop.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: clientloop.c,v 1.417 2025/10/16 00:00:36 djm Exp $ */
1+
/* $OpenBSD: clientloop.c,v 1.418 2025/11/27 02:18:48 dtucker Exp $ */
22
/*
33
* Author: Tatu Ylonen <ylo@cs.hut.fi>
44
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1125,6 +1125,7 @@ static struct escape_help_text esc_txt[] = {
11251125
SUPPRESS_MUXCLIENT},
11261126
{"B", "send a BREAK to the remote system", SUPPRESS_NEVER},
11271127
{"C", "open a command line", SUPPRESS_MUXCLIENT|SUPPRESS_NOCMDLINE},
1128+
{"I", "show connection information", SUPPRESS_NEVER},
11281129
{"R", "request rekey", SUPPRESS_NEVER},
11291130
{"V/v", "decrease/increase verbosity (LogLevel)", SUPPRESS_MUXCLIENT},
11301131
{"^Z", "suspend ssh", SUPPRESS_MUXCLIENT},
@@ -1247,6 +1248,16 @@ process_escapes(struct ssh *ssh, Channel *c,
12471248
fatal_fr(r, "send packet");
12481249
continue;
12491250

1251+
case 'I':
1252+
if ((r = sshbuf_putf(berr, "%cI\r\n",
1253+
efc->escape_char)) != 0)
1254+
fatal_fr(r, "sshbuf_putf");
1255+
s = connection_info_message(ssh);
1256+
if ((r = sshbuf_put(berr, s, strlen(s))) != 0)
1257+
fatal_fr(r, "sshbuf_put");
1258+
free(s);
1259+
continue;
1260+
12501261
case 'R':
12511262
if (ssh->compat & SSH_BUG_NOREKEY)
12521263
logit("Server does not "

packet.c

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: packet.c,v 1.323 2025/09/25 06:33:19 djm Exp $ */
1+
/* $OpenBSD: packet.c,v 1.324 2025/11/27 02:18:48 dtucker Exp $ */
22
/*
33
* Author: Tatu Ylonen <ylo@cs.hut.fi>
44
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -59,6 +59,7 @@
5959
#include <poll.h>
6060
#include <signal.h>
6161
#include <time.h>
62+
#include <util.h>
6263

6364
/*
6465
* Explicitly include OpenSSL before zlib as some versions of OpenSSL have
@@ -2902,3 +2903,108 @@ sshpkt_add_padding(struct ssh *ssh, u_char pad)
29022903
ssh->state->extra_pad = pad;
29032904
return 0;
29042905
}
2906+
2907+
static char *
2908+
format_traffic_stats(struct packet_state *ps)
2909+
{
2910+
char *stats = NULL, bytes[FMT_SCALED_STRSIZE];
2911+
2912+
if (ps->bytes > LLONG_MAX || fmt_scaled(ps->bytes, bytes) != 0)
2913+
strlcpy(bytes, "OVERFLOW", sizeof(bytes));
2914+
2915+
xasprintf(&stats, "%lu pkts %llu blks %sB",
2916+
(unsigned long)ps->packets, (unsigned long long)ps->blocks, bytes);
2917+
return stats;
2918+
}
2919+
2920+
static char *
2921+
dedupe_alg_names(const char *in, const char *out)
2922+
{
2923+
char *names = NULL;
2924+
2925+
if (in == NULL)
2926+
in = "<implicit>";
2927+
if (out == NULL)
2928+
out = "<implicit>";
2929+
2930+
if (strcmp(in, out) == 0) {
2931+
names = xstrdup(in);
2932+
} else {
2933+
xasprintf(&names, "%s in, %s out", in, out);
2934+
}
2935+
return names;
2936+
}
2937+
2938+
char *
2939+
connection_info_message(struct ssh *ssh)
2940+
{
2941+
char *ret = NULL, *cipher = NULL, *mac = NULL, *comp = NULL;
2942+
char *rekey_volume = NULL, *rekey_time = NULL;
2943+
struct kex *kex;
2944+
struct session_state *state;
2945+
struct newkeys *nk_in, *nk_out;
2946+
char *stats_in = NULL, *stats_out = NULL;
2947+
u_int64_t epoch = (u_int64_t)time(NULL) - monotime();
2948+
2949+
if (ssh == NULL)
2950+
return NULL;
2951+
state = ssh->state;
2952+
kex = ssh->kex;
2953+
2954+
nk_in = ssh->state->newkeys[MODE_IN];
2955+
nk_out = ssh->state->newkeys[MODE_OUT];
2956+
stats_in = format_traffic_stats(&ssh->state->p_read);
2957+
stats_out = format_traffic_stats(&ssh->state->p_send);
2958+
2959+
cipher = dedupe_alg_names(nk_in->enc.name, nk_out->enc.name);
2960+
mac = dedupe_alg_names(nk_in->mac.name, nk_out->mac.name);
2961+
comp = dedupe_alg_names(nk_in->comp.name, nk_out->comp.name);
2962+
2963+
/* Volume based rekeying. */
2964+
if (state->rekey_limit == 0) {
2965+
xasprintf(&rekey_volume, "limit none");
2966+
} else {
2967+
char *volumes = NULL, in[32], out[32];
2968+
2969+
snprintf(in, sizeof(in), "%llu",
2970+
(unsigned long long)state->max_blocks_in);
2971+
snprintf(out, sizeof(out), "%llu",
2972+
(unsigned long long)state->max_blocks_out);
2973+
volumes = dedupe_alg_names(in, out);
2974+
xasprintf(&rekey_volume, "limit blocks %s", volumes);
2975+
free(volumes);
2976+
}
2977+
2978+
/* Time based rekeying. */
2979+
if (state->rekey_interval == 0) {
2980+
rekey_time = xstrdup("interval none");
2981+
} else {
2982+
char rekey_next[64];
2983+
2984+
format_absolute_time(epoch + state->rekey_time +
2985+
state->rekey_interval, rekey_next, sizeof(rekey_next));
2986+
xasprintf(&rekey_time, "interval %s, next %s",
2987+
fmt_timeframe(state->rekey_interval), rekey_next);
2988+
}
2989+
2990+
xasprintf(&ret, "Connection information for peer %s port %d:\r\n"
2991+
" kexalgorithm %s\r\n hostkeyalgorithm %s\r\n"
2992+
" cipher %s\r\n mac %s\r\n compression %s\r\n"
2993+
" rekey %s %s\r\n"
2994+
" traffic %s in, %s out\r\n",
2995+
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
2996+
kex->name, kex->hostkey_alg,
2997+
cipher, mac, comp,
2998+
rekey_volume, rekey_time,
2999+
stats_in, stats_out
3000+
);
3001+
free(cipher);
3002+
free(mac);
3003+
free(comp);
3004+
free(stats_in);
3005+
free(stats_out);
3006+
free(rekey_volume);
3007+
free(rekey_time);
3008+
return ret;
3009+
}
3010+

packet.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: packet.h,v 1.103 2025/09/25 06:33:19 djm Exp $ */
1+
/* $OpenBSD: packet.h,v 1.104 2025/11/27 02:18:48 dtucker Exp $ */
22

33
/*
44
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -210,6 +210,7 @@ int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM **valp);
210210
int sshpkt_get_end(struct ssh *ssh);
211211
void sshpkt_fmt_connection_id(struct ssh *ssh, char *s, size_t l);
212212
const u_char *sshpkt_ptr(struct ssh *, size_t *lenp);
213+
char *connection_info_message(struct ssh *ssh);
213214

214215
#if !defined(WITH_OPENSSL)
215216
# undef BIGNUM

ssh.1

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3434
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3535
.\"
36-
.\" $OpenBSD: ssh.1,v 1.444 2024/12/04 14:37:55 djm Exp $
37-
.Dd $Mdocdate: December 4 2024 $
36+
.\" $OpenBSD: ssh.1,v 1.445 2025/11/27 02:18:48 dtucker Exp $
37+
.Dd $Mdocdate: November 27 2025 $
3838
.Dt SSH 1
3939
.Os
4040
.Sh NAME
@@ -1156,6 +1156,8 @@ option is enabled in
11561156
Basic help is available, using the
11571157
.Fl h
11581158
option.
1159+
.It Cm ~I
1160+
Show information about the current SSH connection.
11591161
.It Cm ~R
11601162
Request rekeying of the connection
11611163
(only useful if the peer supports it).

0 commit comments

Comments
 (0)