From e1c06db9614adac5dbc0db3be048e6d3bb916b61 Mon Sep 17 00:00:00 2001 From: green Date: Tue, 20 Mar 2001 02:06:40 +0000 Subject: Make password attacks based on traffic analysis harder by requiring that "non-echoed" characters are still echoed back in a null packet, as well as pad passwords sent to not give hints to the length otherwise. Obtained from: OpenBSD --- crypto/openssh/channels.c | 27 +++++++++++++++++++++++++++ crypto/openssh/channels.h | 2 ++ crypto/openssh/compat.c | 2 ++ crypto/openssh/compat.h | 2 ++ crypto/openssh/serverloop.c | 20 +++++++++++++++++++- crypto/openssh/sshconnect.c | 15 +++++++++++++++ crypto/openssh/sshconnect.h | 2 ++ crypto/openssh/sshconnect1.c | 4 ++-- crypto/openssh/sshconnect2.c | 5 +++-- 9 files changed, 74 insertions(+), 5 deletions(-) diff --git a/crypto/openssh/channels.c b/crypto/openssh/channels.c index 81bd715..1abc940 100644 --- a/crypto/openssh/channels.c +++ b/crypto/openssh/channels.c @@ -40,6 +40,7 @@ */ #include "includes.h" +RCSID("$FreeBSD$"); RCSID("$OpenBSD: channels.c,v 1.72 2000/10/27 07:48:22 markus Exp $"); #include "ssh.h" @@ -192,6 +193,18 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd, c->efd = efd; c->extended_usage = extusage; + /* XXX ugly hack: nonblock is only set by the server */ + if (nonblock && isatty(c->rfd)) { + debug("channel: %d: rfd %d isatty", c->self, c->rfd); + c->isatty = 1; + if (!isatty(c->wfd)) { + error("channel: %d: wfd %d is not a tty?", + c->self, c->wfd); + } + } else { + c->isatty = 0; + } + /* enable nonblocking mode */ if (nonblock) { if (rfd != -1) @@ -722,6 +735,20 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset) } return -1; } + if (compat20 && c->isatty) { + struct termios tio; + if (tcgetattr(c->wfd, &tio) == 0 && + !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) { + /* + * Simulate echo to reduce the impact of + * traffic analysis. + */ + packet_start(SSH2_MSG_IGNORE); + memset(buffer_ptr(&c->output), 0, len); + packet_put_string(buffer_ptr(&c->output), len); + packet_send(); + } + } buffer_consume(&c->output, len); if (compat20 && len > 0) { c->local_consumed += len; diff --git a/crypto/openssh/channels.h b/crypto/openssh/channels.h index 0052686..8f23dee 100644 --- a/crypto/openssh/channels.h +++ b/crypto/openssh/channels.h @@ -32,6 +32,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* RCSID("$FreeBSD$"); */ /* RCSID("$OpenBSD: channels.h,v 1.22 2000/10/27 07:48:22 markus Exp $"); */ #ifndef CHANNELS_H @@ -73,6 +74,7 @@ struct Channel { int wfd; /* write fd */ int efd; /* extended fd */ int sock; /* sock fd */ + int isatty; /* rfd is a tty */ Buffer input; /* data read from socket, to be sent over * encrypted connection */ Buffer output; /* data received over encrypted connection for diff --git a/crypto/openssh/compat.c b/crypto/openssh/compat.c index f58e9fa..c5f69cf 100644 --- a/crypto/openssh/compat.c +++ b/crypto/openssh/compat.c @@ -72,6 +72,8 @@ compat_datafellows(const char *version) { "^2\\.4$", SSH_OLD_SESSIONID}, /* Van Dyke */ { "^3\\.0 SecureCRT", SSH_OLD_SESSIONID}, { "^1\\.7 SecureFX", SSH_OLD_SESSIONID}, + { "^1\\.2\\.1[89]", SSH_BUG_IGNOREMSG}, + { "^1\\.2\\.2[012]", SSH_BUG_IGNOREMSG}, { "^2\\.", SSH_BUG_HMAC}, /* XXX fallback */ { NULL, 0 } }; diff --git a/crypto/openssh/compat.h b/crypto/openssh/compat.h index f14efaf..2b3e5aa 100644 --- a/crypto/openssh/compat.h +++ b/crypto/openssh/compat.h @@ -21,6 +21,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* RCSID("$FreeBSD$"); */ /* RCSID("$OpenBSD: compat.h,v 1.11 2000/10/14 12:16:56 markus Exp $"); */ #ifndef COMPAT_H @@ -36,6 +37,7 @@ #define SSH_BUG_HMAC 0x04 #define SSH_BUG_X11FWD 0x08 #define SSH_OLD_SESSIONID 0x10 +#define SSH_BUG_IGNOREMSG 0x20 void enable_compat13(void); void enable_compat20(void); diff --git a/crypto/openssh/serverloop.c b/crypto/openssh/serverloop.c index f63131d..5372ab3 100644 --- a/crypto/openssh/serverloop.c +++ b/crypto/openssh/serverloop.c @@ -35,6 +35,7 @@ */ #include "includes.h" +RCSID("$FreeBSD$"); RCSID("$OpenBSD: serverloop.c,v 1.34 2000/10/27 07:32:18 markus Exp $"); #include "xmalloc.h" @@ -67,6 +68,7 @@ static long fdout_bytes = 0; /* Number of stdout bytes read from program. */ static int stdin_eof = 0; /* EOF message received from client. */ static int fdout_eof = 0; /* EOF encountered reading from fdout. */ static int fderr_eof = 0; /* EOF encountered readung from fderr. */ +static int fdin_is_tty = 0; /* fdin points to a tty. */ static int connection_in; /* Connection to client (input). */ static int connection_out; /* Connection to client (output). */ static unsigned int buffer_high;/* "Soft" max buffer size. */ @@ -322,6 +324,7 @@ process_input(fd_set * readset) void process_output(fd_set * writeset) { + struct termios tio; int len; /* Write buffered data to program stdin. */ @@ -341,7 +344,19 @@ process_output(fd_set * writeset) #endif fdin = -1; } else { - /* Successful write. Consume the data from the buffer. */ + /* Successful write. */ + if (fdin_is_tty && tcgetattr(fdin, &tio) == 0 && + !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) { + /* + * Simulate echo to reduce the impact of + * traffic analysis + */ + packet_start(SSH_MSG_IGNORE); + memset(buffer_ptr(&stdin_buffer), 0, len); + packet_put_string(buffer_ptr(&stdin_buffer), len); + packet_send(); + } + /* Consume the data from the buffer. */ buffer_consume(&stdin_buffer, len); /* Update the count of bytes written to the program. */ stdin_bytes += len; @@ -425,6 +440,9 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) if (fderr != -1) set_nonblock(fderr); + if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin)) + fdin_is_tty = 1; + connection_in = packet_get_connection_in(); connection_out = packet_get_connection_out(); diff --git a/crypto/openssh/sshconnect.c b/crypto/openssh/sshconnect.c index 57d4a43..364a7c9 100644 --- a/crypto/openssh/sshconnect.c +++ b/crypto/openssh/sshconnect.c @@ -900,3 +900,18 @@ ssh_login(int host_key_valid, RSA *own_host_key, const char *orighost, ssh_userauth(local_user, server_user, host, host_key_valid, own_host_key); } } + +void +ssh_put_password(char *password) +{ + int size; + char *padded; + + size = roundup(strlen(password) + 1, 32); + padded = xmalloc(size); + memset(padded, 0, size); + strlcpy(padded, password, size); + packet_put_string(padded, size); + memset(padded, 0, size); + xfree(padded); +} diff --git a/crypto/openssh/sshconnect.h b/crypto/openssh/sshconnect.h index 0b0287e..b2e70d5 100644 --- a/crypto/openssh/sshconnect.h +++ b/crypto/openssh/sshconnect.h @@ -38,4 +38,6 @@ ssh_userauth(const char* local_user, const char* server_user, char *host, void ssh_kex2(char *host, struct sockaddr *hostaddr); void ssh_userauth2(const char *server_user, char *host); +void ssh_put_password(char *password); + #endif diff --git a/crypto/openssh/sshconnect1.c b/crypto/openssh/sshconnect1.c index 4d7351b..2b2d5fc 100644 --- a/crypto/openssh/sshconnect1.c +++ b/crypto/openssh/sshconnect1.c @@ -640,7 +640,7 @@ try_skey_authentication() error("Permission denied, please try again."); response = read_passphrase("Response: ", 0); packet_start(SSH_CMSG_AUTH_TIS_RESPONSE); - packet_put_string(response, strlen(response)); + ssh_put_password(response); memset(response, 0, strlen(response)); xfree(response); packet_send(); @@ -673,7 +673,7 @@ try_password_authentication(char *prompt) error("Permission denied, please try again."); password = read_passphrase(prompt, 0); packet_start(SSH_CMSG_AUTH_PASSWORD); - packet_put_string(password, strlen(password)); + ssh_put_password(password); memset(password, 0, strlen(password)); xfree(password); packet_send(); diff --git a/crypto/openssh/sshconnect2.c b/crypto/openssh/sshconnect2.c index 6ba23d4..fb7bff0 100644 --- a/crypto/openssh/sshconnect2.c +++ b/crypto/openssh/sshconnect2.c @@ -23,6 +23,7 @@ */ #include "includes.h" +RCSID("$FreeBSD$"); RCSID("$OpenBSD: sshconnect2.c,v 1.27 2000/10/19 16:45:16 provos Exp $"); #include @@ -635,7 +636,7 @@ userauth_passwd(Authctxt *authctxt) packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_put_char(0); - packet_put_cstring(password); + ssh_put_password(password); memset(password, 0, strlen(password)); xfree(password); packet_send(); @@ -892,7 +893,7 @@ input_userauth_info_req(int type, int plen, void *ctxt) response = cli_prompt(prompt, echo); - packet_put_cstring(response); + ssh_put_password(response); memset(response, 0, strlen(response)); xfree(response); xfree(prompt); -- cgit v1.1