]> andersk Git - gssapi-openssh.git/commitdiff
update to http://www.psc.edu/networking/projects/hpn-ssh/openssh-4.7p1-hpn13v1.diff.gz
authorbasney <basney>
Thu, 13 Mar 2008 16:26:37 +0000 (16:26 +0000)
committerbasney <basney>
Thu, 13 Mar 2008 16:26:37 +0000 (16:26 +0000)
14 files changed:
openssh/Makefile.in
openssh/atomicio.c
openssh/auth2.c
openssh/buffer.c
openssh/channels.c
openssh/channels.h
openssh/cipher-ctr-mt.c [new file with mode: 0644]
openssh/cipher.c
openssh/kex.c
openssh/packet.c
openssh/packet.h
openssh/serverloop.c
openssh/sshd.c
openssh/version.h

index 7a38906d6a4b0896ec0fe2ac925caee2813ff592..cac0ba58e0e3c333c0fb16efa4cef71584b3b8a1 100644 (file)
@@ -43,7 +43,7 @@ CC=@CC@
 LD=@LD@
 CFLAGS=@CFLAGS@
 CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
-LIBS=@LIBS@
+LIBS=@LIBS@ -lpthread
 SSHDLIBS=@SSHDLIBS@
 LIBEDIT=@LIBEDIT@
 AR=@AR@
@@ -65,7 +65,7 @@ TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keys
 
 LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
        canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
-       cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \
+       cipher-bf1.o cipher-ctr.o cipher-ctr-mt.o cipher-3des1.o cleanup.o \
        compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \
        log.o match.o md-sha256.o moduli.o nchan.o packet.o \
        readpass.o rsa.o ttymodes.o xmalloc.o \
index 47161eb3a1e3175ebbbd056e7ad9f5f96ba0dd4c..62ee40282d7233aca67b8d903a1eb5ee1430e068 100644 (file)
@@ -1,4 +1,7 @@
+/* $OpenBSD: atomicio.c,v 1.25 2007/06/25 12:02:27 dtucker Exp $ */
 /*
+ * Copyright (c) 2006 Damien Miller. All rights reserved.
+ * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved.
  * Copyright (c) 1995,1999 Theo de Raadt.  All rights reserved.
  * All rights reserved.
  *
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: atomicio.c,v 1.10 2001/05/08 22:48:07 markus Exp $");
+
+#include <sys/param.h>
+#include <sys/uio.h>
+
+#include <errno.h>
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
+#include <string.h>
+#include <unistd.h>
 
 #include "atomicio.h"
 
 /*
- * ensure all of data on socket comes through. f==read || f==write
+ * ensure all of data on socket comes through. f==read || f==vwrite
  */
-ssize_t
-atomicio(f, fd, _s, n)
-       ssize_t (*f) ();
-       int fd;
-       void *_s;
-       size_t n;
+size_t
+atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n)
 {
        char *s = _s;
-       ssize_t res, pos = 0;
+       size_t pos = 0;
+       ssize_t res;
+       struct pollfd pfd;
 
+       pfd.fd = fd;
+       pfd.events = f == read ? POLLIN : POLLOUT;
        while (n > pos) {
                res = (f) (fd, s + pos, n - pos);
                switch (res) {
                case -1:
+                       if (errno == EINTR)
+                               continue;
 #ifdef EWOULDBLOCK
-                       if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
+                       if (errno == EAGAIN || errno == EWOULDBLOCK) {
 #else
-                       if (errno == EINTR || errno == EAGAIN)
+                       if (errno == EAGAIN) {
 #endif
+                               (void)poll(&pfd, 1, -1);
                                continue;
+                       }
+                       return 0;
                case 0:
-                       return (res);
+                       errno = EPIPE;
+                       return pos;
                default:
-                       pos += res;
+                       pos += (size_t)res;
                }
        }
        return (pos);
 }
+
+/*
+ * ensure all of data on socket comes through. f==readv || f==writev
+ */
+size_t
+atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd,
+    const struct iovec *_iov, int iovcnt)
+{
+       size_t pos = 0, rem;
+       ssize_t res;
+       struct iovec iov_array[IOV_MAX], *iov = iov_array;
+       struct pollfd pfd;
+
+       if (iovcnt > IOV_MAX) {
+               errno = EINVAL;
+               return 0;
+       }
+       /* Make a copy of the iov array because we may modify it below */
+       memcpy(iov, _iov, iovcnt * sizeof(*_iov));
+
+       pfd.fd = fd;
+       pfd.events = f == readv ? POLLIN : POLLOUT;
+       for (; iovcnt > 0 && iov[0].iov_len > 0;) {
+               res = (f) (fd, iov, iovcnt);
+               switch (res) {
+               case -1:
+                       if (errno == EINTR)
+                               continue;
+#ifdef EWOULDBLOCK
+                       if (errno == EAGAIN || errno == EWOULDBLOCK) {
+#else
+                       if (errno == EAGAIN) {
+#endif
+                               (void)poll(&pfd, 1, -1);
+                               continue;
+                       }
+                       return 0;
+               case 0:
+                       errno = EPIPE;
+                       return pos;
+               default:
+                       rem = (size_t)res;
+                       pos += rem;
+                       /* skip completed iov entries */
+                       while (iovcnt > 0 && rem >= iov[0].iov_len) {
+                               rem -= iov[0].iov_len;
+                               iov++;
+                               iovcnt--;
+                       }
+                       /* This shouldn't happen... */
+                       if (rem > 0 && (iovcnt <= 0 || rem > iov[0].iov_len)) {
+                               errno = EFAULT;
+                               return 0;
+                       }
+                       if (iovcnt == 0)
+                               break;
+                       /* update pointer in partially complete iov */
+                       iov[0].iov_base = ((char *)iov[0].iov_base) + rem;
+                       iov[0].iov_len -= rem;
+               }
+       }
+       return pos;
+}
index 76724f4406babbfb66593f48c241c0194726461d..ff7d639e68a86ca956205e375131090b095415b5 100644 (file)
@@ -44,6 +44,7 @@
 #include "dispatch.h"
 #include "pathnames.h"
 #include "buffer.h"
+#include "canohost.h"
 
 #ifdef GSSAPI
 #include "ssh-gss.h"
@@ -70,6 +71,9 @@ extern Authmethod method_gssapi;
 extern Authmethod method_gssapi_compat;
 #endif
 
+static int log_flag = 0;
+
+
 Authmethod *authmethods[] = {
        &method_none,
        &method_pubkey,
@@ -178,6 +182,11 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
 
        debug("userauth-request for user %s service %s method %s",
              user[0] ? user : "<implicit>", service, method);
+       if (!log_flag) {
+               logit("SSH: Server;Ltype: Authname;Remote: %s-%d;Name: %s", 
+                     get_remote_ipaddr(), get_remote_port(), user);
+               log_flag = 1;
+       }
        debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
 
        if ((style = strchr(user, ':')) != NULL)
index cb0b620703ccadf23ce5eb480c6fdeb6542c018d..1c04cab3901ed9822704b018637a9b0e510f1929 100644 (file)
@@ -127,7 +127,9 @@ restart:
 
        /* Increase the size of the buffer and retry. */
        newlen = roundup(buffer->alloc + len, BUFFER_ALLOCSZ);
-       if (newlen > BUFFER_MAX_LEN_HPN)
+       /* need it to be slightly larger than the MAX LEN for this */
+       /* still investigating *why* but this works for now -cjr */
+       if (newlen > (BUFFER_MAX_LEN_HPN + BUFFER_MAX_LEN)) 
                fatal("buffer_append_space: alloc %u not supported",
                    newlen);
        buffer->buf = xrealloc(buffer->buf, 1, newlen);
index 39dd9305f7d69b0019688a250308d602bed6fdf3..2ef1af902fc7a35c1ee546d0bc706355a43e14a9 100644 (file)
@@ -1903,11 +1903,12 @@ channel_after_select(fd_set *readset, fd_set *writeset)
 
 
 /* If there is data to send to the connection, enqueue some of it now. */
-void
+int
 channel_output_poll(void)
 {
        Channel *c;
        u_int i, len;
+       int packet_length = 0;
 
        for (i = 0; i < channels_alloc; i++) {
                c = channels[i];
@@ -1947,7 +1948,7 @@ channel_output_poll(void)
                                        packet_start(SSH2_MSG_CHANNEL_DATA);
                                        packet_put_int(c->remote_id);
                                        packet_put_string(data, dlen);
-                                       packet_send();
+                                       packet_length = packet_send();
                                        c->remote_window -= dlen + 4;
                                        xfree(data);
                                }
@@ -1977,7 +1978,7 @@ channel_output_poll(void)
                                    SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA);
                                packet_put_int(c->remote_id);
                                packet_put_string(buffer_ptr(&c->input), len);
-                               packet_send();
+                               packet_length = packet_send();
                                buffer_consume(&c->input, len);
                                c->remote_window -= len;
                        }
@@ -2012,12 +2013,13 @@ channel_output_poll(void)
                        packet_put_int(c->remote_id);
                        packet_put_int(SSH2_EXTENDED_DATA_STDERR);
                        packet_put_string(buffer_ptr(&c->extended), len);
-                       packet_send();
+                       packet_length = packet_send();
                        buffer_consume(&c->extended, len);
                        c->remote_window -= len;
                        debug2("channel %d: sent ext data %d", c->self, len);
                }
        }
+       return (packet_length);
 }
 
 
index c018fb71ab39b685886728eaf6f1ad96347d8483..da37281ceed3f8cd578e9911c5d2762bb443e32b 100644 (file)
@@ -197,7 +197,7 @@ void         channel_input_window_adjust(int, u_int32_t, void *);
 
 void    channel_prepare_select(fd_set **, fd_set **, int *, u_int*, int);
 void     channel_after_select(fd_set *, fd_set *);
-void     channel_output_poll(void);
+int      channel_output_poll(void);
 
 int      channel_not_very_much_buffered_data(void);
 void     channel_close_all(void);
diff --git a/openssh/cipher-ctr-mt.c b/openssh/cipher-ctr-mt.c
new file mode 100644 (file)
index 0000000..abe39ff
--- /dev/null
@@ -0,0 +1,473 @@
+/*
+ * OpenSSH Multi-threaded AES-CTR Cipher
+ *
+ * Author: Benjamin Bennett <ben@psc.edu>
+ * Copyright (c) 2008 Pittsburgh Supercomputing Center. All rights reserved.
+ *
+ * Based on original OpenSSH AES-CTR cipher. Small portions remain unchanged,
+ * Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include "includes.h"
+
+#include <sys/types.h>
+
+#include <stdarg.h>
+#include <string.h>
+
+#include <openssl/evp.h>
+
+#include "xmalloc.h"
+#include "log.h"
+
+/* compatibility with old or broken OpenSSL versions */
+#include "openbsd-compat/openssl-compat.h"
+
+#ifndef USE_BUILTIN_RIJNDAEL
+#include <openssl/aes.h>
+#endif
+
+#include <pthread.h>
+
+/*-------------------- TUNABLES --------------------*/
+/* Number of pregen threads to use */
+#define CIPHER_THREADS 2
+
+/* Number of keystream queues */
+#define NUMKQ          (CIPHER_THREADS + 2)
+
+/* Length of a keystream queue */
+#define KQLEN          4096
+
+/* Processor cacheline length */
+#define CACHELINE_LEN  64
+
+/* Collect thread stats and print at cancellation when in debug mode */
+// #define CIPHER_THREAD_STATS
+
+/* Use single-byte XOR instead of 8-byte XOR */
+// #define CIPHER_BYTE_XOR
+/*-------------------- END TUNABLES --------------------*/
+
+
+const EVP_CIPHER *evp_aes_ctr_mt(void);
+
+#ifdef CIPHER_THREAD_STATS
+/*
+ * Struct to collect thread stats
+ */
+struct thread_stats {
+       u_int   fills;
+       u_int   skips;
+       u_int   waits;
+       u_int   drains;
+};
+
+/*
+ * Debug print the thread stats
+ * Use with pthread_cleanup_push for displaying at thread cancellation
+ */
+static void
+thread_loop_stats(void *x)
+{
+       struct thread_stats *s = x;
+
+       debug("tid %lu - %u fills, %u skips, %u waits", pthread_self(),
+                       s->fills, s->skips, s->waits);
+}
+
+ #define STATS_STRUCT(s)       struct thread_stats s
+ #define STATS_INIT(s)         { memset(&s, 0, sizeof(s)); }
+ #define STATS_FILL(s)         { s.fills++; }
+ #define STATS_SKIP(s)         { s.skips++; }
+ #define STATS_WAIT(s)         { s.waits++; }
+ #define STATS_DRAIN(s)                { s.drains++; }
+#else
+ #define STATS_STRUCT(s)
+ #define STATS_INIT(s)
+ #define STATS_FILL(s)
+ #define STATS_SKIP(s)
+ #define STATS_WAIT(s)
+ #define STATS_DRAIN(s)
+#endif
+
+/* Keystream Queue state */
+enum {
+       KQINIT,
+       KQEMPTY,
+       KQFILLING,
+       KQFULL,
+       KQDRAINING
+};
+
+/* Keystream Queue struct */
+struct kq {
+       u_char          keys[KQLEN][AES_BLOCK_SIZE];
+       u_char          ctr[AES_BLOCK_SIZE];
+       u_char          pad0[CACHELINE_LEN];
+       volatile int    qstate;
+       pthread_mutex_t lock;
+       pthread_cond_t  cond;
+       u_char          pad1[CACHELINE_LEN];
+};
+
+/* Context struct */
+struct ssh_aes_ctr_ctx
+{
+       struct kq       q[NUMKQ];
+       AES_KEY         aes_ctx;
+       STATS_STRUCT(stats);
+       u_char          aes_counter[AES_BLOCK_SIZE];
+       pthread_t       tid[CIPHER_THREADS];
+       int             state;
+       int             qidx;
+       int             ridx;
+};
+
+/* <friedl>
+ * increment counter 'ctr',
+ * the counter is of size 'len' bytes and stored in network-byte-order.
+ * (LSB at ctr[len-1], MSB at ctr[0])
+ */
+static void
+ssh_ctr_inc(u_char *ctr, u_int len)
+{
+       int i;
+
+       for (i = len - 1; i >= 0; i--)
+               if (++ctr[i])   /* continue on overflow */
+                       return;
+}
+
+/*
+ * Add num to counter 'ctr'
+ */
+static void
+ssh_ctr_add(u_char *ctr, uint32_t num, u_int len)
+{
+       int i;
+       uint16_t n;
+
+       for (n = 0, i = len - 1; i >= 0 && (num || n); i--) {
+               n = ctr[i] + (num & 0xff) + n;
+               num >>= 8;
+               ctr[i] = n & 0xff;
+               n >>= 8;
+       }
+}
+
+/*
+ * Threads may be cancelled in a pthread_cond_wait, we must free the mutex
+ */
+static void
+thread_loop_cleanup(void *x)
+{
+       pthread_mutex_unlock((pthread_mutex_t *)x);
+}
+
+/*
+ * The life of a pregen thread:
+ *    Find empty keystream queues and fill them using their counter.
+ *    When done, update counter for the next fill.
+ */
+static void *
+thread_loop(void *x)
+{
+       AES_KEY key;
+       STATS_STRUCT(stats);
+       struct ssh_aes_ctr_ctx *c = x;
+       struct kq *q;
+       int i;
+       int qidx;
+
+       /* Threads stats on cancellation */
+       STATS_INIT(stats);
+#ifdef CIPHER_THREAD_STATS
+       pthread_cleanup_push(thread_loop_stats, &stats);
+#endif
+
+       /* Thread local copy of AES key */
+       memcpy(&key, &c->aes_ctx, sizeof(key));
+
+       /*
+        * Handle the special case of startup, one thread must fill
+        * the first KQ then mark it as draining. Lock held throughout.
+        */
+       if (pthread_equal(pthread_self(), c->tid[0])) {
+               q = &c->q[0];
+               pthread_mutex_lock(&q->lock);
+               if (q->qstate == KQINIT) {
+                       for (i = 0; i < KQLEN; i++) {
+                               AES_encrypt(q->ctr, q->keys[i], &key);
+                               ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE);
+                       }
+                       ssh_ctr_add(q->ctr, KQLEN * (NUMKQ - 1), AES_BLOCK_SIZE);
+                       q->qstate = KQDRAINING;
+                       STATS_FILL(stats);
+                       pthread_cond_broadcast(&q->cond);
+               }
+               pthread_mutex_unlock(&q->lock);
+       }
+       else 
+               STATS_SKIP(stats);
+
+       /*
+        * Normal case is to find empty queues and fill them, skipping over
+        * queues already filled by other threads and stopping to wait for
+        * a draining queue to become empty.
+        *
+        * Multiple threads may be waiting on a draining queue and awoken
+        * when empty.  The first thread to wake will mark it as filling,
+        * others will move on to fill, skip, or wait on the next queue.
+        */
+       for (qidx = 1;; qidx = (qidx + 1) % NUMKQ) {
+               /* Check if I was cancelled, also checked in cond_wait */
+               pthread_testcancel();
+
+               /* Lock queue and block if its draining */
+               q = &c->q[qidx];
+               pthread_mutex_lock(&q->lock);
+               pthread_cleanup_push(thread_loop_cleanup, &q->lock);
+               while (q->qstate == KQDRAINING || q->qstate == KQINIT) {
+                       STATS_WAIT(stats);
+                       pthread_cond_wait(&q->cond, &q->lock);
+               }
+               pthread_cleanup_pop(0);
+
+               /* If filling or full, somebody else got it, skip */
+               if (q->qstate != KQEMPTY) {
+                       pthread_mutex_unlock(&q->lock);
+                       STATS_SKIP(stats);
+                       continue;
+               }
+
+               /*
+                * Empty, let's fill it.
+                * Queue lock is relinquished while we do this so others
+                * can see that it's being filled.
+                */
+               q->qstate = KQFILLING;
+               pthread_mutex_unlock(&q->lock);
+               for (i = 0; i < KQLEN; i++) {
+                       AES_encrypt(q->ctr, q->keys[i], &key);
+                       ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE);
+               }
+
+               /* Re-lock, mark full and signal consumer */
+               pthread_mutex_lock(&q->lock);
+               ssh_ctr_add(q->ctr, KQLEN * (NUMKQ - 1), AES_BLOCK_SIZE);
+               q->qstate = KQFULL;
+               STATS_FILL(stats);
+               pthread_cond_signal(&q->cond);
+               pthread_mutex_unlock(&q->lock);
+       }
+
+#ifdef CIPHER_THREAD_STATS
+       /* Stats */
+       pthread_cleanup_pop(1);
+#endif
+
+       return NULL;
+}
+
+static int
+ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
+    u_int len)
+{
+       struct ssh_aes_ctr_ctx *c;
+       struct kq *q, *oldq;
+       int ridx;
+       u_char *buf;
+
+       if (len == 0)
+               return (1);
+       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
+               return (0);
+
+       q = &c->q[c->qidx];
+       ridx = c->ridx;
+
+       /* src already padded to block multiple */
+       while (len > 0) {
+               buf = q->keys[ridx];
+
+#ifdef CIPHER_BYTE_XOR
+               dest[0] = src[0] ^ buf[0];
+               dest[1] = src[1] ^ buf[1];
+               dest[2] = src[2] ^ buf[2];
+               dest[3] = src[3] ^ buf[3];
+               dest[4] = src[4] ^ buf[4];
+               dest[5] = src[5] ^ buf[5];
+               dest[6] = src[6] ^ buf[6];
+               dest[7] = src[7] ^ buf[7];
+               dest[8] = src[8] ^ buf[8];
+               dest[9] = src[9] ^ buf[9];
+               dest[10] = src[10] ^ buf[10];
+               dest[11] = src[11] ^ buf[11];
+               dest[12] = src[12] ^ buf[12];
+               dest[13] = src[13] ^ buf[13];
+               dest[14] = src[14] ^ buf[14];
+               dest[15] = src[15] ^ buf[15];
+#else
+               *(uint64_t *)dest = *(uint64_t *)src ^ *(uint64_t *)buf;
+               *(uint64_t *)(dest + 8) = *(uint64_t *)(src + 8) ^
+                                               *(uint64_t *)(buf + 8);
+#endif
+
+               dest += 16;
+               src += 16;
+               len -= 16;
+               ssh_ctr_inc(ctx->iv, AES_BLOCK_SIZE);
+
+               /* Increment read index, switch queues on rollover */
+               if ((ridx = (ridx + 1) % KQLEN) == 0) {
+                       oldq = q;
+
+                       /* Mark next queue draining, may need to wait */
+                       c->qidx = (c->qidx + 1) % NUMKQ;
+                       q = &c->q[c->qidx];
+                       pthread_mutex_lock(&q->lock);
+                       while (q->qstate != KQFULL) {
+                               STATS_WAIT(c->stats);
+                               pthread_cond_wait(&q->cond, &q->lock);
+                       }
+                       q->qstate = KQDRAINING;
+                       pthread_mutex_unlock(&q->lock);
+
+                       /* Mark consumed queue empty and signal producers */
+                       pthread_mutex_lock(&oldq->lock);
+                       oldq->qstate = KQEMPTY;
+                       STATS_DRAIN(c->stats);
+                       pthread_cond_broadcast(&oldq->cond);
+                       pthread_mutex_unlock(&oldq->lock);
+               }
+       }
+       c->ridx = ridx;
+       return (1);
+}
+
+#define HAVE_NONE       0
+#define HAVE_KEY        1
+#define HAVE_IV         2
+static int
+ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
+    int enc)
+{
+       struct ssh_aes_ctr_ctx *c;
+       int i;
+
+       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
+               c = xmalloc(sizeof(*c));
+
+               c->state = HAVE_NONE;
+               for (i = 0; i < NUMKQ; i++) {
+                       pthread_mutex_init(&c->q[i].lock, NULL);
+                       pthread_cond_init(&c->q[i].cond, NULL);
+               }
+
+               STATS_INIT(c->stats);
+               
+               EVP_CIPHER_CTX_set_app_data(ctx, c);
+       }
+
+       if (c->state == (HAVE_KEY | HAVE_IV)) {
+               /* Cancel pregen threads */
+               for (i = 0; i < CIPHER_THREADS; i++)
+                       pthread_cancel(c->tid[i]);
+               for (i = 0; i < CIPHER_THREADS; i++)
+                       pthread_join(c->tid[i], NULL);
+               /* Start over getting key & iv */
+               c->state = HAVE_NONE;
+       }
+
+       if (key != NULL) {
+               AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                   &c->aes_ctx);
+               c->state |= HAVE_KEY;
+       }
+
+       if (iv != NULL) {
+               memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
+               c->state |= HAVE_IV;
+       }
+
+       if (c->state == (HAVE_KEY | HAVE_IV)) {
+               /* Clear queues */
+               memcpy(c->q[0].ctr, ctx->iv, AES_BLOCK_SIZE);
+               c->q[0].qstate = KQINIT;
+               for (i = 1; i < NUMKQ; i++) {
+                       memcpy(c->q[i].ctr, ctx->iv, AES_BLOCK_SIZE);
+                       ssh_ctr_add(c->q[i].ctr, i * KQLEN, AES_BLOCK_SIZE);
+                       c->q[i].qstate = KQEMPTY;
+               }
+               c->qidx = 0;
+               c->ridx = 0;
+
+               /* Start threads */
+               for (i = 0; i < CIPHER_THREADS; i++) {
+                       pthread_create(&c->tid[i], NULL, thread_loop, c);
+               }
+               pthread_mutex_lock(&c->q[0].lock);
+               while (c->q[0].qstate != KQDRAINING)
+                       pthread_cond_wait(&c->q[0].cond, &c->q[0].lock);
+               pthread_mutex_unlock(&c->q[0].lock);
+               
+       }
+       return (1);
+}
+
+static int
+ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
+{
+       struct ssh_aes_ctr_ctx *c;
+       int i;
+
+       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
+#ifdef CIPHER_THREAD_STATS
+               debug("main thread: %u drains, %u waits", c->stats.drains,
+                               c->stats.waits);
+#endif
+               /* Cancel pregen threads */
+               for (i = 0; i < CIPHER_THREADS; i++)
+                       pthread_cancel(c->tid[i]);
+               for (i = 0; i < CIPHER_THREADS; i++)
+                       pthread_join(c->tid[i], NULL);
+
+               memset(c, 0, sizeof(*c));
+               xfree(c);
+               EVP_CIPHER_CTX_set_app_data(ctx, NULL);
+       }
+       return (1);
+}
+
+/* <friedl> */
+const EVP_CIPHER *
+evp_aes_ctr_mt(void)
+{
+       static EVP_CIPHER aes_ctr;
+
+       memset(&aes_ctr, 0, sizeof(EVP_CIPHER));
+       aes_ctr.nid = NID_undef;
+       aes_ctr.block_size = AES_BLOCK_SIZE;
+       aes_ctr.iv_len = AES_BLOCK_SIZE;
+       aes_ctr.key_len = 16;
+       aes_ctr.init = ssh_aes_ctr_init;
+       aes_ctr.cleanup = ssh_aes_ctr_cleanup;
+       aes_ctr.do_cipher = ssh_aes_ctr;
+#ifndef SSH_OLD_EVP
+       aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
+           EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
+#endif
+       return (&aes_ctr);
+}
index ddbf97c6b1486138f0da5d18d16ba6301fd622b8..75512922e4f080d9b3cac51a6924b20e00d5b66c 100644 (file)
@@ -55,6 +55,7 @@ extern const EVP_CIPHER *evp_ssh1_bf(void);
 extern const EVP_CIPHER *evp_ssh1_3des(void);
 extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
 extern const EVP_CIPHER *evp_aes_128_ctr(void);
+extern const EVP_CIPHER *evp_aes_ctr_mt(void);
 extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
 
 struct Cipher {
@@ -81,9 +82,9 @@ struct Cipher {
        { "aes256-cbc",         SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc },
        { "rijndael-cbc@lysator.liu.se",
                                SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc },
-       { "aes128-ctr",         SSH_CIPHER_SSH2, 16, 16, 0, evp_aes_128_ctr },
-       { "aes192-ctr",         SSH_CIPHER_SSH2, 16, 24, 0, evp_aes_128_ctr },
-       { "aes256-ctr",         SSH_CIPHER_SSH2, 16, 32, 0, evp_aes_128_ctr },
+       { "aes128-ctr",         SSH_CIPHER_SSH2, 16, 16, 0, evp_aes_ctr_mt },
+       { "aes192-ctr",         SSH_CIPHER_SSH2, 16, 24, 0, evp_aes_ctr_mt },
+       { "aes256-ctr",         SSH_CIPHER_SSH2, 16, 32, 0, evp_aes_ctr_mt },
 #ifdef USE_CIPHER_ACSS
        { "acss@openssh.org",   SSH_CIPHER_SSH2, 16, 5, 0, EVP_acss },
 #endif
index d2fa82925368856b925c3e8d183da2117464adc3..26331719311d4b944332ed0f43811ef07a347605 100644 (file)
@@ -48,6 +48,7 @@
 #include "match.h"
 #include "dispatch.h"
 #include "monitor.h"
+#include "canohost.h"
 
 #ifdef GSSAPI
 #include "ssh-gss.h"
@@ -395,6 +396,7 @@ kex_choose_conf(Kex *kex)
        int nenc, nmac, ncomp;
        u_int mode, ctos, need;
        int first_kex_follows, type;
+       int log_flag = 0;
 
        int auth_flag;
 
@@ -439,6 +441,20 @@ kex_choose_conf(Kex *kex)
                    newkeys->enc.name,
                    newkeys->mac.name,
                    newkeys->comp.name);
+               /* client starts withctos = 0 && log flag = 0 and no log*/
+               /* 2nd client pass ctos=1 and flag = 1 so no log*/
+               /* server starts with ctos =1 && log_flag = 0 so log */
+               /* 2nd sever pass ctos = 1 && log flag = 1 so no log*/
+               /* -cjr*/
+               if (ctos && !log_flag) {
+                       logit("SSH: Server;Ltype: Kex;Remote: %s-%d;Enc: %s;MAC: %s;Comp: %s",
+                             get_remote_ipaddr(),
+                             get_remote_port(),
+                             newkeys->enc.name,
+                             newkeys->mac.name,
+                             newkeys->comp.name);
+               }
+               log_flag = 1;
        }
        choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]);
        choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
index ff83651e8bcb030014da396e200da9753089ab10..cab44bcd79420e1444128c1bf0de38aa7888a754 100644 (file)
@@ -710,7 +710,7 @@ packet_enable_delayed_compress(void)
 /*
  * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
  */
-static void
+static int
 packet_send2_wrapped(void)
 {
        u_char type, *cp, *macbuf = NULL;
@@ -822,11 +822,13 @@ packet_send2_wrapped(void)
                set_newkeys(MODE_OUT);
        else if (type == SSH2_MSG_USERAUTH_SUCCESS && server_side)
                packet_enable_delayed_compress();
+       return(packet_length);
 }
 
-static void
+static int
 packet_send2(void)
 {
+        static int packet_length = 0;
        static int rekeying = 0;
        struct packet *p;
        u_char type, *cp;
@@ -844,7 +846,7 @@ packet_send2(void)
                        memcpy(&p->payload, &outgoing_packet, sizeof(Buffer));
                        buffer_init(&outgoing_packet);
                        TAILQ_INSERT_TAIL(&outgoing, p, next);
-                       return;
+                       return(sizeof(Buffer));
                }
        }
 
@@ -852,7 +854,7 @@ packet_send2(void)
        if (type == SSH2_MSG_KEXINIT)
                rekeying = 1;
 
-       packet_send2_wrapped();
+       packet_length = packet_send2_wrapped();
 
        /* after a NEWKEYS message we can send the complete queue */
        if (type == SSH2_MSG_NEWKEYS) {
@@ -865,19 +867,22 @@ packet_send2(void)
                            sizeof(Buffer));
                        TAILQ_REMOVE(&outgoing, p, next);
                        xfree(p);
-                       packet_send2_wrapped();
+                       packet_length += packet_send2_wrapped();
                }
        }
+       return(packet_length);
 }
 
-void
+int
 packet_send(void)
 {
+  int packet_len = 0;
        if (compat20)
-               packet_send2();
+               packet_len = packet_send2();
        else
                packet_send1();
        DBG(debug("packet_send done"));
+       return(packet_len);
 }
 
 /*
@@ -1415,21 +1420,23 @@ packet_disconnect(const char *fmt,...)
 
 /* Checks if there is any buffered output, and tries to write some of the output. */
 
-void
+int
 packet_write_poll(void)
 {
-       int len = buffer_len(&output);
+       int len = 0;
+       len = buffer_len(&output);
 
        if (len > 0) {
                len = write(connection_out, buffer_ptr(&output), len);
                if (len <= 0) {
                        if (errno == EAGAIN)
-                               return;
+                         return (0);
                        else
                                fatal("Write failed: %.100s", strerror(errno));
                }
                buffer_consume(&output, len);
        }
+       return(len);
 }
 
 /*
@@ -1437,14 +1444,15 @@ packet_write_poll(void)
  * written.
  */
 
-void
+int
 packet_write_wait(void)
 {
        fd_set *setp;
+       u_int bytes_sent = 0;
 
        setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS),
            sizeof(fd_mask));
-       packet_write_poll();
+       bytes_sent += packet_write_poll();
        while (packet_have_data_to_write()) {
                memset(setp, 0, howmany(connection_out + 1, NFDBITS) *
                    sizeof(fd_mask));
@@ -1452,9 +1460,10 @@ packet_write_wait(void)
                while (select(connection_out + 1, NULL, setp, NULL, NULL) == -1 &&
                    (errno == EAGAIN || errno == EINTR))
                        ;
-               packet_write_poll();
+               bytes_sent += packet_write_poll();
        }
        xfree(setp);
+       return (bytes_sent);
 }
 
 /* Returns true if there is buffered data to write to the connection. */
index 4a7b529173e184425a3d25f113ab3ef602f27ce5..caf8c46f58083fc86f2bf3c4cd290cecfaeee191 100644 (file)
@@ -47,7 +47,7 @@ void     packet_put_bignum2(BIGNUM * value);
 void     packet_put_string(const void *buf, u_int len);
 void     packet_put_cstring(const char *str);
 void     packet_put_raw(const void *buf, u_int len);
-void     packet_send(void);
+int      packet_send(void);
 
 int      packet_read(void);
 void     packet_read_expect(int type);
@@ -75,8 +75,8 @@ void   packet_set_state(int, u_int32_t, u_int64_t, u_int32_t);
 int     packet_get_ssh1_cipher(void);
 void    packet_set_iv(int, u_char *);
 
-void     packet_write_poll(void);
-void     packet_write_wait(void);
+int      packet_write_poll(void);
+int      packet_write_wait(void);
 int      packet_have_data_to_write(void);
 int      packet_not_very_much_data_to_write(void);
 
index 289f806a39c5438d8621c86aab160f374ad3aad3..e66e0a98d47f183ae9a65624b9cda0a169b77959 100644 (file)
@@ -92,10 +92,10 @@ static int fdin;            /* Descriptor for stdin (for writing) */
 static int fdout;              /* Descriptor for stdout (for reading);
                                   May be same number as fdin. */
 static int fderr;              /* Descriptor for stderr.  May be -1. */
-static long stdin_bytes = 0;   /* Number of bytes written to stdin. */
-static long stdout_bytes = 0;  /* Number of stdout bytes sent to client. */
-static long stderr_bytes = 0;  /* Number of stderr bytes sent to client. */
-static long fdout_bytes = 0;   /* Number of stdout bytes read from program. */
+static u_long stdin_bytes = 0; /* Number of bytes written to stdin. */
+static u_long stdout_bytes = 0;        /* Number of stdout bytes sent to client. */
+static u_long stderr_bytes = 0;        /* Number of stderr bytes sent to client. */
+static u_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. */
@@ -119,6 +119,20 @@ static volatile sig_atomic_t received_sigterm = 0;
 /* prototypes */
 static void server_init_dispatch(void);
 
+/*
+ * Returns current time in seconds from Jan 1, 1970 with the maximum
+ * available resolution.
+ */
+
+static double
+get_current_time(void)
+{
+       struct timeval tv;
+       gettimeofday(&tv, NULL);
+       return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0;
+}
+
+
 /*
  * we write to this pipe if a SIGCHLD is caught in order to avoid
  * the race between select() and child_terminated
@@ -408,6 +422,7 @@ process_input(fd_set *readset)
                } else {
                        /* Buffer any received data. */
                        packet_process_incoming(buf, len);
+                       fdout_bytes += len;
                }
        }
        if (compat20)
@@ -430,6 +445,7 @@ process_input(fd_set *readset)
                } else {
                        buffer_append(&stdout_buffer, buf, len);
                        fdout_bytes += len;
+                       debug ("FD out now: %ld", fdout_bytes);
                }
        }
        /* Read and buffer any available stderr data from the program. */
@@ -496,7 +512,7 @@ process_output(fd_set *writeset)
        }
        /* Send any buffered packet data to the client. */
        if (FD_ISSET(connection_out, writeset))
-               packet_write_poll();
+               stdin_bytes += packet_write_poll();
 }
 
 /*
@@ -813,8 +829,10 @@ server_loop2(Authctxt *authctxt)
 {
        fd_set *readset = NULL, *writeset = NULL;
        int rekeying = 0, max_fd, nalloc = 0;
+       double start_time, total_time;
 
        debug("Entering interactive session for SSH2.");
+       start_time = get_current_time();
 
        mysignal(SIGCHLD, sigchld_handler);
        child_terminated = 0;
@@ -876,6 +894,11 @@ server_loop2(Authctxt *authctxt)
 
        /* free remaining sessions, e.g. remove wtmp entries */
        session_destroy_all(NULL);
+       total_time = get_current_time() - start_time;
+       logit("SSH: Server;LType: Throughput;Remote: %s-%d;IN: %lu;OUT: %lu;Duration: %.1f;tPut_in: %.1f;tPut_out: %.1f",
+             get_remote_ipaddr(), get_remote_port(),
+             stdin_bytes, fdout_bytes, total_time, stdin_bytes / total_time, 
+             fdout_bytes / total_time);
 }
 
 static void
index 3be9a48bc15161d04685afac1557d565d931d4f0..0a3a549f2cc16f2d5891da856219659fc71b1198 100644 (file)
@@ -477,6 +477,9 @@ sshd_exchange_identification(int sock_in, int sock_out)
        }
        debug("Client protocol version %d.%d; client software version %.100s",
            remote_major, remote_minor, remote_version);
+       logit("SSH: Server;Ltype: Version;Remote: %s-%d;Protocol: %d.%d;Client: %.100s",
+             get_remote_ipaddr(), get_remote_port(),
+           remote_major, remote_minor, remote_version);
 
        compat_datafellows(remote_version);
 
index 492090611a52b55696cc38a4731b3228daa4572c..a4c9f79b678de3810c0025c7d100b02dff45fd9c 100644 (file)
@@ -23,6 +23,6 @@
 #define SSH_VERSION    "OpenSSH_4.7"
 
 #define SSH_PORTABLE   "p1"
-#define SSH_HPN         "-hpn12v20"
+#define SSH_HPN         "-hpn13v1"
 #define SSH_RELEASE    SSH_VERSION SSH_PORTABLE SSH_HPN \
             NCSA_VERSION GSI_VERSION KRB5_VERSION MGLUE_VERSION
This page took 0.092509 seconds and 5 git commands to generate.