From 66f25b64406266b4e757f88274eb6dbf59da222e Mon Sep 17 00:00:00 2001 From: Eygene Ryabinkin Date: Sat, 19 May 2012 15:28:36 +0400 Subject: [PATCH] OpenSSH: allow VersionAddendum to be used again Prior to this, setting VersionAddendum will be a no-op: one will always have BASE_VERSION + " " + VERSION_HPN for VersionAddendum set in the config and a bare BASE_VERSION + VERSION_HPN when there is no VersionAddendum is set. HPN patch requires both parties to have the "hpn" inside their advertized versions, so we add VERSION_HPN to the VERSION_BASE if HPN is enabled and omitting it if HPN is disabled. VersionAddendum now uses the following logics: * unset (default value): append " " and VERSION_ADDENDUM; * VersionAddendum is set and isn't empty: append " " and VersionAddendum; * VersionAddendum is set and empty: don't append anything. Signed-off-by: Eygene Ryabinkin --- crypto/openssh/ssh.c | 3 +- crypto/openssh/sshconnect.c | 2 +- crypto/openssh/sshd.c | 6 ++-- crypto/openssh/version.c | 67 +++++++++++++++++++++++++++++++------------ crypto/openssh/version.h | 4 +-- 5 files changed, 56 insertions(+), 26 deletions(-) diff --git a/crypto/openssh/ssh.c b/crypto/openssh/ssh.c index f36e1f3..44ddeb0 100644 --- a/crypto/openssh/ssh.c +++ b/crypto/openssh/ssh.c @@ -388,7 +388,8 @@ main(int ac, char **av) /* FALLTHROUGH */ case 'V': fprintf(stderr, "%s, %s\n", - SSH_RELEASE, SSLeay_version(SSLEAY_VERSION)); + ssh_version_get(options.hpn_disabled), + SSLeay_version(SSLEAY_VERSION)); if (opt == 'V') exit(0); break; diff --git a/crypto/openssh/sshconnect.c b/crypto/openssh/sshconnect.c index 5e0938a..87c2897 100644 --- a/crypto/openssh/sshconnect.c +++ b/crypto/openssh/sshconnect.c @@ -571,7 +571,7 @@ ssh_exchange_identification(int timeout_ms) snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s", compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, compat20 ? PROTOCOL_MINOR_2 : minor1, - SSH_RELEASE, compat20 ? "\r\n" : "\n"); + ssh_version_get(options.hpn_disabled), compat20 ? "\r\n" : "\n"); if (roaming_atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf)) fatal("write: %.100s", strerror(errno)); diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c index 123b28f..1cde84e 100644 --- a/crypto/openssh/sshd.c +++ b/crypto/openssh/sshd.c @@ -431,7 +431,7 @@ sshd_exchange_identification(int sock_in, int sock_out) minor = PROTOCOL_MINOR_1; } snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s", major, minor, - SSH_RELEASE, newline); + ssh_version_get(options.hpn_disabled), newline); server_version_string = xstrdup(buf); /* Send our protocol version identification. */ @@ -860,7 +860,7 @@ static void usage(void) { fprintf(stderr, "%s, %s\n", - SSH_RELEASE, SSLeay_version(SSLEAY_VERSION)); + ssh_version_get(0), SSLeay_version(SSLEAY_VERSION)); fprintf(stderr, "usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-c host_cert_file]\n" " [-f config_file] [-g login_grace_time] [-h host_key_file]\n" @@ -1550,7 +1550,7 @@ main(int ac, char **av) exit(1); } - debug("sshd version %.100s", SSH_RELEASE); + debug("sshd version %.100s", ssh_version_get(options.hpn_disabled)); /* Store privilege separation user for later use if required. */ if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) { diff --git a/crypto/openssh/version.c b/crypto/openssh/version.c index 3cb4b7a..2f46794 100644 --- a/crypto/openssh/version.c +++ b/crypto/openssh/version.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2001 Brian Fundakowski Feldman + * Copyright (c) 2012 Eygene Ryabinkin * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,30 +36,60 @@ __RCSID("$FreeBSD$"); static char *version = NULL; +/* NULL means "use default value", empty string means "unset" */ +static const char *addendum = NULL; +static unsigned char update_version = 1; +/* + * Constructs the version string if it is empty or needs updating. + * + * HPN patch we're running requires both parties + * to have the "hpn" string inside the advertized version + * (see compat.c::compat_datafellows), so we should + * include it to the generated string if HPN is enabled. + */ const char * -ssh_version_get(void) { +ssh_version_get(int hpn_disabled) +{ + const char *hpn = NULL, *add = NULL; + char *newvers = NULL; + size_t size = 0; - if (version == NULL) - version = xstrdup(SSH_VERSION); - return (version); -} + if (version != NULL && !update_version) + return (version); -void -ssh_version_set_addendum(const char *add) { - char *newvers; - size_t size; + hpn = (hpn_disabled ? NULL : SSH_VERSION_HPN); + add = (addendum == NULL ? SSH_VERSION_ADDENDUM : + (addendum[0] == '\0' ? NULL : addendum)); - if (add != NULL) { - size = strlen(SSH_VERSION_BASE) + strlen(SSH_VERSION_HPN) + 1 + - strlen(add) + 1; - newvers = xmalloc(size); - snprintf(newvers, size, "%s %s", SSH_VERSION_BASE, - SSH_VERSION_HPN, add); - } else { - newvers = xstrdup(SSH_VERSION_BASE SSH_VERSION_HPN); + size = strlen(SSH_VERSION_BASE) + (hpn ? strlen(hpn) : 0) + + (add ? strlen(add) + 1 : 0) + 1; + newvers = xmalloc(size); + strcpy(newvers, SSH_VERSION_BASE); + if (hpn) + strcat(newvers, hpn); + if (add) { + strcat(newvers, " "); + strcat(newvers, add); } - if (version != NULL) + + if (version) xfree(version); version = newvers; + update_version = 0; + + return (version); +} + +void +ssh_version_set_addendum(const char *add) +{ + if (add && addendum && !strcmp(add, addendum)) + return; + + if (addendum) + xfree((void *)addendum); + addendum = (add ? xstrdup(add) : xstrdup("")); + + update_version = 1; } diff --git a/crypto/openssh/version.h b/crypto/openssh/version.h index d9140e8..92ec46f 100644 --- a/crypto/openssh/version.h +++ b/crypto/openssh/version.h @@ -6,9 +6,7 @@ #define SSH_VERSION_BASE "OpenSSH_5.4p1" #define SSH_VERSION_ADDENDUM "FreeBSD-20100308" #define SSH_VERSION_HPN "_hpn13v11" -#define SSH_VERSION SSH_VERSION_BASE SSH_VERSION_HPN " " SSH_VERSION_ADDENDUM -#define SSH_RELEASE (ssh_version_get()) -const char *ssh_version_get(void); +const char *ssh_version_get(int); void ssh_version_set_addendum(const char *); #endif /* SSH_VERSION */ -- 1.7.9.6