From 9c91ea1caf8a7263d830de0bbd5f3b183940b595 Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Mon, 2 Aug 2004 04:25:05 +0000 Subject: [PATCH] Banner printing --HG-- extra : convert_revision : a38558944355bb9b4c8e9e22147c1f2d8d327775 --- auth.h | 1 + cli-auth.c | 42 ++++++++++++++++++++++++++++++++++++++++++ cli-session.c | 22 ++++++++++++++++++++++ options.h | 1 + session.h | 1 + 5 files changed, 67 insertions(+) diff --git a/auth.h b/auth.h index df8ae0c..106a1ad 100644 --- a/auth.h +++ b/auth.h @@ -47,6 +47,7 @@ void recv_msg_userauth_success(); void cli_get_user(); void cli_auth_getmethods(); void cli_auth_try(); +void recv_msg_userauth_banner(); #define MAX_USERNAME_LEN 25 /* arbitrary for the moment */ diff --git a/cli-auth.c b/cli-auth.c index e081587..549349e 100644 --- a/cli-auth.c +++ b/cli-auth.c @@ -35,6 +35,48 @@ void cli_auth_getmethods() { } +void recv_msg_userauth_banner() { + + unsigned char* banner = NULL; + unsigned int bannerlen; + unsigned int i, linecount; + + TRACE(("enter recv_msg_userauth_banner")); + if (ses.authstate.authdone) { + TRACE(("leave recv_msg_userauth_banner: banner after auth done")); + return; + } + + banner = buf_getstring(ses.payload, &bannerlen); + buf_eatstring(ses.payload); /* The language string */ + + if (bannerlen > MAX_BANNER_SIZE) { + TRACE(("recv_msg_userauth_banner: bannerlen too long: %d", bannerlen)); + goto out; + } + + cleantext(banner); + + /* Limit to 25 lines */ + linecount = 1; + for (i = 0; i < bannerlen; i++) { + if (banner[i] == '\n') { + if (linecount >= MAX_BANNER_LINES) { + banner[i] = '\0'; + break; + } + linecount++; + } + } + + printf("%s\n", banner); + +out: + m_free(banner); + TRACE(("leave recv_msg_userauth_banner")); +} + + void recv_msg_userauth_failure() { unsigned char * methods = NULL; diff --git a/cli-session.c b/cli-session.c index 6882d2e..e8c6ae6 100644 --- a/cli-session.c +++ b/cli-session.c @@ -36,6 +36,7 @@ static const packettype cli_packettypes[] = { {SSH_MSG_CHANNEL_OPEN_FAILURE, recv_msg_channel_open_failure}, {SSH_MSG_USERAUTH_FAILURE, recv_msg_userauth_failure}, // client {SSH_MSG_USERAUTH_SUCCESS, recv_msg_userauth_success}, // client + {SSH_MSG_USERAUTH_BANNER, recv_msg_userauth_banner}, // client {0, 0} /* End */ }; @@ -217,3 +218,24 @@ static void cli_remoteclosed() { ses.sock = -1; dropbear_exit("remote closed the connection"); } + +/* Operates in-place turning dirty (untrusted potentially containing control + * characters) text into clean text. */ +void cleantext(unsigned char* dirtytext) { + + unsigned int i, j; + unsigned char c, lastchar; + + j = 0; + for (i = 0; dirtytext[i] != '\0'; i++) { + + c = dirtytext[i]; + /* We can ignore '\r's */ + if ( (c >= ' ' && c <= '~') || c == '\n' || c == '\t') { + dirtytext[j] = c; + j++; + } + } + /* Null terminate */ + dirtytext[j] = '\0'; +} diff --git a/options.h b/options.h index 1ab16c7..8ed21ab 100644 --- a/options.h +++ b/options.h @@ -195,6 +195,7 @@ #endif #define MAX_BANNER_SIZE 2000 /* this is 25*80 chars, any more is foolish */ +#define MAX_BANNER_LINES 20 /* How many lines the client will display */ #define DEV_URANDOM "/dev/urandom" diff --git a/session.h b/session.h index 2009054..2323377 100644 --- a/session.h +++ b/session.h @@ -56,6 +56,7 @@ void cli_session(int sock, char *remotehost); void cli_dropbear_exit(int exitcode, const char* format, va_list param); void cli_dropbear_log(int priority, const char* format, va_list param); void cli_session_cleanup(); +void cleantext(unsigned char* dirtytext); struct key_context {