|
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 $ */ |
2 | 2 | /* |
3 | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
|
59 | 59 | #include <poll.h> |
60 | 60 | #include <signal.h> |
61 | 61 | #include <time.h> |
| 62 | +#include <util.h> |
62 | 63 |
|
63 | 64 | /* |
64 | 65 | * Explicitly include OpenSSL before zlib as some versions of OpenSSL have |
@@ -2902,3 +2903,108 @@ sshpkt_add_padding(struct ssh *ssh, u_char pad) |
2902 | 2903 | ssh->state->extra_pad = pad; |
2903 | 2904 | return 0; |
2904 | 2905 | } |
| 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 | + |
0 commit comments