diff options
author | Andreas Schneider <asn@cryptomilk.org> | 2016-05-02 09:53:02 +0200 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2016-05-03 10:58:27 +0200 |
commit | 219d0bba42ad95227035728c5cb37b9f51e6a8fa (patch) | |
tree | cbe88051ba8de0a8ada842d8080d49777ffff0dd | |
parent | bf3d8f3ad43706c12a6a2c1d6d5e8f4ae92d55e9 (diff) | |
download | libssh-219d0bba42ad95227035728c5cb37b9f51e6a8fa.tar.gz libssh-219d0bba42ad95227035728c5cb37b9f51e6a8fa.tar.xz libssh-219d0bba42ad95227035728c5cb37b9f51e6a8fa.zip |
client: Fix ssh_send_banner() to confirm with RFC 4253
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 3d1edffe770f157afaf543cad6f7256637af6088)
-rw-r--r-- | src/client.c | 95 |
1 files changed, 62 insertions, 33 deletions
diff --git a/src/client.c b/src/client.c index 2abb8b6c..74f2112e 100644 --- a/src/client.c +++ b/src/client.c @@ -169,46 +169,75 @@ static int callback_receive_banner(const void *data, size_t len, void *user) * * @return 0 on success, < 0 on error. */ -int ssh_send_banner(ssh_session session, int server) { - const char *banner = NULL; - char buffer[128] = {0}; - int err=SSH_ERROR; - - banner = session->version == 1 ? CLIENTBANNER1 : CLIENTBANNER2; +int ssh_send_banner(ssh_session session, int server) +{ + const char *banner = NULL; + const char *terminator = NULL; + /* The maximum banner length is 255 for SSH2 */ + char buffer[256] = {0}; + size_t len; + int rc = SSH_ERROR; + + banner = session->version == 1 ? CLIENTBANNER1 : CLIENTBANNER2; + terminator = session->version == 1 ? "\n" : "\r\n"; + + if (server == 1) { + if (session->opts.custombanner == NULL){ + len = strlen(banner); + session->serverbanner = strdup(banner); + if (session->serverbanner == NULL) { + goto end; + } + } else { + len = strlen(session->opts.custombanner); + session->serverbanner = malloc(len + 8 + 1); + if(session->serverbanner == NULL) { + goto end; + } + snprintf(session->serverbanner, + len + 8 + 1, + "SSH-2.0-%s", + session->opts.custombanner); + } - if (server) { - if(session->opts.custombanner == NULL){ - session->serverbanner = strdup(banner); + snprintf(buffer, + sizeof(buffer), + "%s%s", + session->serverbanner, + terminator); } else { - session->serverbanner = malloc(strlen(session->opts.custombanner) + 9); - if(!session->serverbanner) - goto end; - strcpy(session->serverbanner, "SSH-2.0-"); - strcat(session->serverbanner, session->opts.custombanner); - } - if (session->serverbanner == NULL) { - goto end; - } - snprintf(buffer, 128, "%s\n", session->serverbanner); - } else { - session->clientbanner = strdup(banner); - if (session->clientbanner == NULL) { - goto end; + session->clientbanner = strdup(banner); + if (session->clientbanner == NULL) { + goto end; + } + + /* SSH version 1 has a banner length of 128 only */ + len = session->version == 1 ? 128 : 0; + + snprintf(buffer, + sizeof(buffer) - len, + "%s%s", + session->clientbanner, + terminator); } - snprintf(buffer, 128, "%s\n", session->clientbanner); - } - if (ssh_socket_write(session->socket, buffer, strlen(buffer)) == SSH_ERROR) { - goto end; - } + rc = ssh_socket_write(session->socket, buffer, strlen(buffer)); + if (rc == SSH_ERROR) { + goto end; + } #ifdef WITH_PCAP - if(session->pcap_ctx) - ssh_pcap_context_write(session->pcap_ctx,SSH_PCAP_DIR_OUT,buffer,strlen(buffer),strlen(buffer)); + if (session->pcap_ctx != NULL) { + ssh_pcap_context_write(session->pcap_ctx, + SSH_PCAP_DIR_OUT, + buffer, + strlen(buffer), + strlen(buffer)); + } #endif - err=SSH_OK; -end: - return err; + rc = SSH_OK; +end: + return rc; } /** @internal |