summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--auth.h1
-rw-r--r--cli-auth.c42
-rw-r--r--cli-session.c22
-rw-r--r--options.h1
-rw-r--r--session.h1
5 files changed, 67 insertions, 0 deletions
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 {