aboutsummaryrefslogtreecommitdiff
path: root/src/client.c
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 09:41:26 +0200
commit3d1edffe770f157afaf543cad6f7256637af6088 (patch)
tree9548a51fdcf024f9ff08e7adbadc0cab4e0a6cf7 /src/client.c
parentcb52ed7b1253fab98f00e4dc078ad5db6d793021 (diff)
downloadlibssh-3d1edffe770f157afaf543cad6f7256637af6088.tar.gz
libssh-3d1edffe770f157afaf543cad6f7256637af6088.tar.xz
libssh-3d1edffe770f157afaf543cad6f7256637af6088.zip
client: Fix ssh_send_banner() to confirm with RFC 4253
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Diffstat (limited to 'src/client.c')
-rw-r--r--src/client.c95
1 files changed, 62 insertions, 33 deletions
diff --git a/src/client.c b/src/client.c
index b437bfcc..8514624c 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