aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schneider <asn@cryptomilk.org>2016-05-02 09:53:02 +0200
committerAndreas Schneider <asn@cryptomilk.org>2016-05-03 10:58:27 +0200
commit219d0bba42ad95227035728c5cb37b9f51e6a8fa (patch)
treecbe88051ba8de0a8ada842d8080d49777ffff0dd
parentbf3d8f3ad43706c12a6a2c1d6d5e8f4ae92d55e9 (diff)
downloadlibssh-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.c95
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