<pre style='margin:0'>
Christopher Nielsen (mascguy) pushed a commit to branch master
in repository macports-ports.

</pre>
<p><a href="https://github.com/macports/macports-ports/commit/6ee0b7b4a2d271f047b5624e981c9b334577a67b">https://github.com/macports/macports-ports/commit/6ee0b7b4a2d271f047b5624e981c9b334577a67b</a></p>
<pre style="white-space: pre; background: #F8F8F8">The following commit(s) were added to refs/heads/master by this push:
<span style='display:block; white-space:pre;color:#404040;'>     new 6ee0b7b4a2d openssh: update to version 9.0p1
</span>6ee0b7b4a2d is described below

<span style='display:block; white-space:pre;color:#808000;'>commit 6ee0b7b4a2d271f047b5624e981c9b334577a67b
</span>Author: グレェ <artkiver@gmail.com>
AuthorDate: Mon Apr 11 04:56:27 2022 +0000

<span style='display:block; white-space:pre;color:#404040;'>    openssh: update to version 9.0p1
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    * Also removed deprecated gsskex and HPN variant references and patch files.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Closes: https://trac.macports.org/ticket/64982
</span><span style='display:block; white-space:pre;color:#404040;'>    Closes: https://trac.macports.org/ticket/64748
</span>---
 net/openssh/Portfile                               |   19 +-
 .../openssh-8.1p1-hpnssh14v18-openssl-1.1.diff     |   77 -
 net/openssh/files/openssh-8.1p1-hpnssh14v18.diff   | 2458 ------------
 net/openssh/files/openssh-8.8p1-gsskex.patch       | 4033 --------------------
 net/openssh/files/series-gsskex                    |    8 -
 net/openssh/files/series-hpn                       |    9 -
 6 files changed, 4 insertions(+), 6600 deletions(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/net/openssh/Portfile b/net/openssh/Portfile
</span><span style='display:block; white-space:pre;color:#808080;'>index 873a05bdc61..618ff4f82c2 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/net/openssh/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/net/openssh/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -5,7 +5,7 @@ PortSystem          1.0
</span> PortGroup           compiler_blacklist_versions 1.0
 
 name                openssh
<span style='display:block; white-space:pre;background:#ffe0e0;'>-version             8.9p1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+version             9.0p1
</span> revision            3
 categories          net
 platforms           darwin
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -29,9 +29,9 @@ long_description    OpenSSH is a FREE version of the SSH protocol suite of \
</span> 
 homepage            https://www.openbsd.org/openssh/
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-checksums           rmd160  6fcc50d852586bae60eb22c86c7bc9c7ef358e91 \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    sha256  fd497654b7ab1686dac672fb83dfb4ba4096e8b5ffcdaccd262380ae58bec5e7 \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    size    1820282
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+checksums           rmd160  5c79f179c25c8fe0c319d9a08d4b534147184402 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    sha256  03974302161e9ecce32153cfa10012f1e65c8f3750f573a73ab1befd5972a28a \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    size    1822183
</span> 
 master_sites        openbsd:OpenSSH/portable \
                     ftp://ftp.cise.ufl.edu/pub/mirrors/openssh/portable/ \
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -160,17 +160,6 @@ if {${name} eq ${subport}} {
</span>         depends_run-append      port:xauth
     }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    variant gsskex requires kerberos5 description "Add OpenSSH GSSAPI key exchange patch" {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        patchfiles-append       openssh-8.8p1-gsskex.patch
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        configure.ldflags-append \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                                -Wl,-pie
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        configure.cflags-append -fPIE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        configure.args-append   --with-4in6 \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                                --disable-utmp \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                                --disable-wtmp \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                                --with-privsep-user=_sshd
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     variant kerberos5 description "Add Kerberos5 support" {
         depends_lib-append      port:kerberos5
         configure.args-delete   --without-kerberos5
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/net/openssh/files/openssh-8.1p1-hpnssh14v18-openssl-1.1.diff b/net/openssh/files/openssh-8.1p1-hpnssh14v18-openssl-1.1.diff
</span>deleted file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 91cf3c64f69..00000000000
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/net/openssh/files/openssh-8.1p1-hpnssh14v18-openssl-1.1.diff
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,77 +0,0 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/cipher-ctr-mt.c      2019-10-12 06:16:38.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/cipher-ctr-mt.c      2019-10-12 06:16:40.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -434,7 +434,7 @@ ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           destp.u += AES_BLOCK_SIZE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           srcp.u += AES_BLOCK_SIZE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           len -= AES_BLOCK_SIZE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          ssh_ctr_inc(ctx->iv, AES_BLOCK_SIZE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           /* Increment read index, switch queues on rollover */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           if ((ridx = (ridx + 1) % KQLEN) == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -547,16 +547,16 @@ ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, co
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (iv != NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          memcpy(c->aes_counter, iv, AES_BLOCK_SIZE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           c->state |= HAVE_IV;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (c->state == (HAVE_KEY | HAVE_IV)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           /* Clear queues */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          memcpy(c->q[0].ctr, ctx->iv, AES_BLOCK_SIZE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          memcpy(c->q[0].ctr, c->aes_counter, AES_BLOCK_SIZE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           c->q[0].qstate = KQINIT;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           for (i = 1; i < numkq; i++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                  memcpy(c->q[i].ctr, ctx->iv, AES_BLOCK_SIZE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  memcpy(c->q[i].ctr, c->aes_counter, AES_BLOCK_SIZE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   ssh_ctr_add(c->q[i].ctr, i * KQLEN, AES_BLOCK_SIZE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   c->q[i].qstate = KQEMPTY;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -640,6 +640,21 @@ ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- const EVP_CIPHER *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- evp_aes_ctr_mt(void)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# if OPENSSL_VERSION_NUMBER >= 0x10100000UL
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  static EVP_CIPHER *aes_ctr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  aes_ctr = EVP_CIPHER_meth_new(NID_undef, 16/*block*/, 16/*key*/);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  EVP_CIPHER_meth_set_iv_length(aes_ctr, AES_BLOCK_SIZE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  EVP_CIPHER_meth_set_init(aes_ctr, ssh_aes_ctr_init);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  EVP_CIPHER_meth_set_cleanup(aes_ctr, ssh_aes_ctr_cleanup);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  EVP_CIPHER_meth_set_do_cipher(aes_ctr, ssh_aes_ctr);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#  ifndef SSH_OLD_EVP
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  EVP_CIPHER_meth_set_flags(aes_ctr, EVP_CIPH_CBC_MODE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                | EVP_CIPH_VARIABLE_LENGTH
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                | EVP_CIPH_ALWAYS_CALL_INIT
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                | EVP_CIPH_CUSTOM_IV);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#  endif /*SSH_OLD_EVP*/
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return (aes_ctr);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# else /*earlier version of openssl*/
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   static EVP_CIPHER aes_ctr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   memset(&aes_ctr, 0, sizeof(EVP_CIPHER));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -655,6 +670,7 @@ evp_aes_ctr_mt(void)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return &aes_ctr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# endif /*OPENSSH_VERSION_NUMBER*/
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif /* defined(WITH_OPENSSL) */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/cipher.c     2019-10-12 06:16:38.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/cipher.c     2019-10-12 06:16:40.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -329,7 +329,13 @@ cipher_init(struct sshcipher_ctx **ccp, 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   goto out;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#if OPENSSH_VERSION_NUMBER <= 0x10100000UL
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* in OpenSSL 1.1.0, EVP_CipherInit clears all previous setups;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+     use EVP_CipherInit_ex for augmenting */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (EVP_CipherInit_ex(cc->evp, NULL, NULL, (u_char *)key, NULL, -1) == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (EVP_CipherInit(cc->evp, NULL, (u_char *)key, NULL, -1) == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           ret = SSH_ERR_LIBCRYPTO_ERROR;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           goto out;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/net/openssh/files/openssh-8.1p1-hpnssh14v18.diff b/net/openssh/files/openssh-8.1p1-hpnssh14v18.diff
</span>deleted file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 27152286d58..00000000000
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/net/openssh/files/openssh-8.1p1-hpnssh14v18.diff
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,2458 +0,0 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- /dev/null      1970-01-01 00:00:00.000000000 +0000
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/HPN-README   2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,130 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Notes:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+MULTI-THREADED CIPHER:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+The AES cipher in CTR mode has been multithreaded (MTR-AES-CTR). This will allow ssh installations
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+on hosts with multiple cores to use more than one processing core during encryption.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Tests have show significant throughput performance increases when using MTR-AES-CTR up
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+to and including a full gigabit per second on quad core systems. It should be possible to
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+achieve full line rate on dual core systems but OS and data management overhead makes this
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+more difficult to achieve. The cipher stream from MTR-AES-CTR is entirely compatible with single
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+thread AES-CTR (ST-AES-CTR) implementations and should be 100% backward compatible. Optimal
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+performance requires the MTR-AES-CTR mode be enabled on both ends of the connection.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+The MTR-AES-CTR replaces ST-AES-CTR and is used in exactly the same way with the same
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+nomenclature.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Use examples:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh -caes128-ctr you@host.com
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          scp -oCipher=aes256-ctr file you@host.com:~/file
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+NONE CIPHER:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+To use the NONE option you must have the NoneEnabled switch set on the server and
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+you *must* have *both* NoneEnabled and NoneSwitch set to yes on the client. The NONE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+feature works with ALL ssh subsystems (as far as we can tell) *AS LONG AS* a tty is not
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+spawned. If a user uses the -T switch to prevent a tty being created the NONE cipher will
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+be disabled.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+The performance increase will only be as good as the network and TCP stack tuning
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+on the reciever side of the connection allows. As a rule of thumb a user will need
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+at least 10Mb/s connection with a 100ms RTT to see a doubling of performance. The
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+HPN-SSH home page describes this in greater detail.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+http://www.psc.edu/networking/projects/hpn-ssh
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+BUFFER SIZES:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+If HPN is disabled the receive buffer size will be set to the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+OpenSSH default of 64K.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+If an HPN system connects to a nonHPN system the receive buffer will
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+be set to the HPNBufferSize value. The default is 2MB but user adjustable.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+If an HPN to HPN connection is established a number of different things might
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+happen based on the user options and conditions.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+HPN Buffer Size = up to 64MB
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+This is the default state. The HPN buffer size will grow to a maximum of 64MB
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+as the TCP receive buffer grows. The maximum HPN Buffer size of 64MB is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+geared towards 10GigE transcontinental connections.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+HPN Buffer Size = TCP receive buffer value.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Users on non-autotuning systems should disable TCPRcvBufPoll in the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_config and sshd_config
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+HPN Buffer Size = minimum of TCP receive buffer and HPNBufferSize.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+This would be the system defined TCP receive buffer (RWIN).
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf SET
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+HPN Buffer Size = minimum of TCPRcvBuf and HPNBufferSize.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Generally there is no need to set both.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+HPN Buffer Size = grows to HPNBufferSize
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+The buffer will grow up to the maximum size specified here.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf SET
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+HPN Buffer Size = minimum of TCPRcvBuf and HPNBufferSize.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Generally there is no need to set both of these, especially on autotuning
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+systems. However, if the users wishes to override the autotuning this would be
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+one way to do it.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf SET
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+HPN Buffer Size = TCPRcvBuf.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+This will override autotuning and set the TCP recieve buffer to the user defined
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+value.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+HPN Specific Configuration options
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+TcpRcvBuf=[int]KB client
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      set the TCP socket receive buffer to n Kilobytes. It can be set up to the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+maximum socket size allowed by the system. This is useful in situations where
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+the tcp receive window is set low but the maximum buffer size is set
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+higher (as is typical). This works on a per TCP connection basis. You can also
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+use this to artifically limit the transfer rate of the connection. In these
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+cases the throughput will be no more than n/RTT. The minimum buffer size is 1KB.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Default is the current system wide tcp receive buffer size.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+TcpRcvBufPoll=[yes/no] client/server
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      enable of disable the polling of the tcp receive buffer through the life
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+of the connection. You would want to make sure that this option is enabled
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+for systems making use of autotuning kernels (linux 2.4.24+, 2.6, MS Vista)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+default is yes.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+NoneEnabled=[yes/no] client/server
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      enable or disable the use of the None cipher. Care must always be used
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+when enabling this as it will allow users to send data in the clear. However,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+it is important to note that authentication information remains encrypted
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+even if this option is enabled. Set to no by default.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+NoneSwitch=[yes/no] client
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+     Switch the encryption cipher being used to the None cipher after
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+authentication takes place. NoneEnabled must be enabled on both the client
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+and server side of the connection. When the connection switches to the NONE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+cipher a warning is sent to STDERR. The connection attempt will fail with an
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+error if a client requests a NoneSwitch from the server that does not explicitly
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+have NoneEnabled set to yes. Note: The NONE cipher cannot be used in
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+interactive (shell) sessions and it will fail silently. Set to no by default.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+HPNDisabled=[yes/no] client/server
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+     In some situations, such as transfers on a local area network, the impact
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+of the HPN code produces a net decrease in performance. In these cases it is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+helpful to disable the HPN functionality. By default HPNDisabled is set to no.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+HPNBufferSize=[int]KB client/server
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+     This is the default buffer size the HPN functionality uses when interacting
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+with nonHPN SSH installations. Conceptually this is similar to the TcpRcvBuf
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+option as applied to the internal SSH flow control. This value can range from
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+1KB to 64MB (1-65536). Use of oversized or undersized buffers can cause performance
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+problems depending on the length of the network path. The default size of this buffer
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+is 2MB.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Credits: This patch was conceived, designed, and led by Chris Rapier (rapier@psc.edu)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+         The majority of the actual coding for versions up to HPN12v1 was performed
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+         by Michael Stevens (mstevens@andrew.cmu.edu). The MT-AES-CTR cipher was
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+         implemented by Ben Bennet (ben@psc.edu) and improved by Mike Tasota
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+         (tasota@gmail.com) an NSF REU grant recipient for 2013.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+         This work was financed, in part, by Cisco System, Inc., the National
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+         Library of Medicine, and the National Science Foundation.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/Makefile.in  2019-11-08 15:37:33.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/Makefile.in  2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -43,7 +43,7 @@ LD=@LD@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- CFLAGS=@CFLAGS@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- OBJCFLAGS=@OBJCFLAGS@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--LIBS=@LIBS@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+LIBS=@LIBS@ -lpthread
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- K5LIBS=@K5LIBS@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- GSSLIBS=@GSSLIBS@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- SSHLIBS=@SSHLIBS@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -88,7 +88,7 @@ LIBOPENSSH_OBJS=\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   authfd.o authfile.o \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.o \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  cipher-ctr.o cleanup.o \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  cipher-ctr.o cleanup.o cipher-ctr-mt.o \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   compat.o fatal.o hostfile.o \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   log.o match.o moduli.o nchan.o packet.o \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   readpass.o ttymodes.o xmalloc.o addrmatch.o \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/auth2.c      2019-11-08 15:37:33.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/auth2.c      2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -58,6 +58,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "monitor_wrap.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "digest.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "canohost.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* import */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- extern ServerOptions options;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -76,6 +77,8 @@ extern Authmethod method_hostbased;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- extern Authmethod method_gssapi;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static int log_flag = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- Authmethod *authmethods[] = {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   &method_none,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   &method_pubkey,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -275,6 +278,11 @@ input_userauth_request(int type, u_int32
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           goto out;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   debug("userauth-request for user %s service %s method %s", user, service, method);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!log_flag) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          logit("SSH: Server;Ltype: Authname;Remote: %s-%d;Name: %s",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), user);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          log_flag = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if ((style = strchr(user, ':')) != NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/canohost.h   2019-10-09 02:31:03.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/canohost.h   2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -19,7 +19,7 @@ char             *get_peer_ipaddr(int);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int                get_peer_port(int);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- char              *get_local_ipaddr(int);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- char              *get_local_name(int);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--int               get_local_port(int);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int                get_local_port(int);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif /* _CANOHOST_H */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/channels.c   2019-11-08 14:18:24.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/channels.c   2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -220,6 +220,9 @@ static int rdynamic_connect_finish(struc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* Setup helper */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static void channel_handler_init(struct ssh_channels *sc);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static int hpn_disabled = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static int hpn_buffer_size = 2 * 1024 * 1024;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* -- channel core */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -392,6 +395,7 @@ channel_new(struct ssh *ssh, char *ctype
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   c->local_window = window;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   c->local_window_max = window;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   c->local_maxpacket = maxpack;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  c->dynamic_window = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   c->remote_name = xstrdup(remote_name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   c->ctl_chan = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   c->delayed = 1;              /* prevent call to channel_post handler */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1079,6 +1083,28 @@ channel_pre_connecting(struct ssh *ssh, 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   FD_SET(c->sock, writeset);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+channel_tcpwinsz(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_int32_t tcpwinsz = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  socklen_t optsz = sizeof(tcpwinsz);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int ret = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* if we aren't on a socket return 128KB */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!ssh_packet_connection_is_on_socket(ssh))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return 128 * 1024;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ret = getsockopt(ssh_packet_get_connection_in(ssh),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                   SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* return no more than SSHBUF_SIZE_MAX (currently 256MB) */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((ret == 0) && tcpwinsz > SSHBUF_SIZE_MAX)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          tcpwinsz = SSHBUF_SIZE_MAX;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  debug2("tcpwinsz: tcp connection %d, Receive window: %d",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+         ssh_packet_get_connection_in(ssh), tcpwinsz);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return tcpwinsz;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- channel_pre_open(struct ssh *ssh, Channel *c,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     fd_set *readset, fd_set *writeset)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2178,21 +2204,30 @@ channel_check_window(struct ssh *ssh, Ch
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       c->local_maxpacket*3) ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       c->local_window < c->local_window_max/2) &&
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       c->local_consumed > 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          u_int addition = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          u_int32_t tcpwinsz = channel_tcpwinsz(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* adjust max window size if we are in a dynamic environment */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (c->dynamic_window && (tcpwinsz > c->local_window_max)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* grow the window somewhat aggressively to maintain pressure */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  addition = 1.5 * (tcpwinsz - c->local_window_max);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  c->local_window_max += addition;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug("Channel: Window growth to %d by %d bytes", c->local_window_max, addition);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           if (!c->have_remote_id)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   fatal(":%s: channel %d: no remote id",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                       __func__, c->self);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           if ((r = sshpkt_start(ssh,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-               SSH2_MSG_CHANNEL_WINDOW_ADJUST)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-               (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--              (r = sshpkt_put_u32(ssh, c->local_consumed)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              (r = sshpkt_put_u32(ssh, c->local_consumed + addition)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-               (r = sshpkt_send(ssh)) != 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   fatal("%s: channel %i: %s", __func__,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                       c->self, ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           debug2("channel %d: window %d sent adjust %d",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-               c->self, c->local_window,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--              c->local_consumed);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          c->local_window += c->local_consumed;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              c->local_consumed + addition);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          c->local_window += c->local_consumed + addition;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           c->local_consumed = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2543,7 +2578,7 @@ channel_output_poll_input_open(struct ss
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   size_t len, plen;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   const u_char *pkt;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if ((len = sshbuf_len(c->input)) == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2589,7 +2624,6 @@ channel_output_poll_input_open(struct ss
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                       c->self, ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           c->remote_window -= plen;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* Enqueue packet for buffered data. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2661,7 +2695,7 @@ channel_output_poll(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           c = sc->channels[i];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           if (c == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   continue;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            * We are only interested in channels that can have buffered
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            * incoming data.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2671,10 +2705,10 @@ channel_output_poll(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           if ((c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   /* XXX is this true? */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   debug3("channel %d: will not send data after close",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                      c->self);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                         c->self);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   continue;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           /* Get the amount of buffered data for this channel. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           if (c->istate == CHAN_INPUT_OPEN ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-               c->istate == CHAN_INPUT_WAIT_DRAIN)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -3373,6 +3407,14 @@ channel_fwd_bind_addr(struct ssh *ssh, c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return addr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+channel_set_hpn(int external_hpn_disabled, int external_hpn_buffer_size)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  hpn_disabled = external_hpn_disabled;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  hpn_buffer_size = external_hpn_buffer_size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  debug("HPN Disabled: %d, HPN Buffer Size: %d", hpn_disabled, hpn_buffer_size);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     struct Forward *fwd, int *allocated_listen_port,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -3513,9 +3555,11 @@ channel_setup_fwd_listener_tcpip(struct 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           /* Allocate a channel number for the socket. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* explicitly test for hpn disabled option. if true use smaller window size */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           c = channel_new(ssh, "port listener", type, sock, sock, -1,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--              CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--              0, "port listener", 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          hpn_disabled ? CHAN_TCP_WINDOW_DEFAULT : hpn_buffer_size,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          CHAN_TCP_PACKET_DEFAULT,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          0, "port listener", 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           c->path = xstrdup(host);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           c->host_port = fwd->connect_port;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           c->listening_addr = addr == NULL ? NULL : xstrdup(addr);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -4670,8 +4714,9 @@ x11_create_display_inet(struct ssh *ssh,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           sock = socks[n];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           nc = channel_new(ssh, "x11 listener",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-               SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--              CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--              0, "X11 inet listener", 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                           hpn_disabled ? CHAN_X11_WINDOW_DEFAULT : hpn_buffer_size,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                           CHAN_X11_PACKET_DEFAULT,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                           0, "X11 inet listener", 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           nc->single_connection = single_connection;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           (*chanids)[n] = nc->self;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/channels.h   2019-11-08 14:18:24.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/channels.h   2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -150,8 +150,10 @@ struct Channel {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   u_int   local_window_max;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   u_int   local_consumed;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   u_int   local_maxpacket;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int     dynamic_window;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     extended_usage;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     single_connection;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_int   tcpwinsz;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   char   *ctype;          /* type */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -344,4 +346,7 @@ void    chan_rcvd_ieof(struct ssh *, Chann
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- void       chan_write_failed(struct ssh *, Channel *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- void       chan_obuf_empty(struct ssh *, Channel *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* hpn handler */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void     channel_set_hpn(int, int);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- /dev/null      1970-01-01 00:00:00.000000000 +0000
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/cipher-ctr-mt.c      2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,660 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * OpenSSH Multi-threaded AES-CTR Cipher
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Author: Benjamin Bennett <ben@psc.edu>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Author: Mike Tasota <tasota@gmail.com>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Author: Chris Rapier <rapier@psc.edu>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Copyright (c) 2008-2013 Pittsburgh Supercomputing Center. All rights reserved.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Based on original OpenSSH AES-CTR cipher. Small portions remain unchanged,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Permission to use, copy, modify, and distribute this software for any
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * purpose with or without fee is hereby granted, provided that the above
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * copyright notice and this permission notice appear in all copies.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "includes.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#if defined(WITH_OPENSSL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <sys/types.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <stdarg.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <string.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <openssl/evp.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "xmalloc.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "log.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <unistd.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* compatibility with old or broken OpenSSL versions */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "openbsd-compat/openssl-compat.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifndef USE_BUILTIN_RIJNDAEL
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <openssl/aes.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <pthread.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*-------------------- TUNABLES --------------------*/
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* maximum number of threads and queues */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define MAX_THREADS      32 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define MAX_NUMKQ        (MAX_THREADS * 2)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* Number of pregen threads to use */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int cipher_threads = 2;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* Number of keystream queues */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int numkq = 4;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* Length of a keystream queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define KQLEN             4096
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* Processor cacheline length */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define CACHELINE_LEN     64
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* Collect thread stats and print at cancellation when in debug mode */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define CIPHER_THREAD_STATS
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* Can the system do unaligned loads natively? */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#if defined(__aarch64__) || \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    defined(__i386__)    || \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    defined(__powerpc__) || \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    defined(__x86_64__)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# define CIPHER_UNALIGNED_OK
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#if defined(__SIZEOF_INT128__)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# define CIPHER_INT128_OK
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*-------------------- END TUNABLES --------------------*/
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+const EVP_CIPHER *evp_aes_ctr_mt(void);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef CIPHER_THREAD_STATS
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Struct to collect thread stats
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+struct thread_stats {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_int   fills;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_int   skips;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_int   waits;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_int   drains;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Debug print the thread stats
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Use with pthread_cleanup_push for displaying at thread cancellation
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+thread_loop_stats(void *x)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct thread_stats *s = x;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  debug("AES-CTR MT tid %lu - %u fills, %u skips, %u waits", pthread_self(),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  s->fills, s->skips, s->waits);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# define STATS_STRUCT(s)  struct thread_stats s
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# define STATS_INIT(s)            { memset(&s, 0, sizeof(s)); }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# define STATS_FILL(s)            { s.fills++; }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# define STATS_SKIP(s)            { s.skips++; }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# define STATS_WAIT(s)            { s.waits++; }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# define STATS_DRAIN(s)           { s.drains++; }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# define STATS_STRUCT(s)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# define STATS_INIT(s)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# define STATS_FILL(s)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# define STATS_SKIP(s)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# define STATS_WAIT(s)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# define STATS_DRAIN(s)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* Keystream Queue state */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+enum {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  KQINIT,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  KQEMPTY,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  KQFILLING,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  KQFULL,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  KQDRAINING
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* Keystream Queue struct */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+struct kq {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_char          keys[KQLEN][AES_BLOCK_SIZE];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_char          ctr[AES_BLOCK_SIZE];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_char          pad0[CACHELINE_LEN];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int             qstate;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  pthread_mutex_t lock;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  pthread_cond_t  cond;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_char          pad1[CACHELINE_LEN];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* Context struct */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+struct ssh_aes_ctr_ctx_mt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int             struct_id;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct kq       q[MAX_NUMKQ];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  AES_KEY         aes_ctx;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  STATS_STRUCT(stats);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_char          aes_counter[AES_BLOCK_SIZE];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  pthread_t       tid[MAX_THREADS];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int             id[MAX_THREADS];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  pthread_rwlock_t tid_lock;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  pthread_rwlock_t stop_lock;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int             exit_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif /* __APPLE__ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int             state;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int             qidx;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int             ridx;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* <friedl>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * increment counter 'ctr',
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * the counter is of size 'len' bytes and stored in network-byte-order.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * (LSB at ctr[len-1], MSB at ctr[0])
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_ctr_inc(u_char *ctr, size_t len)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int i;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for (i = len - 1; i >= 0; i--)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (++ctr[i])   /* continue on overflow */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Add num to counter 'ctr'
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_ctr_add(u_char *ctr, uint32_t num, u_int len)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int i;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint16_t n;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for (n = 0, i = len - 1; i >= 0 && (num || n); i--) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          n = ctr[i] + (num & 0xff) + n;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          num >>= 8;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ctr[i] = n & 0xff;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          n >>= 8;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Threads may be cancelled in a pthread_cond_wait, we must free the mutex
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+thread_loop_cleanup(void *x)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  pthread_mutex_unlock((pthread_mutex_t *)x);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* Check if we should exit, we are doing both cancel and exit condition
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * since on OSX threads seem to occasionally fail to notice when they have
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * been cancelled. We want to have a backup to make sure that we won't hang
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * when the main process join()-s the cancelled thread.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+thread_loop_check_exit(struct ssh_aes_ctr_ctx_mt *c)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int exit_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  pthread_rwlock_rdlock(&c->stop_lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  exit_flag = c->exit_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  pthread_rwlock_unlock(&c->stop_lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (exit_flag)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_exit(NULL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# define thread_loop_check_exit(s)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif /* __APPLE__ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Helper function to terminate the helper threads
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+stop_and_join_pregen_threads(struct ssh_aes_ctr_ctx_mt *c)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int i;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* notify threads that they should exit */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  pthread_rwlock_wrlock(&c->stop_lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  c->exit_flag = TRUE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  pthread_rwlock_unlock(&c->stop_lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif /* __APPLE__ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Cancel pregen threads */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for (i = 0; i < cipher_threads; i++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug ("Canceled %lu (%d,%d)", c->tid[i], c->struct_id, c->id[i]);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_cancel(c->tid[i]);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for (i = 0; i < numkq; i++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_mutex_trylock(&c->q[i].lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_cond_broadcast(&c->q[i].cond);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_mutex_unlock(&c->q[i].lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for (i = 0; i < cipher_threads; i++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (pthread_kill(c->tid[i], 0) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug3("AES-CTR MT pthread_join failure: Invalid thread id %lu in %s", c->tid[i], __FUNCTION__);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          else { 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug ("Joining %lu (%d, %d)", c->tid[i], c->struct_id, c->id[i]);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  pthread_join(c->tid[i], NULL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * The life of a pregen thread:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *    Find empty keystream queues and fill them using their counter.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *    When done, update counter for the next fill.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static void *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+thread_loop(void *x)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  AES_KEY key;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  STATS_STRUCT(stats);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct ssh_aes_ctr_ctx_mt *c = x;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct kq *q;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int i;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int qidx;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  pthread_t first_tid;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Threads stats on cancellation */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  STATS_INIT(stats);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef CIPHER_THREAD_STATS
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  pthread_cleanup_push(thread_loop_stats, &stats);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Thread local copy of AES key */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  memcpy(&key, &c->aes_ctx, sizeof(key));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  pthread_rwlock_rdlock(&c->tid_lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  first_tid = c->tid[0];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  pthread_rwlock_unlock(&c->tid_lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * Handle the special case of startup, one thread must fill
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * the first KQ then mark it as draining. Lock held throughout.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (pthread_equal(pthread_self(), first_tid)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          q = &c->q[0];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_mutex_lock(&q->lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (q->qstate == KQINIT) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  for (i = 0; i < KQLEN; i++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          AES_encrypt(q->ctr, q->keys[i], &key);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  ssh_ctr_add(q->ctr, KQLEN * (numkq - 1), AES_BLOCK_SIZE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  q->qstate = KQDRAINING;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  STATS_FILL(stats);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  pthread_cond_broadcast(&q->cond);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_mutex_unlock(&q->lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  } else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          STATS_SKIP(stats);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * Normal case is to find empty queues and fill them, skipping over
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * queues already filled by other threads and stopping to wait for
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * a draining queue to become empty.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * Multiple threads may be waiting on a draining queue and awoken
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * when empty.  The first thread to wake will mark it as filling,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * others will move on to fill, skip, or wait on the next queue.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for (qidx = 1;; qidx = (qidx + 1) % numkq) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* Check if I was cancelled, also checked in cond_wait */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_testcancel();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* Check if we should exit as well */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          thread_loop_check_exit(c);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* Lock queue and block if its draining */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          q = &c->q[qidx];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_mutex_lock(&q->lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_cleanup_push(thread_loop_cleanup, &q->lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          while (q->qstate == KQDRAINING || q->qstate == KQINIT) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  STATS_WAIT(stats);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  thread_loop_check_exit(c);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  pthread_cond_wait(&q->cond, &q->lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_cleanup_pop(0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* If filling or full, somebody else got it, skip */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (q->qstate != KQEMPTY) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  pthread_mutex_unlock(&q->lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  STATS_SKIP(stats);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  continue;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * Empty, let's fill it.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * Queue lock is relinquished while we do this so others
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * can see that it's being filled.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          q->qstate = KQFILLING;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_cond_broadcast(&q->cond);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_mutex_unlock(&q->lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          for (i = 0; i < KQLEN; i++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  AES_encrypt(q->ctr, q->keys[i], &key);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* Re-lock, mark full and signal consumer */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_mutex_lock(&q->lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh_ctr_add(q->ctr, KQLEN * (numkq - 1), AES_BLOCK_SIZE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          q->qstate = KQFULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          STATS_FILL(stats);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_cond_broadcast(&q->cond);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_mutex_unlock(&q->lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef CIPHER_THREAD_STATS
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Stats */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  pthread_cleanup_pop(1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    LIBCRYPTO_EVP_INL_TYPE len)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  typedef union {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef CIPHER_INT128_OK
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          __uint128_t *u128;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          uint64_t *u64;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          uint32_t *u32;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          uint8_t *u8;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          const uint8_t *cu8;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          uintptr_t u;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  } ptrs_t;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ptrs_t destp, srcp, bufp;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uintptr_t align;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct ssh_aes_ctr_ctx_mt *c;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct kq *q, *oldq;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int ridx;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_char *buf;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (len == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  q = &c->q[c->qidx];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ridx = c->ridx;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* src already padded to block multiple */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  srcp.cu8 = src;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  destp.u8 = dest;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  while (len > 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          buf = q->keys[ridx];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          bufp.u8 = buf;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* figure out the alignment on the fly */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef CIPHER_UNALIGNED_OK
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          align = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          align = destp.u | srcp.u | bufp.u;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef CIPHER_INT128_OK
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if ((align & 0xf) == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  destp.u128[0] = srcp.u128[0] ^ bufp.u128[0];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          } else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if ((align & 0x7) == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  destp.u64[0] = srcp.u64[0] ^ bufp.u64[0];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  destp.u64[1] = srcp.u64[1] ^ bufp.u64[1];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          } else if ((align & 0x3) == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  destp.u32[0] = srcp.u32[0] ^ bufp.u32[0];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  destp.u32[1] = srcp.u32[1] ^ bufp.u32[1];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  destp.u32[2] = srcp.u32[2] ^ bufp.u32[2];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  destp.u32[3] = srcp.u32[3] ^ bufp.u32[3];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  size_t i;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  for (i = 0; i < AES_BLOCK_SIZE; ++i)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          dest[i] = src[i] ^ buf[i];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          destp.u += AES_BLOCK_SIZE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          srcp.u += AES_BLOCK_SIZE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          len -= AES_BLOCK_SIZE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh_ctr_inc(ctx->iv, AES_BLOCK_SIZE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* Increment read index, switch queues on rollover */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if ((ridx = (ridx + 1) % KQLEN) == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  oldq = q;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* Mark next queue draining, may need to wait */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  c->qidx = (c->qidx + 1) % numkq;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  q = &c->q[c->qidx];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  pthread_mutex_lock(&q->lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  while (q->qstate != KQFULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          STATS_WAIT(c->stats);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          pthread_cond_wait(&q->cond, &q->lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  q->qstate = KQDRAINING;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  pthread_cond_broadcast(&q->cond);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  pthread_mutex_unlock(&q->lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* Mark consumed queue empty and signal producers */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  pthread_mutex_lock(&oldq->lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  oldq->qstate = KQEMPTY;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  STATS_DRAIN(c->stats);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  pthread_cond_broadcast(&oldq->cond);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  pthread_mutex_unlock(&oldq->lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  c->ridx = ridx;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define HAVE_NONE       0
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define HAVE_KEY        1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define HAVE_IV         2
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int X = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    int enc)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct ssh_aes_ctr_ctx_mt *c;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int i;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* get the number of cores in the system */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* if it's not linux it currently defaults to 2 */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* divide by 2 to get threads for each direction (MODE_IN||MODE_OUT) */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef __linux__
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  cipher_threads = sysconf(_SC_NPROCESSORS_ONLN) / 2;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif /*__linux__*/
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  cipher_threads = sysconf(_SC_NPROCESSORS_ONLN) / 2;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif /*__APPLE__*/
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef __FREEBSD__
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int req[2];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  size_t len;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  req[0] = CTL_HW;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  req[1] = HW_NCPU;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  len = sizeof(ncpu);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        sysctl(req, 2, &cipher_threads, &len, NULL, 0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  cipher_threads = cipher_threads / 2;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif /*__FREEBSD__*/
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* if they have less than 4 cores spin up 4 threads anyway */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (cipher_threads < 2) 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          cipher_threads = 2;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        /* assure that we aren't trying to create more threads than we have in the struct */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* cipher_threads is half the total of allowable threads hence the odd looking math here */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (cipher_threads * 2 > MAX_THREADS)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          cipher_threads = MAX_THREADS / 2;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* set the number of keystream queues */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  numkq = cipher_threads * 2;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          c = xmalloc(sizeof(*c));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_rwlock_init(&c->tid_lock, NULL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_rwlock_init(&c->stop_lock, NULL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          c->exit_flag = FALSE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif /* __APPLE__ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          c->state = HAVE_NONE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          for (i = 0; i < numkq; i++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  pthread_mutex_init(&c->q[i].lock, NULL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  pthread_cond_init(&c->q[i].cond, NULL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          STATS_INIT(c->stats);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          EVP_CIPHER_CTX_set_app_data(ctx, c);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (c->state == (HAVE_KEY | HAVE_IV)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* tell the pregen threads to exit */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          stop_and_join_pregen_threads(c);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* reset the exit flag */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          c->exit_flag = FALSE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif /* __APPLE__ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* Start over getting key & iv */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          c->state = HAVE_NONE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (key != NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              &c->aes_ctx);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          c->state |= HAVE_KEY;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (iv != NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          c->state |= HAVE_IV;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (c->state == (HAVE_KEY | HAVE_IV)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* Clear queues */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          memcpy(c->q[0].ctr, ctx->iv, AES_BLOCK_SIZE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          c->q[0].qstate = KQINIT;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          for (i = 1; i < numkq; i++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  memcpy(c->q[i].ctr, ctx->iv, AES_BLOCK_SIZE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  ssh_ctr_add(c->q[i].ctr, i * KQLEN, AES_BLOCK_SIZE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  c->q[i].qstate = KQEMPTY;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          c->qidx = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          c->ridx = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* Start threads */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          for (i = 0; i < cipher_threads; i++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  pthread_rwlock_wrlock(&c->tid_lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if (pthread_create(&c->tid[i], NULL, thread_loop, c) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          debug ("AES-CTR MT Could not create thread in %s", __FUNCTION__); /*should die here */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if (!c->struct_id)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  c->struct_id = X++;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          c->id[i] = i;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          debug ("AES-CTR MT spawned a thread with id %lu in %s (%d, %d)", c->tid[i], __FUNCTION__, c->struct_id, c->id[i]);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  pthread_rwlock_unlock(&c->tid_lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_mutex_lock(&c->q[0].lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          while (c->q[0].qstate == KQINIT)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  pthread_cond_wait(&c->q[0].cond, &c->q[0].lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_mutex_unlock(&c->q[0].lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* this function is no longer used but might prove handy in the future
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * this comment also applies to ssh_aes_ctr_thread_reconstruction
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_aes_ctr_thread_destroy(EVP_CIPHER_CTX *ctx)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct ssh_aes_ctr_ctx_mt *c;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  c = EVP_CIPHER_CTX_get_app_data(ctx);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  stop_and_join_pregen_threads(c);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_aes_ctr_thread_reconstruction(EVP_CIPHER_CTX *ctx)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct ssh_aes_ctr_ctx_mt *c;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int i;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  c = EVP_CIPHER_CTX_get_app_data(ctx);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* reconstruct threads */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for (i = 0; i < cipher_threads; i++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_rwlock_wrlock(&c->tid_lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (pthread_create(&c->tid[i], NULL, thread_loop, c) !=0 )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug("AES-CTR MT could not create thread in %s", __FUNCTION__);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  c->struct_id = X++;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  c->id[i] = i;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug ("AES-CTR MT spawned a thread with id %lu in %s (%d, %d)", c->tid[i], __FUNCTION__, c->struct_id, c->id[i]);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug("AES-CTR MT spawned a thread with id %lu in %s", c->tid[i], __FUNCTION__);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pthread_rwlock_unlock(&c->tid_lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct ssh_aes_ctr_ctx_mt *c;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef CIPHER_THREAD_STATS
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug("AES-CTR MT main thread: %u drains, %u waits", c->stats.drains,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                c->stats.waits);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          stop_and_join_pregen_threads(c);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          memset(c, 0, sizeof(*c));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          free(c);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          EVP_CIPHER_CTX_set_app_data(ctx, NULL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* <friedl> */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+const EVP_CIPHER *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+evp_aes_ctr_mt(void)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  static EVP_CIPHER aes_ctr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  memset(&aes_ctr, 0, sizeof(EVP_CIPHER));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  aes_ctr.nid = NID_undef;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  aes_ctr.block_size = AES_BLOCK_SIZE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  aes_ctr.iv_len = AES_BLOCK_SIZE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  aes_ctr.key_len = 16;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  aes_ctr.init = ssh_aes_ctr_init;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  aes_ctr.cleanup = ssh_aes_ctr_cleanup;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  aes_ctr.do_cipher = ssh_aes_ctr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifndef SSH_OLD_EVP
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return &aes_ctr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif /* defined(WITH_OPENSSL) */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/cipher.c     2019-10-09 02:31:03.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/cipher.c     2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -51,6 +51,9 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "openbsd-compat/openssl-compat.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* for multi-threaded aes-ctr cipher */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+extern const EVP_CIPHER *evp_aes_ctr_mt(void);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifndef WITH_OPENSSL
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #define EVP_CIPHER_CTX void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -83,7 +86,7 @@ struct sshcipher {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--static const struct sshcipher ciphers[] = {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static struct sshcipher ciphers[] = {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef WITH_OPENSSL
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifndef OPENSSL_NO_DES
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "3des-cbc",         8, 24, 0, 0, CFLAG_CBC, EVP_des_ede3_cbc },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -143,6 +146,29 @@ cipher_alg_list(char sep, int auth_only)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return ret;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* used to get the cipher name so when force rekeying to handle the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * single to multithreaded ctr cipher swap we only rekey when appropriate
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+const char *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+cipher_ctx_name(const struct sshcipher_ctx *cc)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return cc->cipher->name;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* in order to get around sandbox and forking issues with a threaded cipher
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * we set the initial pre-auth aes-ctr cipher to the default OpenSSH cipher
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * post auth we set them to the new evp as defined by cipher-ctr-mt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef WITH_OPENSSL
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+cipher_reset_multithreaded(void)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  cipher_by_name("aes128-ctr")->evptype = evp_aes_ctr_mt;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  cipher_by_name("aes192-ctr")->evptype = evp_aes_ctr_mt;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  cipher_by_name("aes256-ctr")->evptype = evp_aes_ctr_mt;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- u_int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- cipher_blocksize(const struct sshcipher *c)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -192,10 +218,10 @@ cipher_ctx_is_plaintext(struct sshcipher
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return cc->plaintext;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--const struct sshcipher *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+struct sshcipher *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- cipher_by_name(const char *name)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  const struct sshcipher *c;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshcipher *c;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   for (c = ciphers; c->name != NULL; c++)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           if (strcmp(c->name, name) == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   return c;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -217,7 +243,8 @@ ciphers_valid(const char *names)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       (p = strsep(&cp, CIPHER_SEP))) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           c = cipher_by_name(p);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          if (c == NULL || (c->flags & CFLAG_INTERNAL) != 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            if (c == NULL || ((c->flags & CFLAG_INTERNAL) != 0 &&
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (c->flags & CFLAG_NONE) != 0)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   free(cipher_list);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/cipher.h     2019-10-09 02:31:03.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/cipher.h     2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -50,7 +50,9 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- struct sshcipher;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- struct sshcipher_ctx;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--const struct sshcipher *cipher_by_name(const char *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void ssh_aes_ctr_thread_destroy(EVP_CIPHER_CTX *ctx); // defined in cipher-ctr-mt.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void ssh_aes_ctr_thread_reconstruction(EVP_CIPHER_CTX *ctx);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+struct sshcipher *cipher_by_name(const char *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- const char *cipher_warning_message(const struct sshcipher_ctx *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int        ciphers_valid(const char *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- char      *cipher_alg_list(char, int);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -67,6 +69,8 @@ u_int     cipher_seclen(const struct sshcip
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- u_int      cipher_authlen(const struct sshcipher *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- u_int      cipher_ivlen(const struct sshcipher *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- u_int      cipher_is_cbc(const struct sshcipher *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void       cipher_reset_multithreaded(void);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+const char *cipher_ctx_name(const struct sshcipher_ctx *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- u_int      cipher_ctx_is_plaintext(struct sshcipher_ctx *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/clientloop.c 2019-11-08 15:37:33.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/clientloop.c 2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1619,9 +1619,11 @@ client_request_x11(struct ssh *ssh, cons
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   sock = x11_connect_display(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (sock < 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           return NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  c = channel_new(ssh, "x11",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--      SSH_CHANNEL_X11_OPEN, sock, sock, -1,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--      CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        c = channel_new(ssh, "x11",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  SSH_CHANNEL_X11_OPEN, sock, sock, -1,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* again is this really necessary for X11? */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  options.hpn_disabled ? CHAN_TCP_WINDOW_DEFAULT : options.hpn_buffer_size,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  CHAN_X11_PACKET_DEFAULT, 0, "x11", 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   c->force_drain = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return c;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1645,9 +1647,10 @@ client_request_agent(struct ssh *ssh, co
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           return NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   c = channel_new(ssh, "authentication agent connection",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--      SSH_CHANNEL_OPEN, sock, sock, -1,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--      CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--      "authentication agent connection", 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  SSH_CHANNEL_OPEN, sock, sock, -1,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  options.hpn_disabled ? CHAN_X11_WINDOW_DEFAULT : options.hpn_buffer_size,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  CHAN_TCP_PACKET_DEFAULT, 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  "authentication agent connection", 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   c->force_drain = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return c;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1672,10 +1675,13 @@ client_request_tun_fwd(struct ssh *ssh, 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   debug("Tunnel forwarding using interface %s", ifname);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  c = channel_new(ssh, "tun", SSH_CHANNEL_OPENING, fd, fd, -1,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--      CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        c = channel_new(ssh, "tun", SSH_CHANNEL_OPENING, fd, fd, -1,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      options.hpn_disabled ? CHAN_TCP_WINDOW_DEFAULT : options.hpn_buffer_size,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   c->datagram = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #if defined(SSH_TUN_FILTER)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options.tun_open == SSH_TUNMODE_POINTOPOINT)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           channel_register_filter(ssh, c->self, sys_tun_infilter,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/compat.c     2019-10-09 02:31:03.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/compat.c     2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -150,6 +150,13 @@ compat_datafellows(const char *version)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   debug("match: %s pat %s compat 0x%08x",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                       version, check[i].pat, check[i].bugs);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   datafellows = check[i].bugs;    /* XXX for now */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* Check to see if the remote side is OpenSSH and not HPN */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if (strstr(version, "OpenSSH") != NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if (strstr(version, "hpn") == NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  datafellows |= SSH_BUG_LARGEWINDOW;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  debug("Remote is NON-HPN aware");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   return check[i].bugs;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/compat.h     2019-10-09 02:31:03.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/compat.h     2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -62,6 +62,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #define SSH_BUG_CURVE25519PAD     0x10000000
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #define SSH_BUG_HOSTKEYS  0x20000000
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #define SSH_BUG_DHGEX_LARGE       0x40000000
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define SSH_BUG_LARGEWINDOW       0x80000000
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- u_int    compat_datafellows(const char *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int        proto_spec(const char *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/kex.c        2019-11-08 15:37:33.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/kex.c        2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -58,6 +58,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "ssherr.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "sshbuf.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "canohost.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "digest.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* prototype */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -884,6 +885,11 @@ kex_choose_conf(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int nenc, nmac, ncomp;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   u_int mode, ctos, need, dh_need, authlen;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int r, first_kex_follows;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int auth_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int log_flag = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  auth_flag = packet_authentication_state(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  debug("AUTH STATE IS %d", auth_flag);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   debug2("local %s KEXINIT proposal", kex->server ? "server" : "client");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -954,11 +960,35 @@ kex_choose_conf(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   peer[ncomp] = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   goto out;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug("REQUESTED ENC.NAME is '%s'", newkeys->enc.name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (strcmp(newkeys->enc.name, "none") == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug("Requesting NONE. Authflag is %d", auth_flag);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if (auth_flag == 1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          debug("None requested post authentication.");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal("Pre-authentication none cipher requests are not allowed.");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           debug("kex: %s cipher: %s MAC: %s compression: %s",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-               ctos ? "client->server" : "server->client",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-               newkeys->enc.name,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-               authlen == 0 ? newkeys->mac.name : "<implicit>",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-               newkeys->comp.name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * client starts with ctos = 0 && log flag = 0 and no log.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * 2nd client pass ctos = 1 and flag = 1 so no log.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * server starts with ctos = 1 && log_flag = 0 so log.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * 2nd sever pass ctos = 1 && log flag = 1 so no log.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * -cjr
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (ctos && !log_flag) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  logit("SSH: Server;Ltype: Kex;Remote: %s-%d;Enc: %s;MAC: %s;Comp: %s",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      ssh_remote_ipaddr(ssh),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      ssh_remote_port(ssh),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      newkeys->enc.name,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      authlen == 0 ? newkeys->mac.name : "<implicit>",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      newkeys->comp.name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          log_flag = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   need = dh_need = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   for (mode = 0; mode < MODE_MAX; mode++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/log.c        2019-10-09 02:31:03.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/log.c        2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -46,6 +46,12 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include <syslog.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include <unistd.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include <errno.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "packet.h" /* needed for host and port look ups */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef HAVE_SYS_TIME_H
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# include <sys/time.h> /* to get current time */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # include <vis.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/packet.c     2019-10-09 02:31:03.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/packet.c     2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -265,6 +265,9 @@ ssh_alloc_session_state(void)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* forward declaration */ 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void ssh_final_log_entry (struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ssh_packet_set_input_hook(struct ssh *ssh, ssh_packet_hook_fn *hook, void *ctx)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -286,7 +289,7 @@ struct ssh *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ssh_packet_set_connection(struct ssh *ssh, int fd_in, int fd_out)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   struct session_state *state;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  const struct sshcipher *none = cipher_by_name("none");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshcipher *none = cipher_by_name("none");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (none == NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -925,6 +928,24 @@ ssh_set_newkeys(struct ssh *ssh, int mod
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* this supports the forced rekeying required for the NONE cipher */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int rekey_requested = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+packet_request_rekeying(void)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  rekey_requested = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* used to determine if pre or post auth when rekeying for aes-ctr
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * and none cipher switch */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+packet_authentication_state(const struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct session_state *state = ssh->state;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return state->after_authentication;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #define MAX_PACKETS       (1U<<31)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -951,6 +972,13 @@ ssh_packet_need_rekeying(struct ssh *ssh
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (state->p_send.packets == 0 && state->p_read.packets == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        /* used to force rekeying when called for by the none
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+         * cipher switch and aes-mt-ctr methods -cjr */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        if (rekey_requested == 1) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                rekey_requested = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                return 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* Time-based rekeying */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (state->rekey_interval != 0 &&
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       (int64_t)state->rekey_time + state->rekey_interval <= monotime())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1807,6 +1835,16 @@ sshpkt_fmt_connection_id(struct ssh *ssh
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* Povide the current time in seconds since epoch */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+get_current_time(void)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct timeval tv;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gettimeofday(&tv, NULL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  * Pretty-print connection-terminating errors and exit.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1820,17 +1858,21 @@ sshpkt_vfatal(struct ssh *ssh, int r, co
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   switch (r) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   case SSH_ERR_CONN_CLOSED:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           ssh_packet_clear_keys(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh_final_log_entry(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           logdie("Connection closed by %s", remote_id);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   case SSH_ERR_CONN_TIMEOUT:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           ssh_packet_clear_keys(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh_final_log_entry(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           logdie("Connection %s %s timed out",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-               ssh->state->server_side ? "from" : "to", remote_id);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   case SSH_ERR_DISCONNECTED:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           ssh_packet_clear_keys(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh_final_log_entry(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           logdie("Disconnected from %s", remote_id);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   case SSH_ERR_SYSTEM_ERROR:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           if (errno == ECONNRESET) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   ssh_packet_clear_keys(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  ssh_final_log_entry(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   logdie("Connection reset by %s", remote_id);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           /* FALLTHROUGH */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1860,6 +1902,24 @@ sshpkt_vfatal(struct ssh *ssh, int r, co
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* this prints out the final log entry - used in sshpkt_fatal -cjr */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_final_log_entry (struct ssh *ssh) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double total_time;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (ssh->start_time < 1) 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* this will produce a NaN in the output. -cjr */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          total_time = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          total_time = get_current_time() - ssh->start_time;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  logit("SSH: Server;LType: Throughput;Remote: %s-%d;IN: %lu;OUT: %lu;Duration: %.1f;tPut_in: %.1f;tPut_out: %.1f",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        ssh->stdin_bytes, ssh->fdout_bytes, total_time,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        ssh->stdin_bytes / total_time,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        ssh->fdout_bytes / total_time);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- sshpkt_fatal(struct ssh *ssh, int r, const char *fmt, ...)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1941,6 +2001,8 @@ ssh_packet_write_poll(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   return SSH_ERR_CONN_CLOSED;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           if ((r = sshbuf_consume(state->output, len)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   return r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  ssh->stdin_bytes += len;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2701,3 +2763,10 @@ sshpkt_add_padding(struct ssh *ssh, u_ch
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   ssh->state->extra_pad = pad;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* need this for the moment for the aes-ctr cipher */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_packet_get_send_context(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        return ssh->state->send_context;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/packet.h     2019-10-09 02:31:03.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/packet.h     2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -86,6 +86,11 @@ struct ssh {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* APP data */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   void *app_data;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* logging data for ServerLogging patch*/
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double start_time;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_long fdout_bytes;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_long stdin_bytes;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- typedef int (ssh_packet_hook_fn)(struct ssh *, struct sshbuf *,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -155,6 +160,10 @@ int    ssh_packet_inc_alive_timeouts(struc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int        ssh_packet_set_maxsize(struct ssh *, u_int);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- u_int      ssh_packet_get_maxsize(struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* for forced packet rekeying post auth */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void       packet_request_rekeying(void);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int        packet_authentication_state(const struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int        ssh_packet_get_state(struct ssh *, struct sshbuf *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int        ssh_packet_set_state(struct ssh *, struct sshbuf *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -169,6 +178,11 @@ time_t         ssh_packet_get_rekey_timeout(str
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- void      *ssh_packet_get_input(struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- void      *ssh_packet_get_output(struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void      *ssh_packet_get_receive_context(struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void      *ssh_packet_get_send_context(struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void    packet_request_rekeying(void);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double  get_current_time(void);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* new API */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int       sshpkt_start(struct ssh *ssh, u_char type);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/progressmeter.c      2019-10-09 02:31:03.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/progressmeter.c      2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -68,6 +68,8 @@ static const char *file; /* name of the 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static off_t start_pos;           /* initial position of transfer */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static off_t end_pos;             /* ending position of transfer */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static off_t cur_pos;             /* transfer position as of last refresh */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static off_t last_pos;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static off_t max_delta_pos = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static volatile off_t *counter;   /* progress counter */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static long stalled;              /* how long we have been stalled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static int bytes_per_second;      /* current speed in bytes per second */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -127,6 +129,7 @@ refresh_progress_meter(int force_update)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int cur_speed;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int hours, minutes, seconds;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int file_len;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  off_t delta_pos;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if ((!force_update && !alarm_fired && !win_resized) || !can_output())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -142,6 +145,10 @@ refresh_progress_meter(int force_update)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   now = monotime_double();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   bytes_left = end_pos - cur_pos;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  delta_pos = cur_pos - last_pos;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (delta_pos > max_delta_pos)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          max_delta_pos = delta_pos;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (bytes_left > 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           elapsed = now - last_update;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -166,7 +173,7 @@ refresh_progress_meter(int force_update)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* filename */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   buf[0] = '\0';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  file_len = win_size - 36;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  file_len = win_size - 45;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (file_len > 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           buf[0] = '\r';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           snmprintf(buf+1, sizeof(buf)-1, &file_len, "%-*s",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -191,6 +198,15 @@ refresh_progress_meter(int force_update)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       (off_t)bytes_per_second);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   strlcat(buf, "/s ", win_size);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* instantaneous rate */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (bytes_left > 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          format_rate(buf + strlen(buf), win_size - strlen(buf),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      delta_pos);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          format_rate(buf + strlen(buf), win_size - strlen(buf),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      max_delta_pos);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  strlcat(buf, "/s ", win_size);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* ETA */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (!transferred)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           stalled += elapsed;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -227,6 +243,7 @@ refresh_progress_meter(int force_update)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   last_update = now;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  last_pos = cur_pos;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /*ARGSUSED*/
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/readconf.c   2019-11-08 15:37:33.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/readconf.c   2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -67,6 +67,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "uidswap.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "myproposal.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "digest.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "sshbuf.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* Format of the configuration file:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -170,6 +171,9 @@ typedef enum {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef __APPLE_KEYCHAIN__
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   oUseKeychain,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  oTcpRcvBufPoll, oTcpRcvBuf, oHPNDisabled, oHPNBufferSize,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  oNoneEnabled, oNoneSwitch,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  oDisableMTAES,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   oVisualHostKey,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -301,6 +305,9 @@ static struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "kexalgorithms", oKexAlgorithms },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "ipqos", oIPQoS },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "requesttty", oRequestTTY },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "noneenabled", oNoneEnabled },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "noneswitch", oNoneSwitch },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        { "disablemtaes", oDisableMTAES },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "proxyusefdpass", oProxyUseFdpass },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "canonicaldomains", oCanonicalDomains },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -317,6 +324,11 @@ static struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "ignoreunknown", oIgnoreUnknown },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "proxyjump", oProxyJump },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "tcprcvbufpoll", oTcpRcvBufPoll },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "tcprcvbuf", oTcpRcvBuf },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "hpndisabled", oHPNDisabled },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "hpnbuffersize", oHPNBufferSize },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { NULL, oBadOption }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1006,6 +1018,42 @@ parse_time:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           intptr = &options->check_host_ip;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case oHPNDisabled:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          intptr = &options->hpn_disabled;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case oHPNBufferSize:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          intptr = &options->hpn_buffer_size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto parse_int;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case oTcpRcvBufPoll:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          intptr = &options->tcp_rcv_buf_poll;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case oNoneEnabled:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          intptr = &options->none_enabled;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        case oDisableMTAES:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          intptr = &options->disable_multithreaded;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * We check to see if the command comes from the command
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * line or not. If it does then enable it otherwise fail.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   *  NONE should never be a default configuration.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case oNoneSwitch:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (strcmp(filename, "command-line") == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  intptr = &options->none_switch;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  error("NoneSwitch is found in %.200s.\nYou may only use this configuration option from the command line", filename);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  error("Continuing...");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug("NoneSwitch directive found in %.200s.", filename);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   case oVerifyHostKeyDNS:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           intptr = &options->verify_host_key_dns;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           multistate_ptr = multistate_yesnoask;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1201,6 +1249,10 @@ parse_int:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   *intptr = value;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case oTcpRcvBuf:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          intptr = &options->tcp_rcv_buf;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto parse_int;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   case oCiphers:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           arg = strdelim(&s);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           if (!arg || *arg == '\0')
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1950,6 +2002,13 @@ initialize_options(Options * options)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->ip_qos_interactive = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->ip_qos_bulk = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->request_tty = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  options->none_switch = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  options->none_enabled = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        options->disable_multithreaded = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  options->hpn_disabled = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  options->hpn_buffer_size = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  options->tcp_rcv_buf_poll = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  options->tcp_rcv_buf = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->proxy_use_fdpass = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->ignored_unknown = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->num_canonical_domains = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2097,6 +2156,32 @@ fill_default_options(Options * options)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           options->server_alive_interval = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options->server_alive_count_max == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           options->server_alive_count_max = 3;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options->hpn_disabled == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          options->hpn_disabled = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options->hpn_buffer_size > -1) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* if a user tries to set the size to 0 set it to 1KB */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (options->hpn_buffer_size == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  options->hpn_buffer_size = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* limit the buffer to SSHBUF_SIZE_MAX (currently 256MB) */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (options->hpn_buffer_size > (SSHBUF_SIZE_MAX / 1024)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  options->hpn_buffer_size = SSHBUF_SIZE_MAX;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug("User requested buffer larger than 256MB. Request reverted to 256MB");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          } else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  options->hpn_buffer_size *= 1024;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options->tcp_rcv_buf == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          options->tcp_rcv_buf = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options->tcp_rcv_buf > -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          options->tcp_rcv_buf *=1024;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options->tcp_rcv_buf_poll == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          options->tcp_rcv_buf_poll = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options->none_switch == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          options->none_switch = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options->none_enabled == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          options->none_enabled = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        if (options->disable_multithreaded == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          options->disable_multithreaded = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options->control_master == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           options->control_master = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options->control_persist == -1) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/readconf.h   2019-11-08 15:37:33.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/readconf.h   2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -50,6 +50,10 @@ typedef struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     strict_host_key_checking;       /* Strict host key checking. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     compression;    /* Compress packets in both directions. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     tcp_keep_alive; /* Set SO_KEEPALIVE. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int     tcp_rcv_buf; /* user switch to set tcp recv buffer */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int     tcp_rcv_buf_poll; /* Option to poll recv buf every window transfer */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int     hpn_disabled;    /* Switch to disable HPN buffer management */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int     hpn_buffer_size; /* User definable size for HPN buffer window */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     ip_qos_interactive;     /* IP ToS/DSCP/class for interactive */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     ip_qos_bulk;            /* IP ToS/DSCP/class for bulk traffic */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   SyslogFacility log_facility;    /* Facility for system logging. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -112,7 +116,11 @@ typedef struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     enable_ssh_keysign;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int64_t rekey_limit;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int     none_switch;    /* Use none cipher */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int     none_enabled;   /* Allow none to be used */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int     disable_multithreaded; /*disable multithreaded aes-ctr*/
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     rekey_interval;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     no_host_authentication_for_localhost;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     identities_only;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     server_alive_interval;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/sandbox-seccomp-filter.c     2019-10-09 02:31:03.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/sandbox-seccomp-filter.c     2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -203,6 +203,9 @@ static const struct sock_filter preauth_
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef __NR_geteuid32
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   SC_ALLOW(__NR_geteuid32),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef __NR_getpeername /* not defined on archs that go via socketcall(2) */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SC_ALLOW(__NR_getpeername),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef __NR_getpgid
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   SC_ALLOW(__NR_getpgid),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -266,6 +269,9 @@ static const struct sock_filter preauth_
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef __NR_sigprocmask
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   SC_ALLOW(__NR_sigprocmask),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef __NR_socketcall
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SC_ALLOW(__NR_socketcall),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef __NR_time
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   SC_ALLOW(__NR_time),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/scp.c        2019-10-09 02:31:03.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/scp.c        2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1066,7 +1066,7 @@ source(int argc, char **argv)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   off_t i, statbytes;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   size_t amt, nr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int fd = -1, haderr, indx;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  char *last, *name, buf[PATH_MAX + 128], encname[PATH_MAX];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char *last, *name, buf[16384], encname[PATH_MAX];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int len;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   for (indx = 0; indx < argc; ++indx) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/servconf.c   2019-11-08 15:37:33.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/servconf.c   2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -64,6 +64,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "auth.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "myproposal.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "digest.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "sshbuf.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static void add_listen_addr(ServerOptions *, const char *,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     const char *, int);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -174,6 +175,11 @@ initialize_server_options(ServerOptions 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->authorized_principals_file = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->authorized_principals_command = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->authorized_principals_command_user = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  options->tcp_rcv_buf_poll = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  options->hpn_disabled = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  options->hpn_buffer_size = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  options->none_enabled = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  options->disable_multithreaded = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->ip_qos_interactive = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->ip_qos_bulk = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->version_addendum = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -273,6 +279,10 @@ void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- fill_default_server_options(ServerOptions *options)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   u_int i;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* needed for hpn socket tests */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int sock;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int socksize;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int socksizelen = sizeof(int);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* Portable-specific options */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options->use_pam == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -409,6 +419,45 @@ fill_default_server_options(ServerOption
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options->permit_tun == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           options->permit_tun = SSH_TUNMODE_NO;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options->none_enabled == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          options->none_enabled = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options->disable_multithreaded == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          options->disable_multithreaded = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options->hpn_disabled == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          options->hpn_disabled = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options->hpn_buffer_size == -1) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* option not explicitly set. Now we have to figure out */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* what value to use */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (options->hpn_disabled == 1) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* get the current RCV size and set it to that */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /*create a socket but don't connect it */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* we use that the get the rcv socket size */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  sock = socket(AF_INET, SOCK_STREAM, 0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  getsockopt(sock, SOL_SOCKET, SO_RCVBUF,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                             &socksize, &socksizelen);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  close(sock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  options->hpn_buffer_size = socksize;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug("HPN Buffer Size: %d", options->hpn_buffer_size);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* we have to do this in case the user sets both values in a contradictory */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* manner. hpn_disabled overrrides hpn_buffer_size*/
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (options->hpn_disabled <= 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if (options->hpn_buffer_size == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          options->hpn_buffer_size = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* limit the maximum buffer to SSHBUF_SIZE_MAX (currently 256MB) */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if (options->hpn_buffer_size > (SSHBUF_SIZE_MAX / 1024)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          options->hpn_buffer_size = SSHBUF_SIZE_MAX;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          options->hpn_buffer_size *= 1024;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          } else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  options->hpn_buffer_size = CHAN_TCP_WINDOW_DEFAULT;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options->ip_qos_interactive == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           options->ip_qos_interactive = IPTOS_DSCP_AF21;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options->ip_qos_bulk == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -486,6 +535,9 @@ typedef enum {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   sPasswordAuthentication, sKbdInteractiveAuthentication,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   sListenAddress, sAddressFamily,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   sPrintMotd, sPrintLastLog, sIgnoreRhosts,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sNoneEnabled,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sDisableMTAES,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sTcpRcvBufPoll, sHPNDisabled, sHPNBufferSize,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   sPermitUserEnvironment, sAllowTcpForwarding, sCompression,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -642,6 +694,11 @@ static struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "revokedkeys", sRevokedKeys, SSHCFG_ALL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "hpndisabled", sHPNDisabled, SSHCFG_ALL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "hpnbuffersize", sHPNBufferSize, SSHCFG_ALL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "tcprcvbufpoll", sTcpRcvBufPoll, SSHCFG_ALL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "noneenabled", sNoneEnabled, SSHCFG_ALL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "disableMTAES", sDisableMTAES, SSHCFG_ALL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "ipqos", sIPQoS, SSHCFG_ALL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -698,6 +755,7 @@ parse_token(const char *cp, const char *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   for (i = 0; keywords[i].name; i++)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           if (strcasecmp(cp, keywords[i].name) == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug("Config token is %s", keywords[i].name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   *flags = keywords[i].flags;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   return keywords[i].opcode;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1424,10 +1482,30 @@ process_server_config_line(ServerOptions
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           multistate_ptr = multistate_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           goto parse_multistate;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case sTcpRcvBufPoll:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          intptr = &options->tcp_rcv_buf_poll;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case sHPNDisabled:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          intptr = &options->hpn_disabled;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case sHPNBufferSize:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          intptr = &options->hpn_buffer_size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto parse_int;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   case sIgnoreUserKnownHosts:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           intptr = &options->ignore_user_known_hosts;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case sNoneEnabled:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          intptr = &options->none_enabled;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case sDisableMTAES:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          intptr = &options->disable_multithreaded;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   case sHostbasedAuthentication:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           intptr = &options->hostbased_authentication;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/servconf.h   2019-11-08 15:37:33.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/servconf.h   2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -183,6 +183,11 @@ typedef struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   char   *adm_forced_command;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     use_pam;                /* Enable auth via PAM */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        int     tcp_rcv_buf_poll;       /* poll tcp rcv window in autotuning kernels*/
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int     hpn_disabled;           /* disable hpn functionality. false by default */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int     hpn_buffer_size;        /* set the hpn buffer size - default 3MB */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int     none_enabled;           /* Enable NONE cipher switch */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        int     disable_multithreaded;  /*disable multithreaded aes-ctr cipher */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     permit_tun;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/serverloop.c 2019-10-09 02:31:03.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/serverloop.c 2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -343,6 +343,7 @@ process_input(struct ssh *ssh, fd_set *r
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                       != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                           fatal("%s: ssh_packet_process_incoming: %s",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                               __func__, ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  ssh->fdout_bytes += len;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -361,6 +362,7 @@ process_output(struct ssh *ssh, fd_set *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           if ((r = ssh_packet_write_poll(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   fatal("%s: ssh_packet_write_poll: %s",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                       __func__, ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh->stdin_bytes += ssh_packet_write_poll(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -401,6 +403,7 @@ server_loop2(struct ssh *ssh, Authctxt *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   u_int64_t rekey_timeout_ms = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   debug("Entering interactive session for SSH2.");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ssh->start_time = get_current_time();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   signal(SIGCHLD, sigchld_handler);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   child_terminated = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -608,7 +611,8 @@ server_request_tun(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   debug("Tunnel forwarding using interface %s", ifname);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--      CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  options.hpn_disabled ? CHAN_TCP_WINDOW_DEFAULT : options.hpn_buffer_size,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   c->datagram = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #if defined(SSH_TUN_FILTER)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (mode == SSH_TUNMODE_POINTOPOINT)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -659,6 +663,8 @@ server_request_session(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   c = channel_new(ssh, "session", SSH_CHANNEL_LARVAL,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       0, "server-session", 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((options.tcp_rcv_buf_poll) && (!options.hpn_disabled))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          c->dynamic_window = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (session_open(the_authctxt, c->self) != 1) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           debug("session open failed, free channel %d", c->self);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           channel_free(ssh, c);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/serverloop.h 2019-10-09 02:31:03.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/serverloop.h 2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -20,7 +20,6 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifndef SERVERLOOP_H
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #define SERVERLOOP_H
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- struct ssh;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- void    server_loop2(struct ssh *, Authctxt *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/session.c    2019-11-08 15:37:33.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/session.c    2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -97,6 +97,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "sftp.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "atomicio.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #if defined(KRB5) && defined(USE_AFS)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include <kafs.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -223,6 +224,7 @@ auth_input_request_forwarding(struct ssh
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           goto authsock_err;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* Allocate a channel for the authentication agent socket. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* this shouldn't matter if its hpn or not - cjr */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   nc = channel_new(ssh, "auth socket",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -460,7 +462,7 @@ do_exec_no_pty(struct ssh *ssh, Session 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           return -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   case 0:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           is_child = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            * Create a new session and process group since the 4.4BSD
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            * setlogin() affects the entire process group.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -603,7 +605,7 @@ do_exec_pty(struct ssh *ssh, Session *s,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           return -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   case 0:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           is_child = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           close(fdout);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           close(ptymaster);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2266,10 +2268,11 @@ session_set_fds(struct ssh *ssh, Session
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (s->chanid == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           fatal("no channel for session %d", s->self);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  channel_set_fds(ssh, s->chanid,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--      fdout, fdin, fderr,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--      ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--      1, is_tty, CHAN_SES_WINDOW_DEFAULT);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        channel_set_fds(ssh, s->chanid,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  fdout, fdin, fderr,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  1, is_tty,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  options.hpn_disabled ? CHAN_SES_WINDOW_DEFAULT : options.hpn_buffer_size);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/sftp.1       2019-10-09 02:31:03.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/sftp.1       2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -286,7 +286,8 @@ diagnostic messages from
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- Specify how many requests may be outstanding at any one time.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- Increasing this may slightly improve file transfer speed
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- but will increase memory usage.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--The default is 64 outstanding requests.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+The default is 256 outstanding requests providing for 8MB
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+of outstanding data with a 32KB buffer.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .It Fl r
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- Recursively copy entire directories when uploading and downloading.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- Note that
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/sftp.c       2019-10-09 02:31:03.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/sftp.c       2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -71,7 +71,7 @@ typedef void EditLine;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "sftp-client.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #define DEFAULT_COPY_BUFLEN       32768   /* Size of buffer for up/download */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--#define DEFAULT_NUM_REQUESTS      64      /* # concurrent outstanding requests */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define DEFAULT_NUM_REQUESTS      256     /* # concurrent outstanding requests */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* File to read commands from */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- FILE* infile;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/ssh.c        2019-11-08 15:37:33.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/ssh.c        2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -960,6 +960,10 @@ main(int ac, char **av)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           case 'T':
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   options.request_tty = REQUEST_TTY_NO;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* ensure that the user doesn't try to backdoor a */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* null cipher switch on an interactive session */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* so explicitly disable it no matter what */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  options.none_switch=0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           case 'o':
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   line = xstrdup(optarg);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1585,6 +1589,8 @@ control_persist_detach(void)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   setproctitle("%s [mux]", options.control_path);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+extern const EVP_CIPHER *evp_aes_ctr_mt(void);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* Do fork() after authentication. Used by "ssh -f" */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- fork_postauth(void)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1828,6 +1834,78 @@ ssh_session2_setup(struct ssh *ssh, int 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       NULL, fileno(stdin), command, environ);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+hpn_options_init(void)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * We need to check to see if what they want to do about buffer
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * sizes here. In a hpn to nonhpn connection we want to limit
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * the window size to something reasonable in case the far side
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * has the large window bug. In hpn to hpn connection we want to
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * use the max window size but allow the user to override it
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * lastly if they disabled hpn then use the ssh std window size.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * So why don't we just do a getsockopt() here and set the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * ssh window to that? In the case of a autotuning receive
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * window the window would get stuck at the initial buffer
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * size generally less than 96k. Therefore we need to set the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * maximum ssh window size to the maximum hpn buffer size
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * unless the user has specifically set the tcprcvbufpoll
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * to no. In which case we *can* just set the window to the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * minimum of the hpn buffer size and tcp receive buffer size.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (tty_flag)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          options.hpn_buffer_size = 2 * 1024 * 1024;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (datafellows & SSH_BUG_LARGEWINDOW) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug("HPN to Non-HPN Connection");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          int sock, socksize;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          socklen_t socksizelen;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (options.tcp_rcv_buf_poll <= 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  sock = socket(AF_INET, SOCK_STREAM, 0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  socksizelen = sizeof(socksize);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  getsockopt(sock, SOL_SOCKET, SO_RCVBUF,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                             &socksize, &socksizelen);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  close(sock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug("socksize %d", socksize);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  options.hpn_buffer_size = socksize;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug("HPNBufferSize set to TCP RWIN: %d", options.hpn_buffer_size);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if (options.tcp_rcv_buf > 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                           * Create a socket but don't connect it:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                           * we use that the get the rcv socket size
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                           */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          sock = socket(AF_INET, SOCK_STREAM, 0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                           * If they are using the tcp_rcv_buf option,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                           * attempt to set the buffer size to that.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                           */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if (options.tcp_rcv_buf) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  socksizelen = sizeof(options.tcp_rcv_buf);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                             &options.tcp_rcv_buf, socksizelen);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          socksizelen = sizeof(socksize);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          getsockopt(sock, SOL_SOCKET, SO_RCVBUF,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                     &socksize, &socksizelen);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          close(sock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          debug("socksize %d", socksize);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          options.hpn_buffer_size = socksize;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          debug("HPNBufferSize set to user TCPRcvBuf: %d", options.hpn_buffer_size);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  debug("Final hpn_buffer_size = %d", options.hpn_buffer_size);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* open new channel for a session */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ssh_session2_open(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1854,9 +1932,11 @@ ssh_session2_open(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (!isatty(err))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           set_nonblock(err);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  window = CHAN_SES_WINDOW_DEFAULT;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  window = options.hpn_buffer_size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   packetmax = CHAN_SES_PACKET_DEFAULT;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (tty_flag) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          window = CHAN_SES_WINDOW_DEFAULT;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           window >>= 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           packetmax >>= 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1865,7 +1945,15 @@ ssh_session2_open(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       window, packetmax, CHAN_EXTENDED_WRITE,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       "client-session", /*nonblock*/0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((options.tcp_rcv_buf_poll > 0) && (!options.hpn_disabled)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          c->dynamic_window = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug("Enabled Dynamic Window Scaling");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   debug3("%s: channel_new: %d", __func__, c->self);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options.tcp_rcv_buf_poll > 0 && !options.hpn_disabled) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          c->dynamic_window = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug("Enabled Dynamic Window Scaling");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   channel_send_open(ssh, c->self);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (!no_shell_flag)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1881,6 +1969,20 @@ ssh_session2(struct ssh *ssh, struct pas
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int r, devnull, id = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   char *cp, *tun_fwd_ifname = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * We need to initialize this early because the forwarding logic below
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * might open channels that use the hpn buffer sizes.  We can't send a
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * window of -1 (the default) to the server as it breaks things.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  hpn_options_init();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * We need to initialize this early because the forwarding logic below
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * might open channels that use the hpn buffer sizes.  We can't send a
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * window of -1 (the default) to the server as it breaks things.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  hpn_options_init();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* XXX should be pre-session */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (!options.control_persist)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           ssh_init_stdio_forwarding(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/ssh_api.c    2019-10-09 02:31:03.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/ssh_api.c    2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -389,7 +389,10 @@ _ssh_read_banner(struct ssh *ssh, struct
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   debug("Remote protocol version %d.%d, remote software version %.100s",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       remote_major, remote_minor, remote_version);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  logit("SSH: Server;Ltype: Version;Remote: %s-%d;Protocol: %d.%d;Client: %.100s",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        remote_major, remote_minor, remote_version);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   ssh->compat = compat_datafellows(remote_version);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if  (remote_major == 1 && remote_minor == 99) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           remote_major = 2;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/ssh_api.h    2019-10-09 02:31:03.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/ssh_api.h    2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -29,6 +29,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "ssh.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "ssh2.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "packet.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "log.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- struct kex_params {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   char *proposal[PROPOSAL_MAX];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/sshbuf.h     2019-10-09 02:31:03.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/sshbuf.h     2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -28,7 +28,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # endif /* OPENSSL_HAS_ECC */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif /* WITH_OPENSSL */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--#define SSHBUF_SIZE_MAX           0x8000000       /* Hard maximum size */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define SSHBUF_SIZE_MAX           0xF000000       /* Hard maximum size 256MB */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #define SSHBUF_REFS_MAX           0x100000        /* Max child buffers */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #define SSHBUF_MAX_BIGNUM (16384 / 8)     /* Max bignum *bytes* */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #define SSHBUF_MAX_ECPOINT        ((528 * 2 / 8) + 1) /* Max EC point *bytes* */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/sshconnect.c 2019-10-09 02:31:03.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/sshconnect.c 2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -359,6 +359,30 @@ check_ifaddrs(const char *ifname, int af
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Set TCP receive buffer if requested.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Note: tuning needs to happen after the socket is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * created but before the connection happens
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * so winscale is negotiated properly -cjr
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_set_socket_recvbuf(int sock)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  void *buf = (void *)&options.tcp_rcv_buf;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int sz = sizeof(options.tcp_rcv_buf);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int socksize;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int socksizelen = sizeof(int);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  debug("setsockopt Attempting to set SO_RCVBUF to %d", options.tcp_rcv_buf);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, buf, sz) >= 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &socksize, &socksizelen);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    debug("setsockopt SO_RCVBUF: %.100s %d", strerror(errno), socksize);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          error("Couldn't set socket receive buffer to %d: %.100s",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              options.tcp_rcv_buf, strerror(errno));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  * Creates a socket for use as the ssh connection.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -380,6 +404,9 @@ ssh_create_socket(struct addrinfo *ai)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   fcntl(sock, F_SETFD, FD_CLOEXEC);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options.tcp_rcv_buf > 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh_set_socket_recvbuf(sock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* Bind the socket to an alternative local IP address */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options.bind_address == NULL && options.bind_interface == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           return sock;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/sshconnect2.c        2019-11-08 15:37:33.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/sshconnect2.c        2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -88,6 +88,13 @@ extern char *server_version_string;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- extern Options options;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * tty_flag is set in ssh.c. Use this in ssh_userauth2:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * if it is set, then prevent the switch to the null cipher.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+extern int tty_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  * SSH2 key exchange
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -159,6 +166,8 @@ order_hostkeyalgs(char *host, struct soc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return ret;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static char *myproposal[PROPOSAL_MAX];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static const char *myproposal_default[PROPOSAL_MAX] = { KEX_CLIENT };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -166,6 +175,8 @@ ssh_kex2(struct ssh *ssh, char *host, st
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   char *s, *all_key;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  memcpy(&myproposal, &myproposal_default, sizeof(myproposal));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   xxx_host = host;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   xxx_hostaddr = hostaddr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -427,6 +438,47 @@ ssh_userauth2(struct ssh *ssh, const cha
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (!authctxt.success)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           fatal("Authentication failed.");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * If the user wants to use the none cipher, do it post authentication
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * and only if the right conditions are met -- both of the NONE commands
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * must be true and there must be no tty allocated.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((options.none_switch == 1) && (options.none_enabled == 1)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (!tty_flag) { /* no null on tty sessions */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug("Requesting none rekeying...");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  memcpy(&myproposal, &myproposal_default, sizeof(myproposal));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  myproposal[PROPOSAL_ENC_ALGS_STOC] = "none";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  myproposal[PROPOSAL_ENC_ALGS_CTOS] = "none";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  kex_prop2buf(ssh->kex->my, myproposal);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  packet_request_rekeying();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  fprintf(stderr, "WARNING: ENABLED NONE CIPHER\n");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* requested NONE cipher when in a tty */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug("Cannot switch to NONE cipher with tty allocated");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  fprintf(stderr, "NONE cipher switch disabled when a TTY is allocated\n");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef WITH_OPENSSL
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options.disable_multithreaded == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* if we are using aes-ctr there can be issues in either a fork or sandbox
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * so the initial aes-ctr is defined to point to the original single process
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * evp. After authentication we'll be past the fork and the sandboxed privsep
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * so we repoint the define to the multithreaded evp. To start the threads we
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * then force a rekey
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          const void *cc = ssh_packet_get_send_context(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* only do this for the ctr cipher. otherwise gcm mode breaks. Don't know why though */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (strstr(cipher_ctx_name(cc), "ctr")) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug("Single to Multithread CTR cipher swap - client request");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  cipher_reset_multithreaded();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  packet_request_rekeying();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   debug("Authentication succeeded (%s).", authctxt.method->name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/sshd.c       2019-11-08 15:37:33.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/sshd.c       2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1019,6 +1019,8 @@ listen_on_addrs(struct listenaddr *la)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int ret, listen_sock;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   struct addrinfo *ai;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   char ntop[NI_MAXHOST], strport[NI_MAXSERV];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int socksize;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int socksizelen = sizeof(int);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   for (ai = la->addrs; ai; ai = ai->ai_next) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1064,6 +1066,11 @@ listen_on_addrs(struct listenaddr *la)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           debug("Bind to port %s on %s.", strport, ntop);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          getsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                             &socksize, &socksizelen);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug("Server TCP RWIN socket size: %d", socksize);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug("HPN Buffer Size: %d", options.hpn_buffer_size);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           /* Bind the socket to the desired port. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) == -1) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   error("Bind to port %s on %s failed: %.200s.",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1705,6 +1712,13 @@ main(int ac, char **av)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* Fill in default values for those options not explicitly set. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   fill_default_server_options(&options);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options.none_enabled == 1) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          char *old_ciphers = options.ciphers;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          xasprintf(&options.ciphers, "%s,none", old_ciphers);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          free(old_ciphers);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* challenge-response is implemented via keyboard interactive */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options.challenge_response_authentication)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           options.kbd_interactive_authentication = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2138,6 +2152,9 @@ main(int ac, char **av)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       rdomain == NULL ? "" : "\"");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   free(laddr);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* set the HPN options for the child */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    * We don't want to listen forever unless the other side
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    * successfully authenticates itself.  So we set up an alarm which is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2244,7 +2261,45 @@ main(int ac, char **av)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* Try to send all our hostkeys to the client */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   notify_hostkeys(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef WITH_OPENSSL
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options.disable_multithreaded == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* if we are using aes-ctr there can be issues in either a fork or sandbox
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * so the initial aes-ctr is defined to point ot the original single process
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * evp. After authentication we'll be past the fork and the sandboxed privsep
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * so we repoint the define to the multithreaded evp. To start the threads we
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * then force a rekey
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          const void *cc = ssh_packet_get_send_context(the_active_state);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* only rekey if necessary. If we don't do this gcm mode cipher breaks */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (strstr(cipher_ctx_name(cc), "ctr")) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug("Single to Multithreaded CTR cipher swap - server request");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  cipher_reset_multithreaded();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  packet_request_rekeying();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* Start session. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef WITH_OPENSSL
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options.disable_multithreaded == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* if we are using aes-ctr there can be issues in either a fork or sandbox
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * so the initial aes-ctr is defined to point ot the original single process
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * evp. After authentication we'll be past the fork and the sandboxed privsep
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * so we repoint the define to the multithreaded evp. To start the threads we
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * then force a rekey
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          const void *cc = ssh_packet_get_send_context(the_active_state);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* only rekey if necessary. If we don't do this gcm mode cipher breaks */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (strstr(cipher_ctx_name(cc), "ctr")) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug("Single to Multithreaded CTR cipher swap - server request");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  cipher_reset_multithreaded();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  packet_request_rekeying();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   do_authenticated(ssh, authctxt);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* The connection has been terminated. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2313,6 +2368,9 @@ do_ssh2_kex(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   struct kex *kex;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options.none_enabled == 1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug("WARNING: None cipher enabled");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       options.kex_algorithms);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/sshd_config  2019-11-08 15:37:33.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/sshd_config  2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -111,6 +111,19 @@ AcceptEnv LANG LC_*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # override default of no subsystems
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- Subsystem sftp    /usr/libexec/sftp-server
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# the following are HPN related configuration options
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# tcp receive buffer polling. disable in non autotuning kernels
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#TcpRcvBufPoll yes
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# disable hpn performance boosts
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#HPNDisabled no
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# buffer size for hpn to non-hpn connections
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#HPNBufferSize 2048
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# allow the use of the none cipher
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#NoneEnabled no
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # Example of overriding settings on a per-user basis
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #Match User anoncvs
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # X11Forwarding no
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/version.h    2019-10-09 02:31:03.000000000 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/version.h    2019-11-08 15:37:59.000000000 +0100
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -3,4 +3,5 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #define SSH_VERSION       "OpenSSH_8.1"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #define SSH_PORTABLE      "p1"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--#define SSH_RELEASE       SSH_VERSION SSH_PORTABLE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define SSH_HPN         "-hpn14v18"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define SSH_RELEASE       SSH_VERSION SSH_PORTABLE SSH_HPN
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/net/openssh/files/openssh-8.8p1-gsskex.patch b/net/openssh/files/openssh-8.8p1-gsskex.patch
</span>deleted file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index ef073f651d0..00000000000
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/net/openssh/files/openssh-8.8p1-gsskex.patch
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,4033 +0,0 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-====== OVERVIEW SECTION ======
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-This file has some content from the previous version of the patch that
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-applied cleanly to 8.4p1.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-====== TEXT FROM 8.4p1 VERSION ======
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-From 1c1b6fa17982eb622e2c4e8f4a279f2113f57413 Mon Sep 17 00:00:00 2001
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-From: Simon Wilkinson <simon@sxw.org.uk>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-Date: Sun, 9 Feb 2014 16:09:48 +0000
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-Subject: GSSAPI key exchange support
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-This patch has been rejected upstream: "None of the OpenSSH developers are
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-in favour of adding this, and this situation has not changed for several
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-years.  This is not a slight on Simon's patch, which is of fine quality, but
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-just that a) we don't trust GSSAPI implementations that much and b) we don't
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-like adding new KEX since they are pre-auth attack surface.  This one is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-particularly scary, since it requires hooks out to typically root-owned
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-system resources."
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-However, quite a lot of people rely on this in Debian, and it's better to
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-have it merged into the main openssh package rather than having separate
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--krb5 packages (as we used to have).  It seems to have a generally good
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-security history.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1242
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-Last-Updated: 2014-10-07
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-Patch-Name: gssapi.patch
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-====== PATCH SECTION ======
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-The below was created using the following commands:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-$ git clone https://github.com/openssh-gsskex/openssh-gsskex.git
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-$ cd openssh-gsskex
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-$ git diff bf944e37..261d3de3
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# bf944e37 corresponds to the upstream V_8_8_P1 tags in
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# https://github.com/openssh/openssh-portable.git
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-#
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# 261d3de3 corresponds to the proposed commit from
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# https://github.com/openssh-gsskex/openssh-gsskex/pull/23
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/.travis.yml b/.travis.yml
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-new file mode 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 00000000..5ba9985d
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- /dev/null
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/.travis.yml
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,27 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+language: c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+dist: bionic
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+compiler:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  - clang
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  - gcc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# Run only unit tests. Without OpenSSL, some additional tests in makefile do not work
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+env:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  - CONFIGURE=--with-kerberos5=auto                   TESTS="file-tests"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  - CONFIGURE=--without-kerberos5                     TESTS="file-tests"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  - CONFIGURE=--with-kerberos5=auto --without-openssl TESTS=""
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  - CONFIGURE=--without-kerberos5 --without-openssl   TESTS=""
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+addons:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  apt_packages:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    - libssl-dev
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    - libkrb5-dev
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+before_script:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  - autoreconf
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  - ./configure $CONFIGURE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+script:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  - make
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  - # make tests
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  - make unit $TESTS
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/Makefile.in b/Makefile.in
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index b0293841..b0e76f01 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/Makefile.in
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/Makefile.in
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -108,6 +108,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   kexgexc.o kexgexs.o \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   kexsntrup761x25519.o sntrup761.o kexgen.o \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  kexgssc.o \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   sshbuf-io.o
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -124,7 +125,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   auth2-none.o auth2-passwd.o auth2-pubkey.o \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   monitor.o monitor_wrap.o auth-krb5.o \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  auth2-gss.o gss-serv.o gss-serv-krb5.o \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   srclimit.o sftp-server.o sftp-common.o \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/README.md b/README.md
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index de471773..53d98ade 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/README.md
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/README.md
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1,3 +1,39 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Portable OpenSSH with GSSAPI Key Exchange patches
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+=================================================
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+[![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/openssh-gsskex/openssh-gsskex.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/openssh-gsskex/openssh-gsskex/context:cpp)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Currently, there are two branches with gssapi key exchange related
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+patches:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * fedora/master: Changes that are shipped in Fedora [![Build Status](https://travis-ci.org/openssh-gsskex/openssh-gsskex.svg?branch=fedora%2Fmaster)](https://travis-ci.org/openssh-gsskex/openssh-gsskex)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * debian/master: Changes that are shipped in Debian [![Build Status](https://travis-ci.org/openssh-gsskex/openssh-gsskex.svg?branch=debian%2Fmaster)](https://travis-ci.org/openssh-gsskex/openssh-gsskex)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+The target is to converge to a shared repository with single master
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+branch from where we could build releases for both OSes.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+What is in:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * The original patch implementing missing parts of RFC4462 by Simon Wilkinson
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   adapted to the current OpenSSH versions and with several fixes
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * New methods for GSSAPI Kex from IETF draft [1] from Jakub Jelen
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Missing kerberos-related parts:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * .k5login and .kusers support available in Fedora [2] [3].
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Improved handling of kerberos ccache location [4]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+[1] https://tools.ietf.org/html/draft-ietf-curdle-gss-keyex-sha2-08
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+[2] https://src.fedoraproject.org/rpms/openssh/blob/master/f/openssh-6.6p1-kuserok.patch
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+[3] https://src.fedoraproject.org/rpms/openssh/blob/master/f/openssh-6.6p1-GSSAPIEnablek5users.patch
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+[4] https://bugzilla.mindrot.org/show_bug.cgi?id=2775
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+-------------------------------------------------------------------------------
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # Portable OpenSSH
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- [![C/C++ CI](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/auth.c b/auth.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 00b168b4..704dc2e7 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/auth.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/auth.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -402,7 +402,8 @@ auth_root_allowed(struct ssh *ssh, const char *method)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   case PERMIT_NO_PASSWD:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           if (strcmp(method, "publickey") == 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-               strcmp(method, "hostbased") == 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--              strcmp(method, "gssapi-with-mic") == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              strcmp(method, "gssapi-with-mic") == 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              strcmp(method, "gssapi-keyex") == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   return 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   case PERMIT_FORCED_ONLY:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -729,97 +730,6 @@ fakepw(void)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return (&fake);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-- * Returns the remote DNS hostname as a string. The returned string must not
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-- * be freed. NB. this will usually trigger a DNS query the first time it is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-- * called.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-- * This function does additional checks on the hostname to mitigate some
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-- * attacks on based on conflation of hostnames and IP addresses.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-- */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--static char *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--remote_hostname(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  struct sockaddr_storage from;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  socklen_t fromlen;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  struct addrinfo hints, *ai, *aitop;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  char name[NI_MAXHOST], ntop2[NI_MAXHOST];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  const char *ntop = ssh_remote_ipaddr(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  /* Get IP address of client. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  fromlen = sizeof(from);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  memset(&from, 0, sizeof(from));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  if (getpeername(ssh_packet_get_connection_in(ssh),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--      (struct sockaddr *)&from, &fromlen) == -1) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          debug("getpeername failed: %.100s", strerror(errno));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          return xstrdup(ntop);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  ipv64_normalise_mapped(&from, &fromlen);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  if (from.ss_family == AF_INET6)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          fromlen = sizeof(struct sockaddr_in6);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  debug3("Trying to reverse map address %.100s.", ntop);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  /* Map the IP address to a host name. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--      NULL, 0, NI_NAMEREQD) != 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          /* Host name not found.  Use ip address. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          return xstrdup(ntop);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--   * if reverse lookup result looks like a numeric hostname,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--   * someone is trying to trick us by PTR record like following:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--   *      1.1.1.10.in-addr.arpa.  IN PTR  2.3.4.5
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--   */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  memset(&hints, 0, sizeof(hints));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  hints.ai_socktype = SOCK_DGRAM; /*dummy*/
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  hints.ai_flags = AI_NUMERICHOST;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  if (getaddrinfo(name, NULL, &hints, &ai) == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          logit("Nasty PTR record \"%s\" is set up for %s, ignoring",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--              name, ntop);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          freeaddrinfo(ai);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          return xstrdup(ntop);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  /* Names are stored in lowercase. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  lowercase(name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--   * Map it back to an IP address and check that the given
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--   * address actually is an address of this host.  This is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--   * necessary because anyone with access to a name server can
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--   * define arbitrary names for an IP address. Mapping from
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--   * name to IP address can be trusted better (but can still be
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--   * fooled if the intruder has access to the name server of
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--   * the domain).
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--   */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  memset(&hints, 0, sizeof(hints));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  hints.ai_family = from.ss_family;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  hints.ai_socktype = SOCK_STREAM;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  if (getaddrinfo(name, NULL, &hints, &aitop) != 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          logit("reverse mapping checking getaddrinfo for %.700s "
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--              "[%s] failed.", name, ntop);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          return xstrdup(ntop);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  /* Look for the address from the list of addresses. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  for (ai = aitop; ai; ai = ai->ai_next) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--              sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 &&
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--              (strcmp(ntop, ntop2) == 0))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                          break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  freeaddrinfo(aitop);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  /* If we reached the end of the list, the address was not there. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  if (ai == NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          /* Address not found for the host name. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          logit("Address %.100s maps to %.600s, but this does not "
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--              "map back to the address.", ntop, name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          return xstrdup(ntop);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  return xstrdup(name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  * Return the canonical name of the host in the other side of the current
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  * connection.  The host name is cached, so it is efficient to call this
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/auth2-gss.c b/auth2-gss.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 60e36961..2e9aad3f 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/auth2-gss.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/auth2-gss.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1,7 +1,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* $OpenBSD: auth2-gss.c,v 1.32 2021/01/27 10:15:08 djm Exp $ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  * Redistribution and use in source and binary forms, with or without
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  * modification, are permitted provided that the following conditions
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -55,6 +55,48 @@ static int input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static int input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static int input_gssapi_errtok(int, u_int32_t, struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * The 'gssapi_keyex' userauth mechanism.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+userauth_gsskeyex(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  Authctxt *authctxt = ssh->authctxt;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int r, authenticated = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshbuf *b = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_buffer_desc mic, gssbuf;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_char *p;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  size_t len;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_get_end(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_fr(r, "parsing");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((b = sshbuf_new()) == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_f("sshbuf_new failed");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  mic.value = p;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  mic.length = len;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ssh_gssapi_buildmic(b, authctxt->user, authctxt->service,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      "gssapi-keyex", ssh->kex->session_id);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_f("sshbuf_mutable_ptr failed");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gssbuf.length = sshbuf_len(b);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* gss_kex_context is NULL with privsep, so we can't check it here */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      &gssbuf, &mic))))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              authctxt->pw, 1));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(b);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  free(mic.value);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return (authenticated);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  * We only support those mechanisms that we know about (ie ones that we know
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  * how to check local user kuserok and the like)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -261,7 +303,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if ((r = sshpkt_get_end(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           fatal_fr(r, "parse packet");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      authctxt->pw, 1));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if ((!use_privsep || mm_is_monitor()) &&
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       (displayname = ssh_gssapi_displayname()) != NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -307,7 +350,8 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   gssbuf.length = sshbuf_len(b);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              authctxt->pw, 0));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           logit("GSSAPI MIC check failed");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -327,6 +371,12 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Authmethod method_gsskeyex = {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  "gssapi-keyex",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  userauth_gsskeyex,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  &options.gss_authentication
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- Authmethod method_gssapi = {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   "gssapi-with-mic",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   userauth_gssapi,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/auth2.c b/auth2.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 84d0ed16..f905d5a3 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/auth2.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/auth2.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -71,6 +71,7 @@ extern Authmethod method_passwd;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- extern Authmethod method_kbdint;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- extern Authmethod method_hostbased;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+extern Authmethod method_gsskeyex;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- extern Authmethod method_gssapi;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -78,6 +79,7 @@ Authmethod *authmethods[] = {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   &method_none,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   &method_pubkey,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  &method_gsskeyex,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   &method_gssapi,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   &method_passwd,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/canohost.c b/canohost.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index a810da0e..99f1cd40 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/canohost.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/canohost.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -35,6 +35,97 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "canohost.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "misc.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Returns the remote DNS hostname as a string. The returned string must not
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * be freed. NB. this will usually trigger a DNS query the first time it is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * called.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * This function does additional checks on the hostname to mitigate some
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * attacks on legacy rhosts-style authentication.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+char *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+remote_hostname(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sockaddr_storage from;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  socklen_t fromlen;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct addrinfo hints, *ai, *aitop;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char name[NI_MAXHOST], ntop2[NI_MAXHOST];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  const char *ntop = ssh_remote_ipaddr(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Get IP address of client. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  fromlen = sizeof(from);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  memset(&from, 0, sizeof(from));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (getpeername(ssh_packet_get_connection_in(ssh),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (struct sockaddr *)&from, &fromlen) == -1) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug("getpeername failed: %.100s", strerror(errno));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return xstrdup(ntop);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ipv64_normalise_mapped(&from, &fromlen);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (from.ss_family == AF_INET6)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fromlen = sizeof(struct sockaddr_in6);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  debug3("Trying to reverse map address %.100s.", ntop);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Map the IP address to a host name. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      NULL, 0, NI_NAMEREQD) != 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* Host name not found.  Use ip address. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return xstrdup(ntop);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * if reverse lookup result looks like a numeric hostname,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * someone is trying to trick us by PTR record like following:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   *      1.1.1.10.in-addr.arpa.  IN PTR  2.3.4.5
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  memset(&hints, 0, sizeof(hints));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  hints.ai_socktype = SOCK_DGRAM; /*dummy*/
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  hints.ai_flags = AI_NUMERICHOST;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (getaddrinfo(name, NULL, &hints, &ai) == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          logit("Nasty PTR record \"%s\" is set up for %s, ignoring",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              name, ntop);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          freeaddrinfo(ai);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return xstrdup(ntop);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Names are stored in lowercase. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  lowercase(name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * Map it back to an IP address and check that the given
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * address actually is an address of this host.  This is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * necessary because anyone with access to a name server can
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * define arbitrary names for an IP address. Mapping from
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * name to IP address can be trusted better (but can still be
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * fooled if the intruder has access to the name server of
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * the domain).
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  memset(&hints, 0, sizeof(hints));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  hints.ai_family = from.ss_family;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  hints.ai_socktype = SOCK_STREAM;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (getaddrinfo(name, NULL, &hints, &aitop) != 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          logit("reverse mapping checking getaddrinfo for %.700s "
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              "[%s] failed.", name, ntop);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return xstrdup(ntop);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Look for the address from the list of addresses. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for (ai = aitop; ai; ai = ai->ai_next) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 &&
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              (strcmp(ntop, ntop2) == 0))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  freeaddrinfo(aitop);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* If we reached the end of the list, the address was not there. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (ai == NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* Address not found for the host name. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          logit("Address %.100s maps to %.600s, but this does not "
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              "map back to the address.", ntop, name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return xstrdup(ntop);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return xstrdup(name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/canohost.h b/canohost.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 26d62855..0cadc9f1 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/canohost.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/canohost.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -15,6 +15,9 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifndef _CANOHOST_H
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #define _CANOHOST_H
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+struct ssh;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+char              *remote_hostname(struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- char              *get_peer_ipaddr(int);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int                get_peer_port(int);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- char              *get_local_ipaddr(int);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/clientloop.c b/clientloop.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index da14d150..d784ddc9 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/clientloop.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/clientloop.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -112,6 +112,10 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "ssherr.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "hostfile.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "ssh-gss.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* import options */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- extern Options options;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1343,9 +1347,18 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           /* Do channel operations unless rekeying in progress. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          if (!ssh_packet_is_rekeying(ssh))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (!ssh_packet_is_rekeying(ssh)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   channel_after_select(ssh, readset, writeset);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if (options.gss_renewal_rekey &&
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      ssh_gssapi_credentials_updated(NULL)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          debug("credentials updated - forcing rekey");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          need_rekeying = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           /* Buffer input from the connection.  */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           client_process_net_input(ssh, readset);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/configure.ac b/configure.ac
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 413913a7..29de0ef0 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/configure.ac
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/configure.ac
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -709,6 +709,30 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       [Use tunnel device compatibility to OpenBSD])
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   AC_DEFINE([SSH_TUN_PREPEND_AF], [1],
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       [Prepend the address family to IP tunnel traffic])
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  AC_MSG_CHECKING([if we have the Security Authorization Session API])
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  AC_TRY_COMPILE([#include <Security/AuthSession.h>],
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          [SessionCreate(0, 0);],
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          [ac_cv_use_security_session_api="yes"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           AC_DEFINE([USE_SECURITY_SESSION_API], [1],
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  [platform has the Security Authorization Session API])
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           LIBS="$LIBS -framework Security"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           AC_MSG_RESULT([yes])],
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          [ac_cv_use_security_session_api="no"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           AC_MSG_RESULT([no])])
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  AC_MSG_CHECKING([if we have an in-memory credentials cache])
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  AC_TRY_COMPILE(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          [#include <Kerberos/Kerberos.h>],
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          [cc_context_t c;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           (void) cc_initialize (&c, 0, NULL, NULL);],
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          [AC_DEFINE([USE_CCAPI], [1],
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  [platform uses an in-memory credentials cache])
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           LIBS="$LIBS -framework Security"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           AC_MSG_RESULT([yes])
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           if test "x$ac_cv_use_security_session_api" = "xno"; then
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  AC_MSG_ERROR([*** Need a security framework to use the credentials cache API ***])
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fi],
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          [AC_MSG_RESULT([no])]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   m4_pattern_allow([AU_IPv])
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   AC_CHECK_DECL([AU_IPv4], [],
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records])
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/gss-genr.c b/gss-genr.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 68528051..cede661b 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/gss-genr.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/gss-genr.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1,7 +1,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* $OpenBSD: gss-genr.c,v 1.28 2021/01/27 10:05:28 djm Exp $ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-- * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  * Redistribution and use in source and binary forms, with or without
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  * modification, are permitted provided that the following conditions
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -41,9 +41,33 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "sshbuf.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "log.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "ssh2.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "cipher.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "sshkey.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "kex.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "digest.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "packet.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "ssh-gss.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+typedef struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char *encoded;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_OID oid;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+} ssh_gss_kex_mapping;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * XXX - It would be nice to find a more elegant way of handling the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * XXX   passing of the key exchange context to the userauth routines
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Gssctxt *gss_kex_context = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static ssh_gss_kex_mapping *gss_enc2oid = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_gssapi_oid_table_ok(void) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return (gss_enc2oid != NULL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* sshbuf_get for gss_buffer_desc */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -59,6 +83,159 @@ ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* sshpkt_get of gss_buffer_desc */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_gssapi_sshpkt_get_buffer_desc(struct ssh *ssh, gss_buffer_desc *g)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_char *p;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  size_t len;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = sshpkt_get_string(ssh, &p, &len)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  g->value = p;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  g->length = len;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Return a list of the gss-group1-sha1 mechanisms supported by this program
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * We test mechanisms to ensure that we can use them, to avoid starting
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * a key exchange with a bad mechanism
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+char *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_gssapi_client_mechanisms(const char *host, const char *client,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    const char *kex) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_OID_set gss_supported = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  OM_uint32 min_status;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (GSS_ERROR(gss_indicate_mechs(&min_status, &gss_supported)))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      host, client, kex);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+char *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    const char *host, const char *client, const char *kex) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshbuf *buf = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  size_t i;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int r = SSH_ERR_ALLOC_FAIL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int oidpos, enclen;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char *mechs, *encoded;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_char digest[SSH_DIGEST_MAX_LENGTH];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char deroid[2];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct ssh_digest_ctx *md = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char *s, *cp, *p;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (gss_enc2oid != NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          for (i = 0; gss_enc2oid[i].encoded != NULL; i++)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  free(gss_enc2oid[i].encoded);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          free(gss_enc2oid);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_enc2oid = xmalloc(sizeof(ssh_gss_kex_mapping) *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (gss_supported->count + 1));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((buf = sshbuf_new()) == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_f("sshbuf_new failed");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  oidpos = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  s = cp = xstrdup(kex);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for (i = 0; i < gss_supported->count; i++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (gss_supported->elements[i].length < 128 &&
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              (*check)(NULL, &(gss_supported->elements[i]), host, client)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  deroid[0] = SSH_GSS_OIDTYPE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  deroid[1] = gss_supported->elements[i].length;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      (r = ssh_digest_update(md, deroid, 2)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      (r = ssh_digest_update(md,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          gss_supported->elements[i].elements,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          gss_supported->elements[i].length)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      (r = ssh_digest_final(md, digest, sizeof(digest))) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal_fr(r, "digest failed");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  ssh_digest_free(md);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  md = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  encoded = xmalloc(ssh_digest_bytes(SSH_DIGEST_MD5)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      * 2);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  enclen = __b64_ntop(digest,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      ssh_digest_bytes(SSH_DIGEST_MD5), encoded,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      ssh_digest_bytes(SSH_DIGEST_MD5) * 2);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  cp = strncpy(s, kex, strlen(kex));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  for ((p = strsep(&cp, ",")); p && *p != '\0';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          (p = strsep(&cp, ","))) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if (sshbuf_len(buf) != 0 &&
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = sshbuf_put_u8(buf, ',')) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  fatal_fr(r, "sshbuf_put_u8 error");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if ((r = sshbuf_put(buf, p, strlen(p))) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = sshbuf_put(buf, encoded, enclen)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  fatal_fr(r, "sshbuf_put error");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  gss_enc2oid[oidpos].encoded = encoded;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  oidpos++;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  free(s);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_enc2oid[oidpos].oid = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_enc2oid[oidpos].encoded = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((mechs = sshbuf_dup_string(buf)) == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_f("sshbuf_dup_string failed");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(buf);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (strlen(mechs) == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          free(mechs);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          mechs = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return (mechs);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+gss_OID
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int i = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define SKIP_KEX_NAME(type) \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case type: \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (strlen(name) < sizeof(type##_ID)) \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  return GSS_C_NO_OID; \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          name += sizeof(type##_ID) - 1; \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  switch (kex_type) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SKIP_KEX_NAME(KEX_GSS_GRP1_SHA1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SKIP_KEX_NAME(KEX_GSS_GRP14_SHA1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SKIP_KEX_NAME(KEX_GSS_GRP14_SHA256)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SKIP_KEX_NAME(KEX_GSS_GRP16_SHA512)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SKIP_KEX_NAME(KEX_GSS_GEX_SHA1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SKIP_KEX_NAME(KEX_GSS_NISTP256_SHA256)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SKIP_KEX_NAME(KEX_GSS_C25519_SHA256)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  default:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return GSS_C_NO_OID;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#undef SKIP_KEX_NAME
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  while (gss_enc2oid[i].encoded != NULL &&
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      strcmp(name, gss_enc2oid[i].encoded) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          i++;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (gss_enc2oid[i].oid != NULL && ctx != NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh_gssapi_set_oid(ctx, gss_enc2oid[i].oid);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return gss_enc2oid[i].oid;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* Check that the OID in a data stream matches that in the context */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -215,7 +392,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   ctx->major = gss_init_sec_context(&ctx->minor,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--      GSS_C_NO_CREDENTIAL, &ctx->context, ctx->name, ctx->oid,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      ctx->client_creds, &ctx->context, ctx->name, ctx->oid,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       0, NULL, recv_tok, NULL, send_tok, flags, NULL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -244,9 +421,43 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return (ctx->major);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+OM_uint32
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_gssapi_client_identity(Gssctxt *ctx, const char *name)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_buffer_desc gssbuf;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_name_t gssname;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  OM_uint32 status;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_OID_set oidset;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gssbuf.value = (void *) name;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gssbuf.length = strlen(gssbuf.value);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_create_empty_oid_set(&status, &oidset);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_add_oid_set_member(&status, ctx->oid, &oidset);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ctx->major = gss_import_name(&ctx->minor, &gssbuf,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      GSS_C_NT_USER_NAME, &gssname);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!ctx->major)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ctx->major = gss_acquire_cred(&ctx->minor,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              gssname, 0, oidset, GSS_C_INITIATE,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              &ctx->client_creds, NULL, NULL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_release_name(&status, &gssname);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_release_oid_set(&status, &oidset);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (ctx->major)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh_gssapi_error(ctx);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return(ctx->major);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- OM_uint32
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (ctx == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       GSS_C_QOP_DEFAULT, buffer, hash)))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           ssh_gssapi_error(ctx);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -254,6 +465,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return (ctx->major);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* Priviledged when used by server */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+OM_uint32
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (ctx == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ctx->major = gss_verify_mic(&ctx->minor, ctx->context,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      gssbuf, gssmic, NULL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return (ctx->major);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     const char *context, const struct sshbuf *session_id)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -270,11 +494,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    const char *client)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   OM_uint32 major, minor;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   gss_OID_desc spnego_oid = {6, (void *)"\x2B\x06\x01\x05\x05\x02"};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  Gssctxt *intctx = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (ctx == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ctx = &intctx;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* RFC 4462 says we MUST NOT do SPNEGO */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (oid->length == spnego_oid.length && 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -284,6 +513,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   ssh_gssapi_build_ctx(ctx);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   ssh_gssapi_set_oid(*ctx, oid);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   major = ssh_gssapi_import_name(*ctx, host);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!GSS_ERROR(major) && client)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          major = ssh_gssapi_client_identity(*ctx, client);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (!GSS_ERROR(major)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-               NULL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -293,10 +526,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                       GSS_C_NO_BUFFER);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  if (GSS_ERROR(major)) 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (GSS_ERROR(major) || intctx != NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           ssh_gssapi_delete_ctx(ctx);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return (!GSS_ERROR(major));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_gssapi_credentials_updated(Gssctxt *ctxt) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  static gss_name_t saved_name = GSS_C_NO_NAME;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  static OM_uint32 saved_lifetime = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  static gss_OID saved_mech = GSS_C_NO_OID;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  static gss_name_t name;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  static OM_uint32 last_call = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  OM_uint32 lifetime, now, major, minor;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int equal;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  now = time(NULL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (ctxt) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug("Rekey has happened - updating saved versions");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (saved_name != GSS_C_NO_NAME)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  gss_release_name(&minor, &saved_name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              &saved_name, &saved_lifetime, NULL, NULL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (!GSS_ERROR(major)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  saved_mech = ctxt->oid;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  saved_lifetime+= now;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* Handle the error */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (now - last_call < 10)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  last_call = now;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (saved_mech == GSS_C_NO_OID)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      &name, &lifetime, NULL, NULL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (major == GSS_S_CREDENTIALS_EXPIRED)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  else if (GSS_ERROR(major))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  major = gss_compare_name(&minor, saved_name, name, &equal);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_release_name(&minor, &name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (GSS_ERROR(major))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (equal && (saved_lifetime < lifetime + now - 10))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif /* GSSAPI */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index a151bc1e..ef20401e 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/gss-serv-krb5.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/gss-serv-krb5.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1,7 +1,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* $OpenBSD: gss-serv-krb5.c,v 1.9 2018/07/09 21:37:55 markus Exp $ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  * Redistribution and use in source and binary forms, with or without
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  * modification, are permitted provided that the following conditions
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -120,7 +120,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   krb5_error_code problem;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   krb5_principal princ;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   OM_uint32 maj_status, min_status;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  int len;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  const char *new_ccname;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   const char *errmsg;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (client->creds == NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -180,11 +180,16 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  new_ccname = krb5_cc_get_name(krb_context, ccache);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   client->store.envvar = "KRB5CCNAME";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  len = strlen(client->store.filename) + 6;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  client->store.envval = xmalloc(len);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  snprintf(client->store.envval, len, "FILE:%s", client->store.filename);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef USE_CCAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  xasprintf(&client->store.envval, "API:%s", new_ccname);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  client->store.filename = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  xasprintf(&client->store.envval, "FILE:%s", new_ccname);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  client->store.filename = xstrdup(new_ccname);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef USE_PAM
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options.use_pam)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -193,9 +198,76 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   krb5_cc_close(krb_context, ccache);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  client->store.data = krb_context;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    ssh_gssapi_client *client)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  krb5_ccache ccache = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  krb5_principal principal = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char *name = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  krb5_error_code problem;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  OM_uint32 maj_status, min_status;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((problem = krb5_cc_resolve(krb_context, store->envval, &ccache))) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                logit("krb5_cc_resolve(): %.100s",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                    krb5_get_err_text(krb_context, problem));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Find out who the principal in this cache is */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((problem = krb5_cc_get_principal(krb_context, ccache,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      &principal))) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          logit("krb5_cc_get_principal(): %.100s",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              krb5_get_err_text(krb_context, problem));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          krb5_cc_close(krb_context, ccache);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((problem = krb5_unparse_name(krb_context, principal, &name))) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          logit("krb5_unparse_name(): %.100s",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              krb5_get_err_text(krb_context, problem));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          krb5_free_principal(krb_context, principal);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          krb5_cc_close(krb_context, ccache);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (strcmp(name,client->exportedname.value)!=0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug("Name in local credentials cache differs. Not storing");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          krb5_free_principal(krb_context, principal);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          krb5_cc_close(krb_context, ccache);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          krb5_free_unparsed_name(krb_context, name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  krb5_free_unparsed_name(krb_context, name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Name matches, so lets get on with it! */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((problem = krb5_cc_initialize(krb_context, ccache, principal))) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          logit("krb5_cc_initialize(): %.100s",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              krb5_get_err_text(krb_context, problem));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          krb5_free_principal(krb_context, principal);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          krb5_cc_close(krb_context, ccache);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  krb5_free_principal(krb_context, principal);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      ccache))) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          logit("gss_krb5_copy_ccache() failed. Sorry!");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          krb5_cc_close(krb_context, ccache);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ssh_gssapi_mech gssapi_kerberos_mech = {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   "toWM5Slw5Ew8Mqkay+al2g==",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   "Kerberos",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -203,7 +275,8 @@ ssh_gssapi_mech gssapi_kerberos_mech = {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   NULL,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   &ssh_gssapi_krb5_userok,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   NULL,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  &ssh_gssapi_krb5_storecreds
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  &ssh_gssapi_krb5_storecreds,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  &ssh_gssapi_krb5_updatecreds
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif /* KRB5 */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/gss-serv.c b/gss-serv.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index b5d4bb2d..4287579a 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/gss-serv.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/gss-serv.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1,7 +1,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* $OpenBSD: gss-serv.c,v 1.32 2020/03/13 03:17:07 djm Exp $ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  * Redistribution and use in source and binary forms, with or without
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  * modification, are permitted provided that the following conditions
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -44,17 +44,19 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "session.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "misc.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "servconf.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "uidswap.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "ssh-gss.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "monitor_wrap.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- extern ServerOptions options;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static ssh_gssapi_client gssapi_client =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL, NULL}};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, GSS_C_NO_CREDENTIAL,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, 0, 0};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ssh_gssapi_mech gssapi_null_mech =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef KRB5
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- extern ssh_gssapi_mech gssapi_kerberos_mech;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -140,6 +142,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return (ssh_gssapi_acquire_cred(*ctx));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* Unprivileged */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+char *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_gssapi_server_mechanisms(void) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (supported_oids == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh_gssapi_prepare_supported_oids();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return (ssh_gssapi_kex_mechs(supported_oids,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      &ssh_gssapi_server_check_mech, NULL, NULL,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      options.gss_kex_algorithms));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* Unprivileged */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_gssapi_server_check_mech(Gssctxt **dum, gss_OID oid, const char *data,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    const char *dummy) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  Gssctxt *ctx = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int res;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid)));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ssh_gssapi_delete_ctx(&ctx);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return (res);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* Unprivileged */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ssh_gssapi_supported_oids(gss_OID_set *oidset)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -150,7 +175,9 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   gss_OID_set supported;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   gss_create_empty_oid_set(&min_status, oidset);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  gss_indicate_mechs(&min_status, &supported);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (GSS_ERROR(gss_indicate_mechs(&min_status, &supported)))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   while (supported_mechs[i]->name != NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           if (GSS_ERROR(gss_test_oid_set_member(&min_status,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -276,8 +303,48 @@ OM_uint32
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int i = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int equal = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_name_t new_name = GSS_C_NO_NAME;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_buffer_desc ename = GSS_C_EMPTY_BUFFER;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options.gss_store_rekey && client->used && ctx->client_creds) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (client->mech->oid.length != ctx->oid->length ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              (memcmp(client->mech->oid.elements,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+               ctx->oid->elements, ctx->oid->length) !=0)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug("Rekeyed credentials have different mechanism");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  return GSS_S_COMPLETE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              ctx->client_creds, ctx->oid, &new_name,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              NULL, NULL, NULL))) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  ssh_gssapi_error(ctx);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  return (ctx->major);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  gss_buffer_desc ename;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ctx->major = gss_compare_name(&ctx->minor, client->name,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              new_name, &equal);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (GSS_ERROR(ctx->major)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  ssh_gssapi_error(ctx);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  return (ctx->major);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (!equal) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug("Rekeyed credentials have different name");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  return GSS_S_COMPLETE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug("Marking rekeyed credentials for export");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          gss_release_name(&ctx->minor, &client->name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          gss_release_cred(&ctx->minor, &client->creds);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          client->name = new_name;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          client->creds = ctx->client_creds;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ctx->client_creds = GSS_C_NO_CREDENTIAL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          client->updated = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return GSS_S_COMPLETE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   client->mech = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -292,6 +359,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (client->mech == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           return GSS_S_FAILURE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (ctx->client_creds &&
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (ctx->major = gss_inquire_cred_by_mech(&ctx->minor,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+       ctx->client_creds, ctx->oid, &client->name, NULL, NULL, NULL))) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh_gssapi_error(ctx);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return (ctx->major);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if ((ctx->major = gss_display_name(&ctx->minor, ctx->client,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       &client->displayname, NULL))) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           ssh_gssapi_error(ctx);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -309,6 +383,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           return (ctx->major);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_release_buffer(&ctx->minor, &ename);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* We can't copy this structure, so we just move the pointer to it */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   client->creds = ctx->client_creds;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   ctx->client_creds = GSS_C_NO_CREDENTIAL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -319,11 +395,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ssh_gssapi_cleanup_creds(void)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  if (gssapi_client.store.filename != NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          /* Unlink probably isn't sufficient */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          debug("removing gssapi cred file\"%s\"",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--              gssapi_client.store.filename);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          unlink(gssapi_client.store.filename);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  krb5_ccache ccache = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  krb5_error_code problem;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (gssapi_client.store.data != NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if ((problem = krb5_cc_resolve(gssapi_client.store.data, gssapi_client.store.envval, &ccache))) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug_f("krb5_cc_resolve(): %.100s",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          krb5_get_err_text(gssapi_client.store.data, problem));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          } else if ((problem = krb5_cc_destroy(gssapi_client.store.data, ccache))) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug_f("krb5_cc_destroy(): %.100s",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          krb5_get_err_text(gssapi_client.store.data, problem));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  krb5_free_context(gssapi_client.store.data);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  gssapi_client.store.data = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -356,19 +441,23 @@ ssh_gssapi_do_child(char ***envp, u_int *envsizep)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* Privileged */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--ssh_gssapi_userok(char *user)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_gssapi_userok(char *user, struct passwd *pw, int kex)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   OM_uint32 lmin;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  (void) kex; /* used in privilege separation */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (gssapi_client.exportedname.length == 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       gssapi_client.exportedname.value == NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           debug("No suitable client data");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (gssapi_client.mech && gssapi_client.mech->userok)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          if ((*gssapi_client.mech->userok)(&gssapi_client, user))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if ((*gssapi_client.mech->userok)(&gssapi_client, user)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  gssapi_client.used = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  gssapi_client.store.owner = pw;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   return 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   /* Destroy delegated credentials if userok fails */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   gss_release_buffer(&lmin, &gssapi_client.displayname);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   gss_release_buffer(&lmin, &gssapi_client.exportedname);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -382,14 +471,90 @@ ssh_gssapi_userok(char *user)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return (0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--/* Privileged */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--OM_uint32
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* These bits are only used for rekeying. The unpriviledged child is running
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * as the user, the monitor is root.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * In the child, we want to :
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *    *) Ask the monitor to store our credentials into the store we specify
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *    *) If it succeeds, maybe do a PAM update
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* Stuff for PAM */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef USE_PAM
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static int ssh_gssapi_simple_conv(int n, const struct pam_message **msg,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    struct pam_response **resp, void *data)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  ctx->major = gss_verify_mic(&ctx->minor, ctx->context,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--      gssbuf, gssmic, NULL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return (PAM_CONV_ERR);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  return (ctx->major);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_gssapi_rekey_creds(void) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int ok;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef USE_PAM
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int ret;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  pam_handle_t *pamh = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char *envstr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (gssapi_client.store.filename == NULL &&
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      gssapi_client.store.envval == NULL &&
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      gssapi_client.store.envvar == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!ok)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  debug("Rekeyed credentials stored successfully");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Actually managing to play with the ssh pam stack from here will
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * be next to impossible. In any case, we may want different options
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * for rekeying. So, use our own :)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef USE_PAM    
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!use_privsep) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug("Not even going to try and do PAM with privsep disabled");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ret = pam_start("sshd-rekey", gssapi_client.store.owner->pw_name,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      &pamconv, &pamh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (ret)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      gssapi_client.store.envval);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ret = pam_putenv(pamh, envstr);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!ret)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          pam_setcred(pamh, PAM_REINITIALIZE_CRED);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  pam_end(pamh, PAM_SUCCESS);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh_gssapi_update_creds(ssh_gssapi_ccache *store) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int ok = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Check we've got credentials to store */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!gssapi_client.updated)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gssapi_client.updated = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  temporarily_use_uid(gssapi_client.store.owner);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (gssapi_client.mech && gssapi_client.mech->updatecreds)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ok = (*gssapi_client.mech->updatecreds)(store, &gssapi_client);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug("No update function for this mechanism");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  restore_uid();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return ok;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* Privileged */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/kex.c b/kex.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 709a0ec6..d369c46b 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/kex.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/kex.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -57,11 +57,16 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "misc.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "dispatch.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "monitor.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "xmalloc.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "ssherr.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "sshbuf.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "digest.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "ssh-gss.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* prototype */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static int kex_choose_conf(struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static int kex_input_newkeys(int, u_int32_t, struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -117,15 +122,28 @@ static const struct kexalg kexalgs[] = {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { NULL, 0, -1, -1},
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static const struct kexalg gss_kexalgs[] = {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { KEX_GSS_GRP14_SHA256_ID, KEX_GSS_GRP14_SHA256, 0, SSH_DIGEST_SHA256 },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { KEX_GSS_GRP16_SHA512_ID, KEX_GSS_GRP16_SHA512, 0, SSH_DIGEST_SHA512 },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { KEX_GSS_NISTP256_SHA256_ID, KEX_GSS_NISTP256_SHA256,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      NID_X9_62_prime256v1, SSH_DIGEST_SHA256 },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { KEX_GSS_C25519_SHA256_ID, KEX_GSS_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { NULL, 0, -1, -1},
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--char *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--kex_alg_list(char sep)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static char *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+kex_alg_list_internal(char sep, const struct kexalg *algs)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   char *ret = NULL, *tmp;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   size_t nlen, rlen = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   const struct kexalg *k;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  for (k = kexalgs; k->name != NULL; k++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for (k = algs; k->name != NULL; k++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           if (ret != NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   ret[rlen++] = sep;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           nlen = strlen(k->name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -140,6 +158,18 @@ kex_alg_list(char sep)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return ret;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+char *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+kex_alg_list(char sep)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return kex_alg_list_internal(sep, kexalgs);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+char *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+kex_gss_alg_list(char sep)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return kex_alg_list_internal(sep, gss_kexalgs);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static const struct kexalg *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- kex_alg_by_name(const char *name)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -149,6 +179,10 @@ kex_alg_by_name(const char *name)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           if (strcmp(k->name, name) == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   return k;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for (k = gss_kexalgs; k->name != NULL; k++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (strncmp(k->name, name, strlen(k->name)) == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  return k;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -317,6 +351,29 @@ kex_assemble_names(char **listp, const char *def, const char *all)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* Validate GSS KEX method name list */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+kex_gss_names_valid(const char *names)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char *s, *cp, *p;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (names == NULL || *names == '\0')
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  s = cp = xstrdup(names);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for ((p = strsep(&cp, ",")); p && *p != '\0';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (p = strsep(&cp, ","))) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (strncmp(p, "gss-", 4) != 0
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            || kex_alg_by_name(p) == NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  error("Unsupported KEX algorithm \"%.100s\"", p);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  free(s);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  debug3("gss kex names ok: [%s]", names);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  free(s);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* put algorithm proposal into buffer */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX])
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -699,6 +756,9 @@ kex_free(struct kex *kex)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   sshbuf_free(kex->server_version);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   sshbuf_free(kex->client_pub);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   sshbuf_free(kex->session_id);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  free(kex->gss_host);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif /* GSSAPI */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   free(kex->failed_choice);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   free(kex->hostkey_alg);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   free(kex->name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/kex.h b/kex.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 9605ed52..0677208a 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/kex.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/kex.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -102,6 +102,15 @@ enum kex_exchange {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   KEX_ECDH_SHA2,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   KEX_C25519_SHA256,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   KEX_KEM_SNTRUP761X25519_SHA512,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  KEX_GSS_GRP1_SHA1,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  KEX_GSS_GRP14_SHA1,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  KEX_GSS_GRP14_SHA256,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  KEX_GSS_GRP16_SHA512,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  KEX_GSS_GEX_SHA1,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  KEX_GSS_NISTP256_SHA256,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  KEX_GSS_C25519_SHA256,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   KEX_MAX
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -152,6 +161,12 @@ struct kex {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   u_int   flags;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     hash_alg;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     ec_nid;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int     gss_deleg_creds;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int     gss_trust_dns;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char    *gss_host;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char    *gss_client;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   char    *failed_choice;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     (*verify_host_key)(struct sshkey *, struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   struct sshkey *(*load_host_public_key)(int, int, struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -173,8 +188,10 @@ struct kex {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int        kex_names_valid(const char *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- char      *kex_alg_list(char);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+char      *kex_gss_alg_list(char);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- char      *kex_names_cat(const char *, const char *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int        kex_assemble_names(char **, const char *, const char *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int        kex_gss_names_valid(const char *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int        kex_exchange_identification(struct ssh *, int, const char *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -202,6 +219,12 @@ int    kexgex_client(struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int        kexgex_server(struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int        kex_gen_client(struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int        kex_gen_server(struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#if defined(GSSAPI) && defined(WITH_OPENSSL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int        kexgssgex_client(struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int        kexgssgex_server(struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int        kexgss_client(struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int        kexgss_server(struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int        kex_dh_keypair(struct kex *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int        kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -234,6 +257,12 @@ int    kexgex_hash(int, const struct sshbuf *, const struct sshbuf *,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     const BIGNUM *, const u_char *, size_t,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     u_char *, size_t *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int        kex_gen_hash(int hash_alg, const struct sshbuf *client_version,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    const struct sshbuf *server_version, const struct sshbuf *client_kexinit,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    const struct sshbuf *server_kexinit, const struct sshbuf *server_host_key_blob,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    const struct sshbuf *client_pub, const struct sshbuf *server_pub,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    const struct sshbuf *shared_secret, u_char *hash, size_t *hashlen);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- void      kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE])
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE)))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE)));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/kexdh.c b/kexdh.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index c1084f21..0faab21b 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/kexdh.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/kexdh.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -49,13 +49,23 @@ kex_dh_keygen(struct kex *kex)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   switch (kex->kex_type) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   case KEX_DH_GRP1_SHA1:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case KEX_GSS_GRP1_SHA1:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           kex->dh = dh_new_group1();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   case KEX_DH_GRP14_SHA1:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   case KEX_DH_GRP14_SHA256:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case KEX_GSS_GRP14_SHA1:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case KEX_GSS_GRP14_SHA256:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           kex->dh = dh_new_group14();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   case KEX_DH_GRP16_SHA512:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case KEX_GSS_GRP16_SHA512:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           kex->dh = dh_new_group16();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   case KEX_DH_GRP18_SHA512:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/kexgen.c b/kexgen.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index bde28053..31f90f50 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/kexgen.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/kexgen.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -44,7 +44,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static int input_kex_gen_init(int, u_int32_t, struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static int input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--static int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- kex_gen_hash(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     int hash_alg,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     const struct sshbuf *client_version,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/kexgssc.c b/kexgssc.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-new file mode 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 00000000..1c62740e
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- /dev/null
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/kexgssc.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,599 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Redistribution and use in source and binary forms, with or without
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * modification, are permitted provided that the following conditions
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * are met:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * 1. Redistributions of source code must retain the above copyright
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *    notice, this list of conditions and the following disclaimer.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * 2. Redistributions in binary form must reproduce the above copyright
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *    notice, this list of conditions and the following disclaimer in the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *    documentation and/or other materials provided with the distribution.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "includes.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#if defined(GSSAPI) && defined(WITH_OPENSSL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "includes.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <openssl/crypto.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <openssl/bn.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <string.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "xmalloc.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "sshbuf.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "ssh2.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "sshkey.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "cipher.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "kex.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "log.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "packet.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "dh.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "digest.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "ssherr.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "ssh-gss.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+kexgss_client(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct kex *kex = ssh->kex;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      recv_tok = GSS_C_EMPTY_BUFFER,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      gssbuf, msg_tok = GSS_C_EMPTY_BUFFER, *token_ptr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  Gssctxt *ctxt;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  OM_uint32 maj_status, min_status, ret_flags;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshbuf *server_blob = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshbuf *shared_secret = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshbuf *server_host_key_blob = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshbuf *empty = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_char *msg;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int type = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int first = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_char hash[SSH_DIGEST_MAX_LENGTH];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  size_t hashlen;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_char c;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Initialise our GSSAPI world */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ssh_gssapi_build_ctx(&ctxt);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      == GSS_C_NO_OID)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("Couldn't identify host exchange");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (ssh_gssapi_import_name(ctxt, kex->gss_host))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("Couldn't import hostname");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (kex->gss_client &&
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      ssh_gssapi_client_identity(ctxt, kex->gss_client))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("Couldn't acquire client credentials");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Step 1 */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  switch (kex->kex_type) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case KEX_GSS_GRP1_SHA1:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case KEX_GSS_GRP14_SHA1:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case KEX_GSS_GRP14_SHA256:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case KEX_GSS_GRP16_SHA512:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          r = kex_dh_keypair(kex);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case KEX_GSS_NISTP256_SHA256:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          r = kex_ecdh_keypair(kex);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case KEX_GSS_C25519_SHA256:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          r = kex_c25519_keypair(kex);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  default:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_f("Unexpected KEX type %d", kex->kex_type);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (r != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  token_ptr = GSS_C_NO_BUFFER;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  do {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug("Calling gss_init_sec_context");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          maj_status = ssh_gssapi_init_ctx(ctxt,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              kex->gss_deleg_creds, token_ptr, &send_tok,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              &ret_flags);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (GSS_ERROR(maj_status)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* XXX Useles code: Missing send? */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if (send_tok.length != 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if ((r = sshpkt_start(ssh,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  SSH2_MSG_KEXGSS_CONTINUE)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = sshpkt_put_string(ssh, send_tok.value,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  send_tok.length)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  fatal("gss_init_context failed");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* If we've got an old receive buffer get rid of it */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (token_ptr != GSS_C_NO_BUFFER)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  gss_release_buffer(&min_status, &recv_tok);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (maj_status == GSS_S_COMPLETE) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* If mutual state flag is not true, kex fails */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if (!(ret_flags & GSS_C_MUTUAL_FLAG))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal("Mutual authentication failed");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* If integ avail flag is not true kex fails */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if (!(ret_flags & GSS_C_INTEG_FLAG))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal("Integrity check failed");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * If we have data to send, then the last message that we
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * received cannot have been a 'complete'.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (send_tok.length != 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if (first) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_INIT)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = sshpkt_put_string(ssh, send_tok.value,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  send_tok.length)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = sshpkt_put_stringb(ssh, kex->client_pub)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  fatal("failed to construct packet: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          first = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = sshpkt_put_string(ssh, send_tok.value,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  send_tok.length)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  fatal("failed to construct packet: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if ((r = sshpkt_send(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal("failed to send packet: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  gss_release_buffer(&min_status, &send_tok);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* If we've sent them data, they should reply */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  do {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          type = ssh_packet_read(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if (type == SSH2_MSG_KEXGSS_HOSTKEY) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  debug("Received KEXGSS_HOSTKEY");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  if (server_host_key_blob)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                          fatal("Server host key received more than once");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  if ((r = sshpkt_getb_froms(ssh, &server_host_key_blob)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                          fatal("Failed to read server host key: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  } while (type == SSH2_MSG_KEXGSS_HOSTKEY);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  switch (type) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  case SSH2_MSG_KEXGSS_CONTINUE:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          debug("Received GSSAPI_CONTINUE");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if (maj_status == GSS_S_COMPLETE)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  fatal("GSSAPI Continue received from server when complete");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  &recv_tok)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = sshpkt_get_end(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  fatal("Failed to read token: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  case SSH2_MSG_KEXGSS_COMPLETE:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          debug("Received GSSAPI_COMPLETE");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if (msg_tok.value != NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  fatal("Received GSSAPI_COMPLETE twice?");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if ((r = sshpkt_getb_froms(ssh, &server_blob)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = ssh_gssapi_sshpkt_get_buffer_desc(ssh,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  &msg_tok)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  fatal("Failed to read message: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          /* Is there a token included? */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if ((r = sshpkt_get_u8(ssh, &c)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if (c) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  if ((r = ssh_gssapi_sshpkt_get_buffer_desc(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                      ssh, &recv_tok)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                          fatal("Failed to read token: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  /* If we're already complete - protocol error */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  if (maj_status == GSS_S_COMPLETE)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                          sshpkt_disconnect(ssh, "Protocol error: received token when complete");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  /* No token included */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  if (maj_status != GSS_S_COMPLETE)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                          sshpkt_disconnect(ssh, "Protocol error: did not receive final token");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if ((r = sshpkt_get_end(ssh)) != 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  fatal("Expecting end of packet.");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  case SSH2_MSG_KEXGSS_ERROR:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          debug("Received Error");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if ((r = sshpkt_get_u32(ssh, &maj_status)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = sshpkt_get_u32(ssh, &min_status)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = sshpkt_get_string(ssh, NULL, NULL)) != 0 || /* lang tag */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = sshpkt_get_end(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  fatal("sshpkt_get failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal("GSSAPI Error: \n%.400s", msg);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  default:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          sshpkt_disconnect(ssh, "Protocol error: didn't expect packet type %d",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              type);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  token_ptr = &recv_tok;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* No data, and not complete */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if (maj_status != GSS_S_COMPLETE)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal("Not complete, and no token output");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  } while (maj_status & GSS_S_CONTINUE_NEEDED);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * We _must_ have received a COMPLETE message in reply from the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * server, which will have set server_blob and msg_tok
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (type != SSH2_MSG_KEXGSS_COMPLETE)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* compute shared secret */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  switch (kex->kex_type) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case KEX_GSS_GRP1_SHA1:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case KEX_GSS_GRP14_SHA1:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case KEX_GSS_GRP14_SHA256:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case KEX_GSS_GRP16_SHA512:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          r = kex_dh_dec(kex, server_blob, &shared_secret);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case KEX_GSS_C25519_SHA256:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (sshbuf_ptr(server_blob)[sshbuf_len(server_blob)] & 0x80)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  fatal("The received key has MSB of last octet set!");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          r = kex_c25519_dec(kex, server_blob, &shared_secret);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case KEX_GSS_NISTP256_SHA256:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (sshbuf_len(server_blob) != 65)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  fatal("The received NIST-P256 key did not match"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      "expected length (expected 65, got %zu)", sshbuf_len(server_blob));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (sshbuf_ptr(server_blob)[0] != POINT_CONVERSION_UNCOMPRESSED)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  fatal("The received NIST-P256 key does not have first octet 0x04");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          r = kex_ecdh_dec(kex, server_blob, &shared_secret);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  default:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          r = SSH_ERR_INVALID_ARGUMENT;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (r != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto out;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((empty = sshbuf_new()) == NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          r = SSH_ERR_ALLOC_FAIL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto out;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  hashlen = sizeof(hash);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = kex_gen_hash(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->hash_alg,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->client_version,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->server_version,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->my,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->peer,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (server_host_key_blob ? server_host_key_blob : empty),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->client_pub,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      server_blob,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      shared_secret,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      hash, &hashlen)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_f("Unexpected KEX type %d", kex->kex_type);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gssbuf.value = hash;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gssbuf.length = hashlen;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Verify that the hash matches the MIC we just got. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok)))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          sshpkt_disconnect(ssh, "Hash's MIC didn't verify");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_release_buffer(&min_status, &msg_tok);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (kex->gss_deleg_creds)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh_gssapi_credentials_updated(ctxt);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (gss_kex_context == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          gss_kex_context = ctxt;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh_gssapi_delete_ctx(&ctxt);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          r = kex_send_newkeys(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+out:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  explicit_bzero(hash, sizeof(hash));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(empty);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(server_host_key_blob);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(server_blob);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(shared_secret);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(kex->client_pub);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  kex->client_pub = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+kexgssgex_client(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct kex *kex = ssh->kex;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      recv_tok = GSS_C_EMPTY_BUFFER, gssbuf,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            msg_tok = GSS_C_EMPTY_BUFFER, *token_ptr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  Gssctxt *ctxt;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  OM_uint32 maj_status, min_status, ret_flags;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshbuf *shared_secret = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  BIGNUM *p = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  BIGNUM *g = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshbuf *buf = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshbuf *server_host_key_blob = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshbuf *server_blob = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  BIGNUM *dh_server_pub = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_char *msg;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int type = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int first = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_char hash[SSH_DIGEST_MAX_LENGTH];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  size_t hashlen;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  const BIGNUM *pub_key, *dh_p, *dh_g;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshbuf *empty = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_char c;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Initialise our GSSAPI world */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ssh_gssapi_build_ctx(&ctxt);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      == GSS_C_NO_OID)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("Couldn't identify host exchange");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (ssh_gssapi_import_name(ctxt, kex->gss_host))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("Couldn't import hostname");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (kex->gss_client &&
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      ssh_gssapi_client_identity(ctxt, kex->gss_client))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("Couldn't acquire client credentials");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  debug("Doing group exchange");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  nbits = dh_estimate(kex->dh_need * 8);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  kex->min = DH_GRP_MIN;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  kex->max = DH_GRP_MAX;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  kex->nbits = nbits;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_GROUPREQ)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_put_u32(ssh, min)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_put_u32(ssh, nbits)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_put_u32(ssh, max)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_send(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("Failed to construct a packet: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = ssh_packet_read_expect(ssh, SSH2_MSG_KEXGSS_GROUP)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("Error: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = sshpkt_get_bignum2(ssh, &p)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_get_bignum2(ssh, &g)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_get_end(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("shpkt_get_bignum2 failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (BN_num_bits(p) < min || BN_num_bits(p) > max)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("GSSGRP_GEX group out of range: %d !< %d !< %d",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              min, BN_num_bits(p), max);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((kex->dh = dh_new_group(g, p)) == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("dn_new_group() failed");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  p = g = NULL; /* belong to kex->dh now */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto out;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  DH_get0_key(kex->dh, &pub_key, NULL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  token_ptr = GSS_C_NO_BUFFER;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  do {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* Step 2 - call GSS_Init_sec_context() */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug("Calling gss_init_sec_context");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          maj_status = ssh_gssapi_init_ctx(ctxt,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              kex->gss_deleg_creds, token_ptr, &send_tok,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              &ret_flags);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (GSS_ERROR(maj_status)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* XXX Useles code: Missing send? */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if (send_tok.length != 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if ((r = sshpkt_start(ssh,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  SSH2_MSG_KEXGSS_CONTINUE)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = sshpkt_put_string(ssh, send_tok.value,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  send_tok.length)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  fatal("gss_init_context failed");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* If we've got an old receive buffer get rid of it */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (token_ptr != GSS_C_NO_BUFFER)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  gss_release_buffer(&min_status, &recv_tok);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (maj_status == GSS_S_COMPLETE) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* If mutual state flag is not true, kex fails */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if (!(ret_flags & GSS_C_MUTUAL_FLAG))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal("Mutual authentication failed");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* If integ avail flag is not true kex fails */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if (!(ret_flags & GSS_C_INTEG_FLAG))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal("Integrity check failed");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * If we have data to send, then the last message that we
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * received cannot have been a 'complete'.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (send_tok.length != 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if (first) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_INIT)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = sshpkt_put_string(ssh, send_tok.value,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  send_tok.length)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = sshpkt_put_bignum2(ssh, pub_key)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          first = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = sshpkt_put_string(ssh,send_tok.value,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  send_tok.length)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if ((r = sshpkt_send(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal("sshpkt_send failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  gss_release_buffer(&min_status, &send_tok);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* If we've sent them data, they should reply */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  do {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          type = ssh_packet_read(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if (type == SSH2_MSG_KEXGSS_HOSTKEY) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  debug("Received KEXGSS_HOSTKEY");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  if (server_host_key_blob)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                          fatal("Server host key received more than once");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  if ((r = sshpkt_getb_froms(ssh, &server_host_key_blob)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                          fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  } while (type == SSH2_MSG_KEXGSS_HOSTKEY);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  switch (type) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  case SSH2_MSG_KEXGSS_CONTINUE:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          debug("Received GSSAPI_CONTINUE");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if (maj_status == GSS_S_COMPLETE)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  fatal("GSSAPI Continue received from server when complete");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  &recv_tok)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = sshpkt_get_end(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  case SSH2_MSG_KEXGSS_COMPLETE:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          debug("Received GSSAPI_COMPLETE");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if (msg_tok.value != NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  fatal("Received GSSAPI_COMPLETE twice?");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if ((r = sshpkt_getb_froms(ssh, &server_blob)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = ssh_gssapi_sshpkt_get_buffer_desc(ssh,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  &msg_tok)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          /* Is there a token included? */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if ((r = sshpkt_get_u8(ssh, &c)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if (c) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  if ((r = ssh_gssapi_sshpkt_get_buffer_desc(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                          ssh, &recv_tok)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                      (r = sshpkt_get_end(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                          fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  /* If we're already complete - protocol error */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  if (maj_status == GSS_S_COMPLETE)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                          sshpkt_disconnect(ssh, "Protocol error: received token when complete");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  /* No token included */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  if (maj_status != GSS_S_COMPLETE)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                          sshpkt_disconnect(ssh, "Protocol error: did not receive final token");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  case SSH2_MSG_KEXGSS_ERROR:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          debug("Received Error");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          if ((r = sshpkt_get_u32(ssh, &maj_status)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = sshpkt_get_u32(ssh, &min_status)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = sshpkt_get_string(ssh, NULL, NULL)) != 0 || /* lang tag */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              (r = sshpkt_get_end(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                  fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal("GSSAPI Error: \n%.400s", msg);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  default:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          sshpkt_disconnect(ssh, "Protocol error: didn't expect packet type %d",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              type);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  token_ptr = &recv_tok;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* No data, and not complete */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if (maj_status != GSS_S_COMPLETE)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal("Not complete, and no token output");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  } while (maj_status & GSS_S_CONTINUE_NEEDED);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * We _must_ have received a COMPLETE message in reply from the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * server, which will have set dh_server_pub and msg_tok
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (type != SSH2_MSG_KEXGSS_COMPLETE)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* 7. C verifies that the key Q_S is valid */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* 8. C computes shared secret */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((buf = sshbuf_new()) == NULL ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshbuf_put_stringb(buf, server_blob)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshbuf_get_bignum2(buf, &dh_server_pub)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto out;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(buf);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  buf = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((shared_secret = sshbuf_new()) == NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          r = SSH_ERR_ALLOC_FAIL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto out;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = kex_dh_compute_key(kex, dh_server_pub, shared_secret)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto out;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((empty = sshbuf_new()) == NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          r = SSH_ERR_ALLOC_FAIL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto out;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  hashlen = sizeof(hash);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = kexgex_hash(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->hash_alg,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->client_version,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->server_version,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->my,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->peer,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (server_host_key_blob ? server_host_key_blob : empty),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->min, kex->nbits, kex->max,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      dh_p, dh_g,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      pub_key,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      dh_server_pub,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      sshbuf_ptr(shared_secret), sshbuf_len(shared_secret),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      hash, &hashlen)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("Failed to calculate hash: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gssbuf.value = hash;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gssbuf.length = hashlen;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Verify that the hash matches the MIC we just got. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok)))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          sshpkt_disconnect(ssh, "Hash's MIC didn't verify");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_release_buffer(&min_status, &msg_tok);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (kex->gss_deleg_creds)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh_gssapi_credentials_updated(ctxt);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (gss_kex_context == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          gss_kex_context = ctxt;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh_gssapi_delete_ctx(&ctxt);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Finally derive the keys and send them */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          r = kex_send_newkeys(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+out:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(buf);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(server_blob);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(empty);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  explicit_bzero(hash, sizeof(hash));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  DH_free(kex->dh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  kex->dh = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  BN_clear_free(dh_server_pub);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(shared_secret);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(server_host_key_blob);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/kexgsss.c b/kexgsss.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-new file mode 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 00000000..a2c02148
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- /dev/null
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/kexgsss.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,474 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Redistribution and use in source and binary forms, with or without
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * modification, are permitted provided that the following conditions
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * are met:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * 1. Redistributions of source code must retain the above copyright
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *    notice, this list of conditions and the following disclaimer.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * 2. Redistributions in binary form must reproduce the above copyright
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *    notice, this list of conditions and the following disclaimer in the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *    documentation and/or other materials provided with the distribution.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "includes.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#if defined(GSSAPI) && defined(WITH_OPENSSL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <string.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <openssl/crypto.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <openssl/bn.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "xmalloc.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "sshbuf.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "ssh2.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "sshkey.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "cipher.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "kex.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "log.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "packet.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "dh.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "ssh-gss.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "monitor_wrap.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "misc.h"      /* servconf.h needs misc.h for struct ForwardOptions */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "servconf.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "ssh-gss.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "digest.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "ssherr.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+extern ServerOptions options;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+kexgss_server(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct kex *kex = ssh->kex;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  OM_uint32 maj_status, min_status;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * Some GSSAPI implementations use the input value of ret_flags (an
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * output variable) as a means of triggering mechanism specific
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * features. Initializing it to zero avoids inadvertently
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * activating this non-standard behaviour.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  OM_uint32 ret_flags = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_buffer_desc gssbuf, recv_tok, msg_tok;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  Gssctxt *ctxt = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshbuf *shared_secret = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshbuf *client_pubkey = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshbuf *server_pubkey = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshbuf *empty = sshbuf_new();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int type = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_OID oid;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char *mechs;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_char hash[SSH_DIGEST_MAX_LENGTH];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  size_t hashlen;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Initialise GSSAPI */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* If we're rekeying, privsep means that some of the private structures
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * in the GSSAPI code are no longer available. This kludges them back
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * into life
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!ssh_gssapi_oid_table_ok()) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          mechs = ssh_gssapi_server_mechanisms();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          free(mechs);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  debug2_f("Identifying %s", kex->name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (oid == GSS_C_NO_OID)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+     fatal("Unknown gssapi mechanism");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  debug2_f("Acquiring credentials");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid))))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("Unable to acquire credentials for the server");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  do {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug("Wait SSH2_MSG_KEXGSS_INIT");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          type = ssh_packet_read(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          switch(type) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          case SSH2_MSG_KEXGSS_INIT:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if (client_pubkey != NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal("Received KEXGSS_INIT after initialising");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          &recv_tok)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      (r = sshpkt_getb_froms(ssh, &client_pubkey)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      (r = sshpkt_get_end(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  switch (kex->kex_type) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  case KEX_GSS_GRP1_SHA1:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  case KEX_GSS_GRP14_SHA1:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  case KEX_GSS_GRP14_SHA256:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  case KEX_GSS_GRP16_SHA512:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          r = kex_dh_enc(kex, client_pubkey, &server_pubkey,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              &shared_secret);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  case KEX_GSS_NISTP256_SHA256:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          r = kex_ecdh_enc(kex, client_pubkey, &server_pubkey,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              &shared_secret);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  case KEX_GSS_C25519_SHA256:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          r = kex_c25519_enc(kex, client_pubkey, &server_pubkey,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              &shared_secret);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  default:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal_f("Unexpected KEX type %d", kex->kex_type);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if (r != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          goto out;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          case SSH2_MSG_KEXGSS_CONTINUE:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          &recv_tok)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      (r = sshpkt_get_end(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          default:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  sshpkt_disconnect(ssh,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      "Protocol error: didn't expect packet type %d",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      type);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              &send_tok, &ret_flags));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          gss_release_buffer(&min_status, &recv_tok);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (maj_status != GSS_S_COMPLETE && send_tok.length == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  fatal("Zero length token output when incomplete");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (client_pubkey == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  fatal("No client public key");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (maj_status & GSS_S_CONTINUE_NEEDED) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug("Sending GSSAPI_CONTINUE");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      (r = sshpkt_send(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  gss_release_buffer(&min_status, &send_tok);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  } while (maj_status & GSS_S_CONTINUE_NEEDED);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (GSS_ERROR(maj_status)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (send_tok.length > 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      (r = sshpkt_send(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("accept_ctx died");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!(ret_flags & GSS_C_MUTUAL_FLAG))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("Mutual Authentication flag wasn't set");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!(ret_flags & GSS_C_INTEG_FLAG))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("Integrity flag wasn't set");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  hashlen = sizeof(hash);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = kex_gen_hash(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->hash_alg,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->client_version,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->server_version,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->peer,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->my,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      empty,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      client_pubkey,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      server_pubkey,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      shared_secret,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      hash, &hashlen)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto out;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gssbuf.value = hash;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gssbuf.length = hashlen;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok))))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("Couldn't get MIC");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_COMPLETE)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_put_stringb(ssh, server_pubkey)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_put_string(ssh, msg_tok.value, msg_tok.length)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (send_tok.length != 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if ((r = sshpkt_put_u8(ssh, 1)) != 0 || /* true */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if ((r = sshpkt_put_u8(ssh, 0)) != 0) /* false */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = sshpkt_send(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("sshpkt_send failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_release_buffer(&min_status, &send_tok);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_release_buffer(&min_status, &msg_tok);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (gss_kex_context == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          gss_kex_context = ctxt;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh_gssapi_delete_ctx(&ctxt);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          r = kex_send_newkeys(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* If this was a rekey, then save out any delegated credentials we
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * just exchanged.  */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options.gss_store_rekey)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh_gssapi_rekey_creds();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+out:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(empty);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  explicit_bzero(hash, sizeof(hash));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(shared_secret);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(client_pubkey);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(server_pubkey);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+kexgssgex_server(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct kex *kex = ssh->kex;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  OM_uint32 maj_status, min_status;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * Some GSSAPI implementations use the input value of ret_flags (an
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * output variable) as a means of triggering mechanism specific
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * features. Initializing it to zero avoids inadvertently
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * activating this non-standard behaviour.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  OM_uint32 ret_flags = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_buffer_desc gssbuf, recv_tok, msg_tok;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  Gssctxt *ctxt = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshbuf *shared_secret = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int type = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_OID oid;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char *mechs;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_char hash[SSH_DIGEST_MAX_LENGTH];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  size_t hashlen;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  BIGNUM *dh_client_pub = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  const BIGNUM *pub_key, *dh_p, *dh_g;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int min = -1, max = -1, nbits = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int cmin = -1, cmax = -1; /* client proposal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshbuf *empty = sshbuf_new();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Initialise GSSAPI */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* If we're rekeying, privsep means that some of the private structures
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * in the GSSAPI code are no longer available. This kludges them back
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * into life
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!ssh_gssapi_oid_table_ok())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if ((mechs = ssh_gssapi_server_mechanisms()))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  free(mechs);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  debug2_f("Identifying %s", kex->name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (oid == GSS_C_NO_OID)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+     fatal("Unknown gssapi mechanism");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  debug2_f("Acquiring credentials");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid))))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("Unable to acquire credentials for the server");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* 5. S generates an ephemeral key pair (do the allocations early) */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  debug("Doing group exchange");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ssh_packet_read_expect(ssh, SSH2_MSG_KEXGSS_GROUPREQ);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* store client proposal to provide valid signature */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = sshpkt_get_u32(ssh, &cmin)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_get_u32(ssh, &nbits)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_get_u32(ssh, &cmax)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_get_end(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  kex->nbits = nbits;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  kex->min = cmin;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  kex->max = cmax;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  min = MAX(DH_GRP_MIN, cmin);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  max = MIN(DH_GRP_MAX, cmax);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  nbits = MAXIMUM(DH_GRP_MIN, nbits);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  nbits = MINIMUM(DH_GRP_MAX, nbits);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (max < min || nbits < min || max < nbits)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("GSS_GEX, bad parameters: %d !< %d !< %d",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              min, nbits, max);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  kex->dh = PRIVSEP(choose_dh(min, nbits, max));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (kex->dh == NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          sshpkt_disconnect(ssh, "Protocol error: no matching group found");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("Protocol error: no matching group found");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_GROUP)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_put_bignum2(ssh, dh_p)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_put_bignum2(ssh, dh_g)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_send(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = ssh_packet_write_wait(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("ssh_packet_write_wait: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Compute our exchange value in parallel with the client */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto out;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  do {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug("Wait SSH2_MSG_GSSAPI_INIT");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          type = ssh_packet_read(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          switch(type) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          case SSH2_MSG_KEXGSS_INIT:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if (dh_client_pub != NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal("Received KEXGSS_INIT after initialising");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          &recv_tok)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      (r = sshpkt_get_bignum2(ssh, &dh_client_pub)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      (r = sshpkt_get_end(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          case SSH2_MSG_KEXGSS_CONTINUE:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          &recv_tok)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      (r = sshpkt_get_end(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          default:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  sshpkt_disconnect(ssh,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      "Protocol error: didn't expect packet type %d",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      type);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              &send_tok, &ret_flags));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          gss_release_buffer(&min_status, &recv_tok);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (maj_status != GSS_S_COMPLETE && send_tok.length == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  fatal("Zero length token output when incomplete");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (dh_client_pub == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  fatal("No client public key");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (maj_status & GSS_S_CONTINUE_NEEDED) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug("Sending GSSAPI_CONTINUE");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      (r = sshpkt_send(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  gss_release_buffer(&min_status, &send_tok);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  } while (maj_status & GSS_S_CONTINUE_NEEDED);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (GSS_ERROR(maj_status)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (send_tok.length > 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      (r = sshpkt_send(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("accept_ctx died");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!(ret_flags & GSS_C_MUTUAL_FLAG))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("Mutual Authentication flag wasn't set");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!(ret_flags & GSS_C_INTEG_FLAG))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("Integrity flag wasn't set");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* calculate shared secret */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((shared_secret = sshbuf_new()) == NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          r = SSH_ERR_ALLOC_FAIL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto out;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = kex_dh_compute_key(kex, dh_client_pub, shared_secret)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto out;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  DH_get0_key(kex->dh, &pub_key, NULL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  hashlen = sizeof(hash);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = kexgex_hash(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->hash_alg,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->client_version,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->server_version,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->peer,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      kex->my,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      empty,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      cmin, nbits, cmax,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      dh_p, dh_g,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      dh_client_pub,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      pub_key,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      sshbuf_ptr(shared_secret), sshbuf_len(shared_secret),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      hash, &hashlen)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("kexgex_hash failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gssbuf.value = hash;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gssbuf.length = hashlen;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok))))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("Couldn't get MIC");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_COMPLETE)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_put_string(ssh, msg_tok.value, msg_tok.length)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (send_tok.length != 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if ((r = sshpkt_put_u8(ssh, 1)) != 0 || /* true */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if ((r = sshpkt_put_u8(ssh, 0)) != 0) /* false */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = sshpkt_send(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("sshpkt failed: %s", ssh_err(r));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_release_buffer(&min_status, &send_tok);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_release_buffer(&min_status, &msg_tok);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (gss_kex_context == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          gss_kex_context = ctxt;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh_gssapi_delete_ctx(&ctxt);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Finally derive the keys and send them */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          r = kex_send_newkeys(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* If this was a rekey, then save out any delegated credentials we
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * just exchanged.  */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options.gss_store_rekey)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh_gssapi_rekey_creds();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+out:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(empty);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  explicit_bzero(hash, sizeof(hash));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  DH_free(kex->dh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  kex->dh = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  BN_clear_free(dh_client_pub);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(shared_secret);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/monitor.c b/monitor.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 74c803e1..d8e447fe 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/monitor.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/monitor.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -145,6 +145,8 @@ int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int mm_answer_gss_accept_ctx(struct ssh *, int, struct sshbuf *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int mm_answer_gss_sign(struct ssh *, int, struct sshbuf *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int mm_answer_gss_updatecreds(struct ssh *, int, struct sshbuf *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef SSH_AUDIT_EVENTS
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -217,11 +219,18 @@ struct mon_table mon_dispatch_proto20[] = {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx},
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok},
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic},
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     {0, 0, NULL}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- struct mon_table mon_dispatch_postauth20[] = {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx},
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx},
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign},
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds},
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef WITH_OPENSSL
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -290,6 +299,10 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* Permit requests for moduli and signatures */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* and for the GSSAPI key exchange */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* The first few requests do not require asynchronous access */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   while (!authenticated) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -401,6 +414,10 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* and for the GSSAPI key exchange */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (auth_opts->permit_pty_flag) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1730,6 +1747,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # ifdef OPENSSL_HAS_ECC
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   kex->kex[KEX_ECDH_SHA2] = kex_gen_server;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options.gss_keyex) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif /* WITH_OPENSSL */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   kex->kex[KEX_C25519_SHA256] = kex_gen_server;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1822,8 +1850,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   u_char *p;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  if (!options.gss_authentication)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          fatal_f("GSSAPI authentication not enabled");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!options.gss_authentication && !options.gss_keyex)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_f("GSSAPI not enabled");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if ((r = sshbuf_get_string(m, &p, &len)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           fatal_fr(r, "parse");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1855,8 +1883,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   OM_uint32 flags = 0; /* GSI needs this */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  if (!options.gss_authentication)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          fatal_f("GSSAPI authentication not enabled");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!options.gss_authentication && !options.gss_keyex)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_f("GSSAPI not enabled");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           fatal_fr(r, "ssh_gssapi_get_buffer_desc");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1876,6 +1904,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return (0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1887,8 +1916,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   OM_uint32 ret;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  if (!options.gss_authentication)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          fatal_f("GSSAPI authentication not enabled");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!options.gss_authentication && !options.gss_keyex)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_f("GSSAPI not enabled");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1914,13 +1943,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  int r, authenticated;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int r, authenticated, kex;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   const char *displayname;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  if (!options.gss_authentication)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          fatal_f("GSSAPI authentication not enabled");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!options.gss_authentication && !options.gss_keyex)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_f("GSSAPI not enabled");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = sshbuf_get_u32(m, &kex)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_fr(r, "buffer error");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  authenticated = authctxt->valid &&
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      ssh_gssapi_userok(authctxt->user, authctxt->pw, kex);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   sshbuf_reset(m);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if ((r = sshbuf_put_u32(m, authenticated)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1929,7 +1962,11 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   debug3_f("sending result %d", authenticated);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  auth_method = "gssapi-with-mic";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (kex) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          auth_method = "gssapi-keyex";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          auth_method = "gssapi-with-mic";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if ((displayname = ssh_gssapi_displayname()) != NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           auth2_record_info(authctxt, "%s", displayname);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1937,5 +1974,83 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* Monitor loop will terminate if authenticated */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return (authenticated);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--#endif /* GSSAPI */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+mm_answer_gss_sign(struct ssh *ssh, int socket, struct sshbuf *m)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_buffer_desc data;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_buffer_desc hash = GSS_C_EMPTY_BUFFER;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  OM_uint32 major, minor;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  size_t len;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  u_char *p = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!options.gss_authentication && !options.gss_keyex)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_f("GSSAPI not enabled");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = sshbuf_get_string(m, &p, &len)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_fr(r, "buffer error");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  data.value = p;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  data.length = len;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Lengths of SHA-1, SHA-256 and SHA-512 hashes that are used */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (data.length != 20 && data.length != 32 && data.length != 64)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_f("data length incorrect: %d", (int) data.length);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Save the session ID on the first time around */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (session_id2_len == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          session_id2_len = data.length;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          session_id2 = xmalloc(session_id2_len);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          memcpy(session_id2, data.value, session_id2_len);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  major = ssh_gssapi_sign(gsscontext, &data, &hash);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  free(data.value);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_reset(m);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = sshbuf_put_u32(m, major)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshbuf_put_string(m, hash.value, hash.length)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_fr(r, "buffer error");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  mm_request_send(socket, MONITOR_ANS_GSSSIGN, m);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_release_buffer(&minor, &hash);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Turn on getpwnam permissions */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* And credential updating, for when rekeying */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return (0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+mm_answer_gss_updatecreds(struct ssh *ssh, int socket, struct sshbuf *m) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ssh_gssapi_ccache store;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int r, ok;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!options.gss_authentication && !options.gss_keyex)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_f("GSSAPI not enabled");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = sshbuf_get_string(m, (u_char **)&store.filename, NULL)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshbuf_get_string(m, (u_char **)&store.envvar, NULL)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshbuf_get_string(m, (u_char **)&store.envval, NULL)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_fr(r, "buffer error");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ok = ssh_gssapi_update_creds(&store);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  free(store.filename);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  free(store.envvar);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  free(store.envval);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_reset(m);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = sshbuf_put_u32(m, ok)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_fr(r, "buffer error");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return(0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif /* GSSAPI */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/monitor.h b/monitor.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 683e5e07..2b1a2d59 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/monitor.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/monitor.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -63,6 +63,8 @@ enum monitor_reqtype {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- struct ssh;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/monitor_wrap.c b/monitor_wrap.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 748333c7..3310ad3f 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/monitor_wrap.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/monitor_wrap.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -999,13 +999,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--mm_ssh_gssapi_userok(char *user)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+mm_ssh_gssapi_userok(char *user, struct passwd *pw, int kex)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   struct sshbuf *m;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int r, authenticated = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if ((m = sshbuf_new()) == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           fatal_f("sshbuf_new failed");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = sshbuf_put_u32(m, kex)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_fr(r, "buffer error");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   mm_request_receive_expect(pmonitor->m_recvfd,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1018,4 +1020,57 @@ mm_ssh_gssapi_userok(char *user)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   debug3_f("user %sauthenticated", authenticated ? "" : "not ");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return (authenticated);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+OM_uint32
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshbuf *m;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  OM_uint32 major;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((m = sshbuf_new()) == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_f("sshbuf_new failed");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = sshbuf_put_string(m, data->value, data->length)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_fr(r, "buffer error");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSIGN, m);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSIGN, m);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = sshbuf_get_u32(m, &major)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = ssh_gssapi_get_buffer_desc(m, hash)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_fr(r, "buffer error");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(m);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return (major);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *store)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshbuf *m;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int r, ok;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((m = sshbuf_new()) == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_f("sshbuf_new failed");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = sshbuf_put_cstring(m,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      store->filename ? store->filename : "")) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshbuf_put_cstring(m,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      store->envvar ? store->envvar : "")) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshbuf_put_cstring(m,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      store->envval ? store->envval : "")) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_fr(r, "buffer error");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUPCREDS, m);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUPCREDS, m);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = sshbuf_get_u32(m, &ok)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_fr(r, "buffer error");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(m);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return (ok);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif /* GSSAPI */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/monitor_wrap.h b/monitor_wrap.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index a163b67d..f51bcca0 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/monitor_wrap.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/monitor_wrap.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -65,8 +65,10 @@ int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--int mm_ssh_gssapi_userok(char *user);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef USE_PAM
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/readconf.c b/readconf.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index bcca6ed4..dc7ece37 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/readconf.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/readconf.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -67,6 +67,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "uidswap.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "myproposal.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "digest.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "ssh-gss.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* Format of the configuration file:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -161,6 +162,8 @@ typedef enum {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   oClearAllForwardings, oNoHostAuthenticationForLocalhost,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   oAddressFamily, oGssAuthentication, oGssDelegateCreds,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  oGssServerIdentity, oGssKexAlgorithms,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   oHashKnownHosts,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -206,10 +209,22 @@ static struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* Sometimes-unsupported options */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #if defined(GSSAPI)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "gssapiauthentication", oGssAuthentication },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssapikeyexchange", oGssKeyEx },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "gssapidelegatecredentials", oGssDelegateCreds },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssapitrustdns", oGssTrustDns },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssapiclientidentity", oGssClientIdentity },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssapiserveridentity", oGssServerIdentity },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssapirenewalforcesrekey", oGssRenewalRekey },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssapikexalgorithms", oGssKexAlgorithms },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "gssapiauthentication", oUnsupported },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssapikeyexchange", oUnsupported },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "gssapidelegatecredentials", oUnsupported },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssapitrustdns", oUnsupported },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssapiclientidentity", oUnsupported },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssapiserveridentity", oUnsupported },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssapirenewalforcesrekey", oUnsupported },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssapikexalgorithms", oUnsupported },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef ENABLE_PKCS11
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "pkcs11provider", oPKCS11Provider },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1113,10 +1128,46 @@ parse_time:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           intptr = &options->gss_authentication;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case oGssKeyEx:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          intptr = &options->gss_keyex;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   case oGssDelegateCreds:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           intptr = &options->gss_deleg_creds;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case oGssTrustDns:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          intptr = &options->gss_trust_dns;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case oGssClientIdentity:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          charptr = &options->gss_client_identity;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto parse_string;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case oGssServerIdentity:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          charptr = &options->gss_server_identity;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto parse_string;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case oGssRenewalRekey:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          intptr = &options->gss_renewal_rekey;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case oGssKexAlgorithms:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          arg = argv_next(&ac, &av);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (!arg || *arg == '\0') {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  error("%.200s line %d: Missing argument.",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      filename, linenum);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  goto out;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (!kex_gss_names_valid(arg)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  error("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      filename, linenum, arg ? arg : "<NONE>");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  goto out;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (*activep && options->gss_kex_algorithms == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  options->gss_kex_algorithms = xstrdup(arg);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   case oBatchMode:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           intptr = &options->batch_mode;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2333,7 +2384,13 @@ initialize_options(Options * options)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->fwd_opts.streamlocal_bind_unlink = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->pubkey_authentication = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->gss_authentication = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  options->gss_keyex = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->gss_deleg_creds = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  options->gss_trust_dns = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  options->gss_renewal_rekey = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  options->gss_client_identity = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  options->gss_server_identity = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  options->gss_kex_algorithms = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->password_authentication = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->kbd_interactive_authentication = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->kbd_interactive_devices = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2490,8 +2547,18 @@ fill_default_options(Options * options)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           options->pubkey_authentication = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options->gss_authentication == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           options->gss_authentication = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options->gss_keyex == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          options->gss_keyex = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options->gss_deleg_creds == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           options->gss_deleg_creds = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options->gss_trust_dns == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          options->gss_trust_dns = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options->gss_renewal_rekey == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          options->gss_renewal_rekey = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options->gss_kex_algorithms == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options->password_authentication == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           options->password_authentication = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options->kbd_interactive_authentication == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -3282,7 +3349,14 @@ dump_client_config(Options *o, const char *host)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  dump_cfg_fmtint(oGssKeyEx, o->gss_keyex);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  dump_cfg_fmtint(oGssTrustDns, o->gss_trust_dns);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  dump_cfg_fmtint(oGssRenewalRekey, o->gss_renewal_rekey);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  dump_cfg_string(oGssClientIdentity, o->gss_client_identity);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  dump_cfg_string(oGssServerIdentity, o->gss_server_identity);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  dump_cfg_string(oGssKexAlgorithms, o->gss_kex_algorithms ?
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      o->gss_kex_algorithms : GSS_KEX_DEFAULT_KEX);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif /* GSSAPI */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/readconf.h b/readconf.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index f24719f9..00895ad8 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/readconf.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/readconf.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -39,7 +39,13 @@ typedef struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     pubkey_authentication;  /* Try ssh2 pubkey authentication. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     hostbased_authentication;       /* ssh2's rhosts_rsa */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     gss_authentication;     /* Try GSS authentication */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int     gss_keyex;              /* Try GSS key exchange */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     gss_deleg_creds;        /* Delegate GSS credentials */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int     gss_trust_dns;          /* Trust DNS for GSS canonicalization */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int     gss_renewal_rekey;      /* Credential renewal forces rekey */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char    *gss_client_identity;   /* Principal to initiate GSSAPI with */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char    *gss_server_identity;   /* GSSAPI target principal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char    *gss_kex_algorithms;    /* GSSAPI kex methods to be offered by client. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     password_authentication;        /* Try password
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                                            * authentication. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     kbd_interactive_authentication; /* Try keyboard-interactive auth. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/servconf.c b/servconf.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index b2fbf0b2..d78fbb67 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/servconf.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/servconf.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -70,6 +70,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "auth.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "myproposal.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "digest.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "ssh-gss.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static void add_listen_addr(ServerOptions *, const char *,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     const char *, int);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -136,8 +137,11 @@ initialize_server_options(ServerOptions *options)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->kerberos_ticket_cleanup = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->kerberos_get_afs_token = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->gss_authentication=-1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  options->gss_keyex = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->gss_cleanup_creds = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->gss_strict_acceptor = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  options->gss_store_rekey = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  options->gss_kex_algorithms = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->password_authentication = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->kbd_interactive_authentication = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   options->permit_empty_passwd = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -356,10 +360,18 @@ fill_default_server_options(ServerOptions *options)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           options->kerberos_get_afs_token = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options->gss_authentication == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           options->gss_authentication = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options->gss_keyex == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          options->gss_keyex = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options->gss_cleanup_creds == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           options->gss_cleanup_creds = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options->gss_strict_acceptor == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           options->gss_strict_acceptor = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options->gss_store_rekey == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          options->gss_store_rekey = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options->gss_kex_algorithms == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options->password_authentication == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           options->password_authentication = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options->kbd_interactive_authentication == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -505,6 +517,7 @@ typedef enum {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   sAcceptEnv, sSetEnv, sPermitTunnel,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   sUsePrivilegeSeparation, sAllowAgentForwarding,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -586,12 +599,22 @@ static struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssapicleanupcreds", sGssCleanupCreds, SSHCFG_GLOBAL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "gssapiauthentication", sUnsupported, SSHCFG_ALL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { "challengeresponseauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1575,6 +1598,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           intptr = &options->gss_authentication;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case sGssKeyEx:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          intptr = &options->gss_keyex;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   case sGssCleanupCreds:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           intptr = &options->gss_cleanup_creds;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1583,6 +1610,22 @@ process_server_config_line_depth(ServerOptions *options, char *line,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           intptr = &options->gss_strict_acceptor;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case sGssStoreRekey:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          intptr = &options->gss_store_rekey;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case sGssKexAlgorithms:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          arg = argv_next(&ac, &av);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (!arg || *arg == '\0')
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  fatal("%.200s line %d: Missing argument.",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      filename, linenum);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (!kex_gss_names_valid(arg))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      filename, linenum, arg ? arg : "<NONE>");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (*activep && options->gss_kex_algorithms == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  options->gss_kex_algorithms = xstrdup(arg);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   case sPasswordAuthentication:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           intptr = &options->password_authentication;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           goto parse_flag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2891,6 +2934,10 @@ dump_config(ServerOptions *o)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  dump_cfg_fmtint(sGssKeyEx, o->gss_keyex);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  dump_cfg_string(sGssKexAlgorithms, o->gss_kex_algorithms);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   dump_cfg_fmtint(sKbdInteractiveAuthentication,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/servconf.h b/servconf.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index dd5cbc15..413413e9 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/servconf.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/servconf.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -141,8 +141,11 @@ typedef struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     kerberos_get_afs_token;         /* If true, try to get AFS token if
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                                            * authenticated with Kerberos. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     gss_authentication;     /* If true, permit GSSAPI authentication */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int     gss_keyex;              /* If true, permit GSSAPI key exchange */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     gss_cleanup_creds;      /* If true, destroy cred cache on logout */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     gss_strict_acceptor;    /* If true, restrict the GSSAPI acceptor name */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int     gss_store_rekey;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char   *gss_kex_algorithms;     /* GSSAPI kex methods to be offered by client. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     password_authentication;        /* If true, permit password
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                                            * authentication. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int     kbd_interactive_authentication; /* If true, permit */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/session.c b/session.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 5f423f9f..165b8782 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/session.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/session.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2670,13 +2670,19 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef KRB5
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options.kerberos_ticket_cleanup &&
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--      authctxt->krb5_ctx)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      authctxt->krb5_ctx) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          temporarily_use_uid(authctxt->pw);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           krb5_cleanup_proc(authctxt);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          restore_uid();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  if (options.gss_cleanup_creds)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options.gss_cleanup_creds) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          temporarily_use_uid(authctxt->pw);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           ssh_gssapi_cleanup_creds();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          restore_uid();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* remove agent socket */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/ssh-gss.h b/ssh-gss.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index a8af117d..6303ce18 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/ssh-gss.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/ssh-gss.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1,6 +1,6 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* $OpenBSD: ssh-gss.h,v 1.15 2021/01/27 10:05:28 djm Exp $ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  * Redistribution and use in source and binary forms, with or without
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  * modification, are permitted provided that the following conditions
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -61,10 +61,34 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #define SSH_GSS_OIDTYPE 0x06
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define SSH2_MSG_KEXGSS_INIT                            30
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define SSH2_MSG_KEXGSS_CONTINUE                        31
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define SSH2_MSG_KEXGSS_COMPLETE                        32
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define SSH2_MSG_KEXGSS_HOSTKEY                         33
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define SSH2_MSG_KEXGSS_ERROR                           34
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define SSH2_MSG_KEXGSS_GROUPREQ                  40
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define SSH2_MSG_KEXGSS_GROUP                             41
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define KEX_GSS_GRP1_SHA1_ID                              "gss-group1-sha1-"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define KEX_GSS_GRP14_SHA1_ID                             "gss-group14-sha1-"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define KEX_GSS_GRP14_SHA256_ID                   "gss-group14-sha256-"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define KEX_GSS_GRP16_SHA512_ID                   "gss-group16-sha512-"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define KEX_GSS_GEX_SHA1_ID                               "gss-gex-sha1-"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define KEX_GSS_NISTP256_SHA256_ID                        "gss-nistp256-sha256-"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define KEX_GSS_C25519_SHA256_ID                  "gss-curve25519-sha256-"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define        GSS_KEX_DEFAULT_KEX \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  KEX_GSS_GRP14_SHA256_ID "," \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  KEX_GSS_GRP16_SHA512_ID "," \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  KEX_GSS_NISTP256_SHA256_ID "," \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  KEX_GSS_C25519_SHA256_ID "," \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  KEX_GSS_GRP14_SHA1_ID "," \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  KEX_GSS_GEX_SHA1_ID
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- typedef struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   char *filename;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   char *envvar;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   char *envval;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct passwd *owner;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   void *data;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- } ssh_gssapi_ccache;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -72,8 +96,11 @@ typedef struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   gss_buffer_desc displayname;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   gss_buffer_desc exportedname;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   gss_cred_id_t creds;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_name_t name;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   struct ssh_gssapi_mech_struct *mech;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   ssh_gssapi_ccache store;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int used;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int updated;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- } ssh_gssapi_client;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- typedef struct ssh_gssapi_mech_struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -84,6 +111,7 @@ typedef struct ssh_gssapi_mech_struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int (*userok) (ssh_gssapi_client *, char *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int (*localname) (ssh_gssapi_client *, char **);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   void (*storecreds) (ssh_gssapi_client *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- } ssh_gssapi_mech;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- typedef struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -94,10 +122,11 @@ typedef struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   gss_OID         oid; /* client */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   gss_cred_id_t   creds; /* server */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   gss_name_t      client; /* server */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  gss_cred_id_t   client_creds; /* server */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_cred_id_t   client_creds; /* both */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- } Gssctxt;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- extern ssh_gssapi_mech *supported_mechs[];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+extern Gssctxt *gss_kex_context;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int  ssh_gssapi_check_oid(Gssctxt *, void *, size_t);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -109,6 +138,7 @@ OM_uint32 ssh_gssapi_test_oid_supported(OM_uint32 *, gss_OID, int *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- struct sshbuf;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- int ssh_gssapi_get_buffer_desc(struct sshbuf *, gss_buffer_desc *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int ssh_gssapi_sshpkt_get_buffer_desc(struct ssh *, gss_buffer_desc *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- OM_uint32 ssh_gssapi_import_name(Gssctxt *, const char *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- OM_uint32 ssh_gssapi_init_ctx(Gssctxt *, int,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -123,17 +153,33 @@ void ssh_gssapi_delete_ctx(Gssctxt **);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- void ssh_gssapi_buildmic(struct sshbuf *, const char *,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     const char *, const char *, const struct sshbuf *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *, const char *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int ssh_gssapi_credentials_updated(Gssctxt *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* In the server */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    const char *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+char *ssh_gssapi_client_mechanisms(const char *, const char *, const char *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    const char *, const char *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    const char *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--int ssh_gssapi_userok(char *name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int ssh_gssapi_userok(char *name, struct passwd *, int kex);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- void ssh_gssapi_do_child(char ***, u_int *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- void ssh_gssapi_cleanup_creds(void);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- void ssh_gssapi_storecreds(void);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- const char *ssh_gssapi_displayname(void);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+char *ssh_gssapi_server_mechanisms(void);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int ssh_gssapi_oid_table_ok(void);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int ssh_gssapi_update_creds(ssh_gssapi_ccache *store);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void ssh_gssapi_rekey_creds(void);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif /* GSSAPI */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif /* _SSH_GSS_H */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/ssh.1 b/ssh.1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 7efb2382..67ea50aa 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/ssh.1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/ssh.1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -530,7 +530,13 @@ For full details of the options listed below, and their possible values, see
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .It GatewayPorts
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .It GlobalKnownHostsFile
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .It GSSAPIAuthentication
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.It GSSAPIKeyExchange
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.It GSSAPIClientIdentity
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .It GSSAPIDelegateCredentials
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.It GSSAPIKexAlgorithms
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.It GSSAPIRenewalForcesRekey
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.It GSSAPIServerIdentity
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.It GSSAPITrustDns
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .It HashKnownHosts
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .It Host
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .It HostbasedAcceptedAlgorithms
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -607,6 +613,8 @@ flag),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- (supported message integrity codes),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .Ar kex
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- (key exchange algorithms),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Ar kex-gss
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+(GSSAPI key exchange algorithms),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .Ar key
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- (key types),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .Ar key-cert
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/ssh.c b/ssh.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index e6fe8090..519b7a23 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/ssh.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/ssh.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -775,6 +775,8 @@ main(int ac, char **av)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   else if (strcmp(optarg, "kex") == 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                       strcasecmp(optarg, "KexAlgorithms") == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                           cp = kex_alg_list('\n');
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  else if (strcmp(optarg, "kex-gss") == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          cp = kex_gss_alg_list('\n');
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   else if (strcmp(optarg, "key") == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                           cp = sshkey_alg_list(0, 0, 0, '\n');
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   else if (strcmp(optarg, "key-cert") == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -802,8 +804,8 @@ main(int ac, char **av)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   } else if (strcmp(optarg, "help") == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                           cp = xstrdup(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                               "cipher\ncipher-auth\ncompression\nkex\n"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                              "key\nkey-cert\nkey-plain\nkey-sig\nmac\n"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                              "protocol-version\nsig");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              "kex-gss\nkey\nkey-cert\nkey-plain\n"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              "key-sig\nmac\nprotocol-version\nsig");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   if (cp == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                           fatal("Unsupported query \"%s\"", optarg);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/ssh_config b/ssh_config
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 842ea866..52aae869 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/ssh_config
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/ssh_config
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -24,6 +24,8 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #   HostbasedAuthentication no
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #   GSSAPIAuthentication no
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #   GSSAPIDelegateCredentials no
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#   GSSAPIKeyExchange no
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#   GSSAPITrustDNS no
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #   BatchMode no
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #   CheckHostIP yes
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #   AddressFamily any
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/ssh_config.5 b/ssh_config.5
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 170125a0..2bac0a75 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/ssh_config.5
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/ssh_config.5
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -833,10 +833,67 @@ The default is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- Specifies whether user authentication based on GSSAPI is allowed.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- The default is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .Cm no .
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.It Cm GSSAPIClientIdentity
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+If set, specifies the GSSAPI client identity that ssh should use when
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+connecting to the server. The default is unset, which means that the default
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+identity will be used.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .It Cm GSSAPIDelegateCredentials
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- Forward (delegate) credentials to the server.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- The default is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .Cm no .
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.It Cm GSSAPIKeyExchange
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Specifies whether key exchange based on GSSAPI may be used. When using
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+GSSAPI key exchange the server need not have a host key.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+The default is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Dq no .
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.It Cm GSSAPIRenewalForcesRekey
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+If set to
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Dq yes
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+then renewal of the client's GSSAPI credentials will force the rekeying of the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ssh connection. With a compatible server, this will delegate the renewed
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+credentials to a session on the server.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Pp
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Checks are made to ensure that credentials are only propagated when the new
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+credentials match the old ones on the originating client and where the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+receiving server still has the old set in its cache.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Pp
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+The default is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Dq no .
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Pp
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+For this to work
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Cm GSSAPIKeyExchange
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+needs to be enabled in the server and also used by the client.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.It Cm GSSAPIServerIdentity
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+If set, specifies the GSSAPI server identity that ssh should expect when
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+connecting to the server. The default is unset, which means that the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+expected GSSAPI server identity will be determined from the target
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+hostname.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.It Cm GSSAPITrustDns
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Set to
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Dq yes
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+to indicate that the DNS is trusted to securely canonicalize
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+the name of the host being connected to. If
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Dq no ,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+the hostname entered on the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+command line will be passed untouched to the GSSAPI library.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+The default is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Dq no .
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.It Cm GSSAPIKexAlgorithms
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+The list of key exchange algorithms that are offered for GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+key exchange. Possible values are
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Bd -literal -offset 3n
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+gss-gex-sha1-,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+gss-group1-sha1-,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+gss-group14-sha1-,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+gss-group14-sha256-,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+gss-group16-sha512-,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+gss-nistp256-sha256-,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+gss-curve25519-sha256-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Ed
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Pp
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+The default is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-,gss-curve25519-sha256-,gss-gex-sha1-,gss-group14-sha1- .
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+This option only applies to connections using GSSAPI.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .It Cm HashKnownHosts
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- Indicates that
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .Xr ssh 1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/sshconnect2.c b/sshconnect2.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index fea50fab..9837b212 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/sshconnect2.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/sshconnect2.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -81,8 +81,6 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* import */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--extern char *client_version_string;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--extern char *server_version_string;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- extern Options options;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -220,6 +218,11 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   char *s, *all_key;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int r, use_known_hosts_order = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#if defined(GSSAPI) && defined(WITH_OPENSSL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char *orig = NULL, *gss = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char *gss_host = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   xxx_host = host;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   xxx_hostaddr = hostaddr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   xxx_conn_info = cinfo;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -264,6 +267,42 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-               compat_pkalg_proposal(ssh, options.hostkeyalgorithms);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#if defined(GSSAPI) && defined(WITH_OPENSSL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options.gss_keyex) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* Add the GSSAPI mechanisms currently supported on this
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * client to the key exchange algorithm proposal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          orig = myproposal[PROPOSAL_KEX_ALGS];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (options.gss_server_identity) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  gss_host = xstrdup(options.gss_server_identity);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          } else if (options.gss_trust_dns) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  gss_host = remote_hostname(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* Fall back to specified host if we are using proxy command
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                   * and can not use DNS on that socket */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  if (strcmp(gss_host, "UNKNOWN") == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          free(gss_host);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                          gss_host = xstrdup(host);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  gss_host = xstrdup(host);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          gss = ssh_gssapi_client_mechanisms(gss_host,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              options.gss_client_identity, options.gss_kex_algorithms);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (gss) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  debug("Offering GSSAPI proposal: %s", gss);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      "%s,%s", gss, orig);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  /* If we've got GSSAPI algorithms, then we also support the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                   * 'null' hostkey, as a last resort */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                      "%s,null", orig);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (options.rekey_limit || options.rekey_interval)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           ssh_packet_set_rekey_limits(ssh, options.rekey_limit,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-               options.rekey_interval);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -282,16 +321,46 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # ifdef OPENSSL_HAS_ECC
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_client;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options.gss_keyex) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh->kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh->kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh->kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_client;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh->kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_client;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh->kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_client;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh->kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_client;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh->kex->kex[KEX_GSS_C25519_SHA256] = kexgss_client;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif /* WITH_OPENSSL */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   ssh->kex->verify_host_key=&verify_host_key_callback;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#if defined(GSSAPI) && defined(WITH_OPENSSL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options.gss_keyex) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh->kex->gss_deleg_creds = options.gss_deleg_creds;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh->kex->gss_trust_dns = options.gss_trust_dns;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh->kex->gss_client = options.gss_client_identity;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          ssh->kex->gss_host = gss_host;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &ssh->kex->done);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* remove ext-info from the KEX proposals for rekeying */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   myproposal[PROPOSAL_KEX_ALGS] =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       compat_kex_proposal(ssh, options.kex_algorithms);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#if defined(GSSAPI) && defined(WITH_OPENSSL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* repair myproposal after it was crumpled by the */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* ext-info removal above */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (gss) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          orig = myproposal[PROPOSAL_KEX_ALGS];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              "%s,%s", gss, orig);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          free(gss);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if ((r = kex_prop2buf(ssh->kex->my, myproposal)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           fatal_r(r, "kex_prop2buf");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -385,6 +454,7 @@ static int input_gssapi_response(int type, u_int32_t, struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static int input_gssapi_token(int type, u_int32_t, struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static int input_gssapi_error(int, u_int32_t, struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static int input_gssapi_errtok(int, u_int32_t, struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static int userauth_gsskeyex(struct ssh *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- void      userauth(struct ssh *, char *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -401,6 +471,11 @@ static char *authmethods_get(void);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- Authmethod authmethods[] = {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  {"gssapi-keyex",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          userauth_gsskeyex,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          NULL,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          &options.gss_keyex,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          NULL},
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   {"gssapi-with-mic",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           userauth_gssapi,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           userauth_gssapi_cleanup,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -776,12 +851,32 @@ userauth_gssapi(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   OM_uint32 min;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int r, ok = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   gss_OID mech = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char *gss_host = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options.gss_server_identity) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          gss_host = xstrdup(options.gss_server_identity);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  } else if (options.gss_trust_dns) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          gss_host = remote_hostname(ssh);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /* Fall back to specified host if we are using proxy command
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+           * and can not use DNS on that socket */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (strcmp(gss_host, "UNKNOWN") == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  free(gss_host);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  gss_host = xstrdup(authctxt->host);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          gss_host = xstrdup(authctxt->host);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* Try one GSSAPI method at a time, rather than sending them all at
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    * once. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (authctxt->gss_supported_mechs == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          gss_indicate_mechs(&min, &authctxt->gss_supported_mechs);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (GSS_ERROR(gss_indicate_mechs(&min,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              &authctxt->gss_supported_mechs))) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  authctxt->gss_supported_mechs = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  free(gss_host);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                  return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* Check to see whether the mechanism is usable before we offer it */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   while (authctxt->mech_tried < authctxt->gss_supported_mechs->count &&
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -790,13 +885,15 @@ userauth_gssapi(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-               elements[authctxt->mech_tried];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           /* My DER encoding requires length<128 */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           if (mech->length < 128 && ssh_gssapi_check_mechanism(&gssctxt,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--              mech, authctxt->host)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              mech, gss_host, options.gss_client_identity)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   ok = 1; /* Mechanism works */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   authctxt->mech_tried++;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  free(gss_host);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (!ok || mech == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1037,6 +1134,55 @@ input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   free(lang);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   return r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+userauth_gsskeyex(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  struct sshbuf *b = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  Authctxt *authctxt = ssh->authctxt;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_buffer_desc gssbuf;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  OM_uint32 ms;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  static int attempt = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (attempt++ >= 1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return (0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (gss_kex_context == NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug("No valid Key exchange context");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return (0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((b = sshbuf_new()) == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_f("sshbuf_new failed");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      "gssapi-keyex", ssh->kex->session_id);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_f("sshbuf_mutable_ptr failed");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gssbuf.length = sshbuf_len(b);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          sshbuf_free(b);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          return (0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      (r = sshpkt_send(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal_fr(r, "parsing");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  sshbuf_free(b);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gss_release_buffer(&ms, &mic);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return (1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif /* GSSAPI */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/sshd.c b/sshd.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index ea63d030..eb884efd 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/sshd.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/sshd.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -807,8 +807,8 @@ notify_hostkeys(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   debug3_f("sent %u hostkeys", nkeys);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if (nkeys == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          fatal_f("no hostkeys");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  if ((r = sshpkt_send(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          debug3_f("no hostkeys");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  else if ((r = sshpkt_send(ssh)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           sshpkt_fatal(ssh, r, "%s: send", __func__);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   sshbuf_free(buf);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1898,7 +1898,8 @@ main(int ac, char **av)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           free(fp);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   accumulate_host_timing_secret(cfg, NULL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--  if (!sensitive_data.have_ssh2_key) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* The GSSAPI key exchange can run without a host key */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!sensitive_data.have_ssh2_key && !options.gss_keyex) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           logit("sshd: no hostkeys available -- exiting.");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           exit(1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2388,6 +2389,48 @@ do_ssh2_kex(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       ssh, list_hostkey_types());
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#if defined(GSSAPI) && defined(WITH_OPENSSL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char *orig;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char *gss = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char *newstr = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  orig = myproposal[PROPOSAL_KEX_ALGS];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * If we don't have a host key, then there's no point advertising
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * the other key exchange algorithms
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          orig = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options.gss_keyex)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          gss = ssh_gssapi_server_mechanisms();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          gss = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (gss && orig)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          xasprintf(&newstr, "%s,%s", gss, orig);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  else if (gss)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          newstr = gss;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  else if (orig)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          newstr = orig;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * If we've got GSSAPI mechanisms, then we've got the 'null' host
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * key alg, but we can't tell people about it unless its the only
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * host key algorithm we support
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (newstr)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          myproposal[PROPOSAL_KEX_ALGS] = newstr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          fatal("No supported key exchange algorithms");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* start key exchange */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   if ((r = kex_setup(ssh, myproposal)) != 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           fatal_r(r, "kex_setup");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2403,7 +2446,18 @@ do_ssh2_kex(struct ssh *ssh)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # ifdef OPENSSL_HAS_ECC
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   kex->kex[KEX_ECDH_SHA2] = kex_gen_server;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# ifdef GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (options.gss_keyex) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif /* WITH_OPENSSL */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   kex->kex[KEX_C25519_SHA256] = kex_gen_server;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   kex->load_host_public_key=&get_hostkey_public_by_type;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/sshd_config b/sshd_config
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index c423eba1..f91d293c 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/sshd_config
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/sshd_config
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -69,6 +69,8 @@ AuthorizedKeysFile       .ssh/authorized_keys
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # GSSAPI options
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #GSSAPIAuthentication no
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #GSSAPICleanupCredentials yes
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#GSSAPIStrictAcceptorCheck yes
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#GSSAPIKeyExchange no
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # Set this to 'yes' to enable PAM authentication, account processing,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # and session processing. If this is enabled, PAM authentication will
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/sshd_config.5 b/sshd_config.5
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index a8d0545c..6076df94 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/sshd_config.5
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/sshd_config.5
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -650,6 +650,11 @@ Specifies whether to automatically destroy the user's credentials cache
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- on logout.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- The default is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .Cm yes .
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.It Cm GSSAPIKeyExchange
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+doesn't rely on ssh keys to verify host identity.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+The default is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Cm no .
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .It Cm GSSAPIStrictAcceptorCheck
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- Determines whether to be strict about the identity of the GSSAPI acceptor
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- a client authenticates against.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -664,6 +669,31 @@ machine's default store.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- This facility is provided to assist with operation on multi homed machines.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- The default is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .Cm yes .
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.It Cm GSSAPIStoreCredentialsOnRekey
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Controls whether the user's GSSAPI credentials should be updated following a
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+successful connection rekeying. This option can be used to accepted renewed
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+or updated credentials from a compatible client. The default is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Dq no .
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Pp
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+For this to work
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Cm GSSAPIKeyExchange
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+needs to be enabled in the server and also used by the client.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.It Cm GSSAPIKexAlgorithms
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+The list of key exchange algorithms that are accepted by GSSAPI
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+key exchange. Possible values are
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Bd -literal -offset 3n
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+gss-gex-sha1-,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+gss-group1-sha1-,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+gss-group14-sha1-,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+gss-group14-sha256-,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+gss-group16-sha512-,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+gss-nistp256-sha256-,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+gss-curve25519-sha256-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Ed
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Pp
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+The default is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-,gss-curve25519-sha256-,gss-gex-sha1-,gss-group14-sha1- .
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+This option only applies to connections using GSSAPI.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- .It Cm HostbasedAcceptedAlgorithms
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- Specifies the signature algorithms that will be accepted for hostbased
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- authentication as a list of comma-separated patterns.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/sshkey.c b/sshkey.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 0dbc0d87..17f8aa91 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/sshkey.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/sshkey.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -156,6 +156,7 @@ static const struct keytype keytypes[] = {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       KEY_ECDSA_SK_CERT, NID_X9_62_prime256v1, 1, 0 },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # endif /* OPENSSL_HAS_ECC */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif /* WITH_OPENSSL */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  { "null", "null", NULL, KEY_NULL, 0, 0, 0 },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   { NULL, NULL, NULL, -1, -1, 0, 0 }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -257,7 +258,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   const struct keytype *kt;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   for (kt = keytypes; kt->type != -1; kt++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--          if (kt->name == NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (kt->name == NULL || kt->type == KEY_NULL)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   continue;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           if (!include_sigonly && kt->sigonly)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   continue;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/sshkey.h b/sshkey.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 6edc6c5a..94501115 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/sshkey.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/sshkey.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -71,6 +71,7 @@ enum sshkey_types {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   KEY_ECDSA_SK_CERT,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   KEY_ED25519_SK,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   KEY_ED25519_SK_CERT,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  KEY_NULL,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   KEY_UNSPEC
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/net/openssh/files/series-gsskex b/net/openssh/files/series-gsskex
</span>deleted file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 86f0232ffb0..00000000000
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/net/openssh/files/series-gsskex
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,8 +0,0 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-launchd.patch
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-pam.patch
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-patch-sandbox-darwin.c-apple-sandbox-named-external.diff
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-patch-sshd.c-apple-sandbox-named-external.diff
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-0002-Apple-keychain-integration-other-changes.patch
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-macports-config.patch
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-patch-openbsd_compat-memmem-bug.diff
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-openssh-8.8p1-gsskex.patch
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/net/openssh/files/series-hpn b/net/openssh/files/series-hpn
</span>deleted file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index e128c7b759d..00000000000
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/net/openssh/files/series-hpn
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,9 +0,0 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-launchd.patch
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-pam.patch
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-patch-sandbox-darwin.c-apple-sandbox-named-external.diff
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-patch-sshd.c-apple-sandbox-named-external.diff
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-0002-Apple-keychain-integration-other-changes.patch
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-macports-config.patch
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-patch-openbsd_compat-memmem-bug.diff
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-openssh-8.1p1-hpnssh14v18.diff
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-openssh-8.1p1-hpnssh14v18-openssl-1.1.diff
</span></pre><pre style='margin:0'>

</pre>