]> andersk Git - gssapi-openssh.git/commitdiff
Initial revision
authorjbasney <jbasney>
Fri, 4 Apr 2003 18:31:37 +0000 (18:31 +0000)
committerjbasney <jbasney>
Fri, 4 Apr 2003 18:31:37 +0000 (18:31 +0000)
16 files changed:
openssh/kexdhc.c [new file with mode: 0644]
openssh/kexdhs.c [new file with mode: 0644]
openssh/kexgexc.c [new file with mode: 0644]
openssh/kexgexs.c [new file with mode: 0644]
openssh/openbsd-compat/basename.c [new file with mode: 0644]
openssh/openbsd-compat/basename.h [new file with mode: 0644]
openssh/openbsd-compat/vis.c [new file with mode: 0644]
openssh/openbsd-compat/vis.h [new file with mode: 0644]
openssh/progressmeter.c [new file with mode: 0644]
openssh/progressmeter.h [new file with mode: 0644]
openssh/regress/agent-getpeereid.sh [new file with mode: 0644]
openssh/regress/agent-ptrace.sh [new file with mode: 0644]
openssh/regress/agent-timeout.sh [new file with mode: 0644]
openssh/regress/keygen-change.sh [new file with mode: 0644]
openssh/regress/sftp-batch.sh [new file with mode: 0644]
openssh/regress/sftp-cmds.sh [new file with mode: 0644]

diff --git a/openssh/kexdhc.c b/openssh/kexdhc.c
new file mode 100644 (file)
index 0000000..fe6dc53
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2001 Markus Friedl.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: kexdhc.c,v 1.1 2003/02/16 17:09:57 markus Exp $");
+
+#include "xmalloc.h"
+#include "key.h"
+#include "kex.h"
+#include "log.h"
+#include "packet.h"
+#include "dh.h"
+#include "ssh2.h"
+
+void
+kexdh_client(Kex *kex)
+{
+       BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
+       DH *dh;
+       Key *server_host_key;
+       u_char *server_host_key_blob = NULL, *signature = NULL;
+       u_char *kbuf, *hash;
+       u_int klen, kout, slen, sbloblen;
+
+       /* generate and send 'e', client DH public key */
+       dh = dh_new_group1();
+       dh_gen_key(dh, kex->we_need * 8);
+       packet_start(SSH2_MSG_KEXDH_INIT);
+       packet_put_bignum2(dh->pub_key);
+       packet_send();
+
+       debug("sending SSH2_MSG_KEXDH_INIT");
+#ifdef DEBUG_KEXDH
+       DHparams_print_fp(stderr, dh);
+       fprintf(stderr, "pub= ");
+       BN_print_fp(stderr, dh->pub_key);
+       fprintf(stderr, "\n");
+#endif
+
+       debug("expecting SSH2_MSG_KEXDH_REPLY");
+       packet_read_expect(SSH2_MSG_KEXDH_REPLY);
+
+       /* key, cert */
+       server_host_key_blob = packet_get_string(&sbloblen);
+       server_host_key = key_from_blob(server_host_key_blob, sbloblen);
+       if (server_host_key == NULL)
+               fatal("cannot decode server_host_key_blob");
+       if (server_host_key->type != kex->hostkey_type)
+               fatal("type mismatch for decoded server_host_key_blob");
+       if (kex->verify_host_key == NULL)
+               fatal("cannot verify server_host_key");
+       if (kex->verify_host_key(server_host_key) == -1)
+               fatal("server_host_key verification failed");
+
+       /* DH paramter f, server public DH key */
+       if ((dh_server_pub = BN_new()) == NULL)
+               fatal("dh_server_pub == NULL");
+       packet_get_bignum2(dh_server_pub);
+
+#ifdef DEBUG_KEXDH
+       fprintf(stderr, "dh_server_pub= ");
+       BN_print_fp(stderr, dh_server_pub);
+       fprintf(stderr, "\n");
+       debug("bits %d", BN_num_bits(dh_server_pub));
+#endif
+
+       /* signed H */
+       signature = packet_get_string(&slen);
+       packet_check_eom();
+
+       if (!dh_pub_is_valid(dh, dh_server_pub))
+               packet_disconnect("bad server public DH value");
+
+       klen = DH_size(dh);
+       kbuf = xmalloc(klen);
+       kout = DH_compute_key(kbuf, dh_server_pub, dh);
+#ifdef DEBUG_KEXDH
+       dump_digest("shared secret", kbuf, kout);
+#endif
+       if ((shared_secret = BN_new()) == NULL)
+               fatal("kexdh_client: BN_new failed");
+       BN_bin2bn(kbuf, kout, shared_secret);
+       memset(kbuf, 0, klen);
+       xfree(kbuf);
+
+       /* calc and verify H */
+       hash = kex_dh_hash(
+           kex->client_version_string,
+           kex->server_version_string,
+           buffer_ptr(&kex->my), buffer_len(&kex->my),
+           buffer_ptr(&kex->peer), buffer_len(&kex->peer),
+           server_host_key_blob, sbloblen,
+           dh->pub_key,
+           dh_server_pub,
+           shared_secret
+       );
+       xfree(server_host_key_blob);
+       BN_clear_free(dh_server_pub);
+       DH_free(dh);
+
+       if (key_verify(server_host_key, signature, slen, hash, 20) != 1)
+               fatal("key_verify failed for server_host_key");
+       key_free(server_host_key);
+       xfree(signature);
+
+       /* save session id */
+       if (kex->session_id == NULL) {
+               kex->session_id_len = 20;
+               kex->session_id = xmalloc(kex->session_id_len);
+               memcpy(kex->session_id, hash, kex->session_id_len);
+       }
+
+       kex_derive_keys(kex, hash, shared_secret);
+       BN_clear_free(shared_secret);
+       kex_finish(kex);
+}
diff --git a/openssh/kexdhs.c b/openssh/kexdhs.c
new file mode 100644 (file)
index 0000000..f04bce8
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2001 Markus Friedl.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: kexdhs.c,v 1.1 2003/02/16 17:09:57 markus Exp $");
+
+#include "xmalloc.h"
+#include "key.h"
+#include "kex.h"
+#include "log.h"
+#include "packet.h"
+#include "dh.h"
+#include "ssh2.h"
+#include "monitor_wrap.h"
+
+void
+kexdh_server(Kex *kex)
+{
+       BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
+       DH *dh;
+       Key *server_host_key;
+       u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
+       u_int sbloblen, klen, kout;
+       u_int slen;
+
+       /* generate server DH public key */
+       dh = dh_new_group1();
+       dh_gen_key(dh, kex->we_need * 8);
+
+       debug("expecting SSH2_MSG_KEXDH_INIT");
+       packet_read_expect(SSH2_MSG_KEXDH_INIT);
+
+       if (kex->load_host_key == NULL)
+               fatal("Cannot load hostkey");
+       server_host_key = kex->load_host_key(kex->hostkey_type);
+       if (server_host_key == NULL)
+               fatal("Unsupported hostkey type %d", kex->hostkey_type);
+
+       /* key, cert */
+       if ((dh_client_pub = BN_new()) == NULL)
+               fatal("dh_client_pub == NULL");
+       packet_get_bignum2(dh_client_pub);
+       packet_check_eom();
+
+#ifdef DEBUG_KEXDH
+       fprintf(stderr, "dh_client_pub= ");
+       BN_print_fp(stderr, dh_client_pub);
+       fprintf(stderr, "\n");
+       debug("bits %d", BN_num_bits(dh_client_pub));
+#endif
+
+#ifdef DEBUG_KEXDH
+       DHparams_print_fp(stderr, dh);
+       fprintf(stderr, "pub= ");
+       BN_print_fp(stderr, dh->pub_key);
+       fprintf(stderr, "\n");
+#endif
+       if (!dh_pub_is_valid(dh, dh_client_pub))
+               packet_disconnect("bad client public DH value");
+
+       klen = DH_size(dh);
+       kbuf = xmalloc(klen);
+       kout = DH_compute_key(kbuf, dh_client_pub, dh);
+#ifdef DEBUG_KEXDH
+       dump_digest("shared secret", kbuf, kout);
+#endif
+       if ((shared_secret = BN_new()) == NULL)
+               fatal("kexdh_server: BN_new failed");
+       BN_bin2bn(kbuf, kout, shared_secret);
+       memset(kbuf, 0, klen);
+       xfree(kbuf);
+
+       key_to_blob(server_host_key, &server_host_key_blob, &sbloblen);
+
+       /* calc H */
+       hash = kex_dh_hash(
+           kex->client_version_string,
+           kex->server_version_string,
+           buffer_ptr(&kex->peer), buffer_len(&kex->peer),
+           buffer_ptr(&kex->my), buffer_len(&kex->my),
+           server_host_key_blob, sbloblen,
+           dh_client_pub,
+           dh->pub_key,
+           shared_secret
+       );
+       BN_clear_free(dh_client_pub);
+
+       /* save session id := H */
+       /* XXX hashlen depends on KEX */
+       if (kex->session_id == NULL) {
+               kex->session_id_len = 20;
+               kex->session_id = xmalloc(kex->session_id_len);
+               memcpy(kex->session_id, hash, kex->session_id_len);
+       }
+
+       /* sign H */
+       /* XXX hashlen depends on KEX */
+       PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20));
+
+       /* destroy_sensitive_data(); */
+
+       /* send server hostkey, DH pubkey 'f' and singed H */
+       packet_start(SSH2_MSG_KEXDH_REPLY);
+       packet_put_string(server_host_key_blob, sbloblen);
+       packet_put_bignum2(dh->pub_key);        /* f */
+       packet_put_string(signature, slen);
+       packet_send();
+
+       xfree(signature);
+       xfree(server_host_key_blob);
+       /* have keys, free DH */
+       DH_free(dh);
+
+       kex_derive_keys(kex, hash, shared_secret);
+       BN_clear_free(shared_secret);
+       kex_finish(kex);
+}
diff --git a/openssh/kexgexc.c b/openssh/kexgexc.c
new file mode 100644 (file)
index 0000000..f14ac44
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2000 Niels Provos.  All rights reserved.
+ * Copyright (c) 2001 Markus Friedl.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: kexgexc.c,v 1.1 2003/02/16 17:09:57 markus Exp $");
+
+#include "xmalloc.h"
+#include "key.h"
+#include "kex.h"
+#include "log.h"
+#include "packet.h"
+#include "dh.h"
+#include "ssh2.h"
+#include "compat.h"
+
+void
+kexgex_client(Kex *kex)
+{
+       BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
+       BIGNUM *p = NULL, *g = NULL;
+       Key *server_host_key;
+       u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
+       u_int klen, kout, slen, sbloblen;
+       int min, max, nbits;
+       DH *dh;
+
+       nbits = dh_estimate(kex->we_need * 8);
+
+       if (datafellows & SSH_OLD_DHGEX) {
+               debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD sent");
+
+               /* Old GEX request */
+               packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD);
+               packet_put_int(nbits);
+               min = DH_GRP_MIN;
+               max = DH_GRP_MAX;
+       } else {
+               debug("SSH2_MSG_KEX_DH_GEX_REQUEST sent");
+
+               /* New GEX request */
+               min = DH_GRP_MIN;
+               max = DH_GRP_MAX;
+               packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST);
+               packet_put_int(min);
+               packet_put_int(nbits);
+               packet_put_int(max);
+       }
+#ifdef DEBUG_KEXDH
+       fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n",
+           min, nbits, max);
+#endif
+       packet_send();
+
+       debug("expecting SSH2_MSG_KEX_DH_GEX_GROUP");
+       packet_read_expect(SSH2_MSG_KEX_DH_GEX_GROUP);
+
+       if ((p = BN_new()) == NULL)
+               fatal("BN_new");
+       packet_get_bignum2(p);
+       if ((g = BN_new()) == NULL)
+               fatal("BN_new");
+       packet_get_bignum2(g);
+       packet_check_eom();
+
+       if (BN_num_bits(p) < min || BN_num_bits(p) > max)
+               fatal("DH_GEX group out of range: %d !< %d !< %d",
+                   min, BN_num_bits(p), max);
+
+       dh = dh_new_group(g, p);
+       dh_gen_key(dh, kex->we_need * 8);
+
+#ifdef DEBUG_KEXDH
+       DHparams_print_fp(stderr, dh);
+       fprintf(stderr, "pub= ");
+       BN_print_fp(stderr, dh->pub_key);
+       fprintf(stderr, "\n");
+#endif
+
+       debug("SSH2_MSG_KEX_DH_GEX_INIT sent");
+       /* generate and send 'e', client DH public key */
+       packet_start(SSH2_MSG_KEX_DH_GEX_INIT);
+       packet_put_bignum2(dh->pub_key);
+       packet_send();
+
+       debug("expecting SSH2_MSG_KEX_DH_GEX_REPLY");
+       packet_read_expect(SSH2_MSG_KEX_DH_GEX_REPLY);
+
+       /* key, cert */
+       server_host_key_blob = packet_get_string(&sbloblen);
+       server_host_key = key_from_blob(server_host_key_blob, sbloblen);
+       if (server_host_key == NULL)
+               fatal("cannot decode server_host_key_blob");
+       if (server_host_key->type != kex->hostkey_type)
+               fatal("type mismatch for decoded server_host_key_blob");
+       if (kex->verify_host_key == NULL)
+               fatal("cannot verify server_host_key");
+       if (kex->verify_host_key(server_host_key) == -1)
+               fatal("server_host_key verification failed");
+
+       /* DH paramter f, server public DH key */
+       if ((dh_server_pub = BN_new()) == NULL)
+               fatal("dh_server_pub == NULL");
+       packet_get_bignum2(dh_server_pub);
+
+#ifdef DEBUG_KEXDH
+       fprintf(stderr, "dh_server_pub= ");
+       BN_print_fp(stderr, dh_server_pub);
+       fprintf(stderr, "\n");
+       debug("bits %d", BN_num_bits(dh_server_pub));
+#endif
+
+       /* signed H */
+       signature = packet_get_string(&slen);
+       packet_check_eom();
+
+       if (!dh_pub_is_valid(dh, dh_server_pub))
+               packet_disconnect("bad server public DH value");
+
+       klen = DH_size(dh);
+       kbuf = xmalloc(klen);
+       kout = DH_compute_key(kbuf, dh_server_pub, dh);
+#ifdef DEBUG_KEXDH
+       dump_digest("shared secret", kbuf, kout);
+#endif
+       if ((shared_secret = BN_new()) == NULL)
+               fatal("kexgex_client: BN_new failed");
+       BN_bin2bn(kbuf, kout, shared_secret);
+       memset(kbuf, 0, klen);
+       xfree(kbuf);
+
+       if (datafellows & SSH_OLD_DHGEX)
+               min = max = -1;
+
+       /* calc and verify H */
+       hash = kexgex_hash(
+           kex->client_version_string,
+           kex->server_version_string,
+           buffer_ptr(&kex->my), buffer_len(&kex->my),
+           buffer_ptr(&kex->peer), buffer_len(&kex->peer),
+           server_host_key_blob, sbloblen,
+           min, nbits, max,
+           dh->p, dh->g,
+           dh->pub_key,
+           dh_server_pub,
+           shared_secret
+       );
+       /* have keys, free DH */
+       DH_free(dh);
+       xfree(server_host_key_blob);
+       BN_clear_free(dh_server_pub);
+
+       if (key_verify(server_host_key, signature, slen, hash, 20) != 1)
+               fatal("key_verify failed for server_host_key");
+       key_free(server_host_key);
+       xfree(signature);
+
+       /* save session id */
+       if (kex->session_id == NULL) {
+               kex->session_id_len = 20;
+               kex->session_id = xmalloc(kex->session_id_len);
+               memcpy(kex->session_id, hash, kex->session_id_len);
+       }
+       kex_derive_keys(kex, hash, shared_secret);
+       BN_clear_free(shared_secret);
+
+       kex_finish(kex);
+}
diff --git a/openssh/kexgexs.c b/openssh/kexgexs.c
new file mode 100644 (file)
index 0000000..baebfcf
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2000 Niels Provos.  All rights reserved.
+ * Copyright (c) 2001 Markus Friedl.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: kexgexs.c,v 1.1 2003/02/16 17:09:57 markus Exp $");
+
+#include "xmalloc.h"
+#include "key.h"
+#include "kex.h"
+#include "log.h"
+#include "packet.h"
+#include "dh.h"
+#include "ssh2.h"
+#include "compat.h"
+#include "monitor_wrap.h"
+
+void
+kexgex_server(Kex *kex)
+{
+       BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
+       Key *server_host_key;
+       DH *dh;
+       u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
+       u_int sbloblen, klen, kout, slen;
+       int min = -1, max = -1, nbits = -1, type;
+
+       if (kex->load_host_key == NULL)
+               fatal("Cannot load hostkey");
+       server_host_key = kex->load_host_key(kex->hostkey_type);
+       if (server_host_key == NULL)
+               fatal("Unsupported hostkey type %d", kex->hostkey_type);
+
+       type = packet_read();
+       switch (type) {
+       case SSH2_MSG_KEX_DH_GEX_REQUEST:
+               debug("SSH2_MSG_KEX_DH_GEX_REQUEST received");
+               min = packet_get_int();
+               nbits = packet_get_int();
+               max = packet_get_int();
+               min = MAX(DH_GRP_MIN, min);
+               max = MIN(DH_GRP_MAX, max);
+               break;
+       case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD:
+               debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received");
+               nbits = packet_get_int();
+               min = DH_GRP_MIN;
+               max = DH_GRP_MAX;
+               /* unused for old GEX */
+               break;
+       default:
+               fatal("protocol error during kex, no DH_GEX_REQUEST: %d", type);
+       }
+       packet_check_eom();
+
+       if (max < min || nbits < min || max < nbits)
+               fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d",
+                   min, nbits, max);
+
+       /* Contact privileged parent */
+       dh = PRIVSEP(choose_dh(min, nbits, max));
+       if (dh == NULL)
+               packet_disconnect("Protocol error: no matching DH grp found");
+
+       debug("SSH2_MSG_KEX_DH_GEX_GROUP sent");
+       packet_start(SSH2_MSG_KEX_DH_GEX_GROUP);
+       packet_put_bignum2(dh->p);
+       packet_put_bignum2(dh->g);
+       packet_send();
+
+       /* flush */
+       packet_write_wait();
+
+       /* Compute our exchange value in parallel with the client */
+       dh_gen_key(dh, kex->we_need * 8);
+
+       debug("expecting SSH2_MSG_KEX_DH_GEX_INIT");
+       packet_read_expect(SSH2_MSG_KEX_DH_GEX_INIT);
+
+       /* key, cert */
+       if ((dh_client_pub = BN_new()) == NULL)
+               fatal("dh_client_pub == NULL");
+       packet_get_bignum2(dh_client_pub);
+       packet_check_eom();
+
+#ifdef DEBUG_KEXDH
+       fprintf(stderr, "dh_client_pub= ");
+       BN_print_fp(stderr, dh_client_pub);
+       fprintf(stderr, "\n");
+       debug("bits %d", BN_num_bits(dh_client_pub));
+#endif
+
+#ifdef DEBUG_KEXDH
+       DHparams_print_fp(stderr, dh);
+       fprintf(stderr, "pub= ");
+       BN_print_fp(stderr, dh->pub_key);
+       fprintf(stderr, "\n");
+#endif
+       if (!dh_pub_is_valid(dh, dh_client_pub))
+               packet_disconnect("bad client public DH value");
+
+       klen = DH_size(dh);
+       kbuf = xmalloc(klen);
+       kout = DH_compute_key(kbuf, dh_client_pub, dh);
+#ifdef DEBUG_KEXDH
+       dump_digest("shared secret", kbuf, kout);
+#endif
+       if ((shared_secret = BN_new()) == NULL)
+               fatal("kexgex_server: BN_new failed");
+       BN_bin2bn(kbuf, kout, shared_secret);
+       memset(kbuf, 0, klen);
+       xfree(kbuf);
+
+       key_to_blob(server_host_key, &server_host_key_blob, &sbloblen);
+
+       if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD)
+               min = max = -1;
+
+       /* calc H */                    /* XXX depends on 'kex' */
+       hash = kexgex_hash(
+           kex->client_version_string,
+           kex->server_version_string,
+           buffer_ptr(&kex->peer), buffer_len(&kex->peer),
+           buffer_ptr(&kex->my), buffer_len(&kex->my),
+           server_host_key_blob, sbloblen,
+           min, nbits, max,
+           dh->p, dh->g,
+           dh_client_pub,
+           dh->pub_key,
+           shared_secret
+       );
+       BN_clear_free(dh_client_pub);
+
+       /* save session id := H */
+       /* XXX hashlen depends on KEX */
+       if (kex->session_id == NULL) {
+               kex->session_id_len = 20;
+               kex->session_id = xmalloc(kex->session_id_len);
+               memcpy(kex->session_id, hash, kex->session_id_len);
+       }
+
+       /* sign H */
+       /* XXX hashlen depends on KEX */
+       PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20));
+
+       /* destroy_sensitive_data(); */
+
+       /* send server hostkey, DH pubkey 'f' and singed H */
+       debug("SSH2_MSG_KEX_DH_GEX_REPLY sent");
+       packet_start(SSH2_MSG_KEX_DH_GEX_REPLY);
+       packet_put_string(server_host_key_blob, sbloblen);
+       packet_put_bignum2(dh->pub_key);        /* f */
+       packet_put_string(signature, slen);
+       packet_send();
+
+       xfree(signature);
+       xfree(server_host_key_blob);
+       /* have keys, free DH */
+       DH_free(dh);
+
+       kex_derive_keys(kex, hash, shared_secret);
+       BN_clear_free(shared_secret);
+
+       kex_finish(kex);
+}
diff --git a/openssh/openbsd-compat/basename.c b/openssh/openbsd-compat/basename.c
new file mode 100644 (file)
index 0000000..5a3823b
--- /dev/null
@@ -0,0 +1,73 @@
+/*     $OpenBSD: basename.c,v 1.8 2002/06/09 05:03:59 deraadt Exp $    */
+
+/*
+ * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "includes.h"
+
+#if !defined(HAVE_BASENAME)
+
+#ifndef lint
+static char rcsid[] = "$OpenBSD: basename.c,v 1.8 2002/06/09 05:03:59 deraadt Exp $";
+#endif /* not lint */
+
+char *
+basename(const char *path)
+{
+       static char bname[MAXPATHLEN];
+       register const char *endp, *startp;
+
+       /* Empty or NULL string gets treated as "." */
+       if (path == NULL || *path == '\0') {
+               (void)strlcpy(bname, ".", sizeof bname);
+               return(bname);
+       }
+
+       /* Strip trailing slashes */
+       endp = path + strlen(path) - 1;
+       while (endp > path && *endp == '/')
+               endp--;
+
+       /* All slashes become "/" */
+       if (endp == path && *endp == '/') {
+               (void)strlcpy(bname, "/", sizeof bname);
+               return(bname);
+       }
+
+       /* Find the start of the base */
+       startp = endp;
+       while (startp > path && *(startp - 1) != '/')
+               startp--;
+
+       if (endp - startp + 2 > sizeof(bname)) {
+               errno = ENAMETOOLONG;
+               return(NULL);
+       }
+       strlcpy(bname, startp, endp - startp + 2);
+       return(bname);
+}
+
+#endif /* !defined(HAVE_BASENAME) */
diff --git a/openssh/openbsd-compat/basename.h b/openssh/openbsd-compat/basename.h
new file mode 100644 (file)
index 0000000..4909933
--- /dev/null
@@ -0,0 +1,12 @@
+/* $Id$ */
+
+#ifndef _BASENAME_H 
+#define _BASENAME_H
+#include "config.h"
+
+#if !defined(HAVE_BASENAME)
+
+char *basename(const char *path);
+
+#endif /* !defined(HAVE_BASENAME) */
+#endif /* _BASENAME_H */
diff --git a/openssh/openbsd-compat/vis.c b/openssh/openbsd-compat/vis.c
new file mode 100644 (file)
index 0000000..fc57413
--- /dev/null
@@ -0,0 +1,232 @@
+/*-
+ * Copyright (c) 1989, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include "config.h"
+#if !defined(HAVE_STRNVIS)
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$OpenBSD: vis.c,v 1.8 2002/02/19 19:39:36 millert Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <ctype.h>
+
+#include "vis.h"
+
+#define        isoctal(c)      (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
+#define isvisible(c)   (((u_int)(c) <= UCHAR_MAX && isascii((u_char)(c)) && \
+                               isgraph((u_char)(c))) ||                     \
+                               ((flag & VIS_SP) == 0 && (c) == ' ') ||      \
+                               ((flag & VIS_TAB) == 0 && (c) == '\t') ||    \
+                               ((flag & VIS_NL) == 0 && (c) == '\n') ||     \
+                               ((flag & VIS_SAFE) &&                        \
+                               ((c) == '\b' || (c) == '\007' || (c) == '\r')))
+
+/*
+ * vis - visually encode characters
+ */
+char *
+vis(dst, c, flag, nextc)
+       register char *dst;
+       int c, nextc;
+       register int flag;
+{
+       if (isvisible(c)) {
+               *dst++ = c;
+               if (c == '\\' && (flag & VIS_NOSLASH) == 0)
+                       *dst++ = '\\';
+               *dst = '\0';
+               return (dst);
+       }
+
+       if (flag & VIS_CSTYLE) {
+               switch(c) {
+               case '\n':
+                       *dst++ = '\\';
+                       *dst++ = 'n';
+                       goto done;
+               case '\r':
+                       *dst++ = '\\';
+                       *dst++ = 'r';
+                       goto done;
+               case '\b':
+                       *dst++ = '\\';
+                       *dst++ = 'b';
+                       goto done;
+               case '\a':
+                       *dst++ = '\\';
+                       *dst++ = 'a';
+                       goto done;
+               case '\v':
+                       *dst++ = '\\';
+                       *dst++ = 'v';
+                       goto done;
+               case '\t':
+                       *dst++ = '\\';
+                       *dst++ = 't';
+                       goto done;
+               case '\f':
+                       *dst++ = '\\';
+                       *dst++ = 'f';
+                       goto done;
+               case ' ':
+                       *dst++ = '\\';
+                       *dst++ = 's';
+                       goto done;
+               case '\0':
+                       *dst++ = '\\';
+                       *dst++ = '0';
+                       if (isoctal(nextc)) {
+                               *dst++ = '0';
+                               *dst++ = '0';
+                       }
+                       goto done;
+               }
+       }
+       if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) {        
+               *dst++ = '\\';
+               *dst++ = ((u_char)c >> 6 & 07) + '0';
+               *dst++ = ((u_char)c >> 3 & 07) + '0';
+               *dst++ = ((u_char)c & 07) + '0';
+               goto done;
+       }
+       if ((flag & VIS_NOSLASH) == 0)
+               *dst++ = '\\';
+       if (c & 0200) {
+               c &= 0177;
+               *dst++ = 'M';
+       }
+       if (iscntrl(c)) {
+               *dst++ = '^';
+               if (c == 0177)
+                       *dst++ = '?';
+               else
+                       *dst++ = c + '@';
+       } else {
+               *dst++ = '-';
+               *dst++ = c;
+       }
+done:
+       *dst = '\0';
+       return (dst);
+}
+
+/*
+ * strvis, strnvis, strvisx - visually encode characters from src into dst
+ *     
+ *     Dst must be 4 times the size of src to account for possible
+ *     expansion.  The length of dst, not including the trailing NULL,
+ *     is returned. 
+ *
+ *     Strnvis will write no more than siz-1 bytes (and will NULL terminate).
+ *     The number of bytes needed to fully encode the string is returned.
+ *
+ *     Strvisx encodes exactly len bytes from src into dst.
+ *     This is useful for encoding a block of data.
+ */
+int
+strvis(dst, src, flag)
+       register char *dst;
+       register const char *src;
+       int flag;
+{
+       register char c;
+       char *start;
+
+       for (start = dst; (c = *src);)
+               dst = vis(dst, c, flag, *++src);
+       *dst = '\0';
+       return (dst - start);
+}
+
+int
+strnvis(dst, src, siz, flag)
+       register char *dst;
+       register const char *src;
+       size_t siz;
+       int flag;
+{
+       register char c;
+       char *start, *end;
+
+       for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) {
+               if (isvisible(c)) {
+                       *dst++ = c;
+                       if (c == '\\' && (flag & VIS_NOSLASH) == 0) {
+                               /* need space for the extra '\\' */
+                               if (dst < end)
+                                       *dst++ = '\\';
+                               else {
+                                       dst--;
+                                       break;
+                               }
+                       }
+                       src++;
+               } else {
+                       /* vis(3) requires up to 4 chars */
+                       if (dst + 3 < end)
+                               dst = vis(dst, c, flag, *++src);
+                       else
+                               break;
+               }
+       }
+       *dst = '\0';
+       if (dst >= end) {
+               char tbuf[5];
+
+               /* adjust return value for truncation */
+               while ((c = *src))
+                       dst += vis(tbuf, c, flag, *++src) - tbuf;
+       }
+       return (dst - start);
+}
+
+int
+strvisx(dst, src, len, flag)
+       register char *dst;
+       register const char *src;
+       register size_t len;
+       int flag;
+{
+       register char c;
+       char *start;
+
+       for (start = dst; len > 1; len--) {
+               c = *src;
+               dst = vis(dst, c, flag, *++src);
+       }
+       if (len)
+               dst = vis(dst, *src, flag, '\0');
+       *dst = '\0';
+       return (dst - start);
+}
+
+#endif
diff --git a/openssh/openbsd-compat/vis.h b/openssh/openbsd-compat/vis.h
new file mode 100644 (file)
index 0000000..5df6f36
--- /dev/null
@@ -0,0 +1,91 @@
+/*     $OpenBSD: vis.h,v 1.5 2002/02/16 21:27:17 millert Exp $ */
+/*     $NetBSD: vis.h,v 1.4 1994/10/26 00:56:41 cgd Exp $      */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)vis.h       5.9 (Berkeley) 4/3/91
+ */
+#include "config.h"
+#if !defined(HAVE_STRNVIS)
+
+#ifndef _VIS_H_
+#define        _VIS_H_
+
+#include <sys/types.h>
+#include <limits.h>
+
+/*
+ * to select alternate encoding format
+ */
+#define        VIS_OCTAL       0x01    /* use octal \ddd format */
+#define        VIS_CSTYLE      0x02    /* use \[nrft0..] where appropriate */
+
+/*
+ * to alter set of characters encoded (default is to encode all
+ * non-graphic except space, tab, and newline).
+ */
+#define        VIS_SP          0x04    /* also encode space */
+#define        VIS_TAB         0x08    /* also encode tab */
+#define        VIS_NL          0x10    /* also encode newline */
+#define        VIS_WHITE       (VIS_SP | VIS_TAB | VIS_NL)
+#define        VIS_SAFE        0x20    /* only encode "unsafe" characters */
+
+/*
+ * other
+ */
+#define        VIS_NOSLASH     0x40    /* inhibit printing '\' */
+
+/*
+ * unvis return codes
+ */
+#define        UNVIS_VALID      1      /* character valid */
+#define        UNVIS_VALIDPUSH  2      /* character valid, push back passed char */
+#define        UNVIS_NOCHAR     3      /* valid sequence, no character produced */
+#define        UNVIS_SYNBAD    -1      /* unrecognized escape sequence */
+#define        UNVIS_ERROR     -2      /* decoder in unknown state (unrecoverable) */
+
+/*
+ * unvis flags
+ */
+#define        UNVIS_END       1       /* no more characters */
+
+char   *vis(char *, int, int, int);
+int    strvis(char *, const char *, int);
+int    strnvis(char *, const char *, size_t, int);
+int    strvisx(char *, const char *, size_t, int);
+int    strunvis(char *, const char *);
+int    unvis(char *, char, int *, int);
+
+#endif /* !_VIS_H_ */
+
+#endif /* !HAVE_STRNVIS */
diff --git a/openssh/progressmeter.c b/openssh/progressmeter.c
new file mode 100644 (file)
index 0000000..90eb97f
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 1999 Theo de Raadt.  All rights reserved.
+ * Copyright (c) 1999 Aaron Campbell.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Parts from:
+ *
+ * Copyright (c) 1983, 1990, 1992, 1993, 1995
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: progressmeter.c,v 1.3 2003/03/17 10:38:38 markus Exp $");
+
+#ifdef HAVE_LIBGEN_H
+#include <libgen.h>
+#endif
+
+#include "atomicio.h"
+#include "progressmeter.h"
+
+/* Number of seconds before xfer considered "stalled". */
+#define STALLTIME      5
+/* alarm() interval for updating progress meter. */
+#define PROGRESSTIME   1
+
+/* Signal handler used for updating the progress meter. */
+static void update_progress_meter(int);
+
+/* Returns non-zero if we are the foreground process. */
+static int foregroundproc(void);
+
+/* Returns width of the terminal (for progress meter calculations). */
+static int get_tty_width(void);
+
+/* Visual statistics about files as they are transferred. */
+static void draw_progress_meter(void);
+
+/* Time a transfer started. */
+static struct timeval start;
+
+/* Number of bytes of current file transferred so far. */
+static volatile off_t *statbytes;
+
+/* Total size of current file. */
+static off_t totalbytes;
+
+/* Name of current file being transferred. */
+static char *curfile;
+
+/* Time of last update. */
+static struct timeval lastupdate;
+
+/* Size at the time of the last update. */
+static off_t lastsize;
+
+void
+start_progress_meter(char *file, off_t filesize, off_t *counter)
+{
+       if ((curfile = basename(file)) == NULL)
+               curfile = file;
+
+       totalbytes = filesize;
+       statbytes = counter;
+       (void) gettimeofday(&start, (struct timezone *) 0);
+       lastupdate = start;
+       lastsize = 0;
+
+       draw_progress_meter();
+       signal(SIGALRM, update_progress_meter);
+       alarm(PROGRESSTIME);
+}
+
+void
+stop_progress_meter()
+{
+       alarm(0);
+       draw_progress_meter();
+       if (foregroundproc() != 0)
+               atomicio(write, fileno(stdout), "\n", 1);
+}
+
+static void
+update_progress_meter(int ignore)
+{
+       int save_errno = errno;
+
+       draw_progress_meter();
+       signal(SIGALRM, update_progress_meter);
+       alarm(PROGRESSTIME);
+       errno = save_errno;
+}
+
+static int
+foregroundproc(void)
+{
+       static pid_t pgrp = -1;
+       int ctty_pgrp;
+
+       if (pgrp == -1)
+               pgrp = getpgrp();
+
+#ifdef HAVE_TCGETPGRP
+        return ((ctty_pgrp = tcgetpgrp(STDOUT_FILENO)) != -1 &&
+                       ctty_pgrp == pgrp);
+#else
+       return ((ioctl(STDOUT_FILENO, TIOCGPGRP, &ctty_pgrp) != -1 &&
+                ctty_pgrp == pgrp));
+#endif
+}
+
+static void
+draw_progress_meter()
+{
+       static const char spaces[] = "                          "
+           "                                                   "
+           "                                                   "
+           "                                                   "
+           "                                                   "
+           "                                                   ";
+       static const char prefixes[] = " KMGTP";
+       struct timeval now, td, wait;
+       off_t cursize, abbrevsize, bytespersec;
+       double elapsed;
+       int ratio, remaining, i, ai, bi, nspaces;
+       char buf[512];
+
+       if (foregroundproc() == 0)
+               return;
+
+       (void) gettimeofday(&now, (struct timezone *) 0);
+       cursize = *statbytes;
+       if (totalbytes != 0) {
+               ratio = 100.0 * cursize / totalbytes;
+               ratio = MAX(ratio, 0);
+               ratio = MIN(ratio, 100);
+       } else
+               ratio = 100;
+
+       abbrevsize = cursize;
+       for (ai = 0; abbrevsize >= 10000 && ai < sizeof(prefixes); ai++)
+               abbrevsize >>= 10;
+
+       timersub(&now, &lastupdate, &wait);
+       if (cursize > lastsize) {
+               lastupdate = now;
+               lastsize = cursize;
+               wait.tv_sec = 0;
+       }
+       timersub(&now, &start, &td);
+       elapsed = td.tv_sec + (td.tv_usec / 1000000.0);
+
+       bytespersec = 0;
+       if (cursize > 0) {
+               bytespersec = cursize;
+               if (elapsed > 0.0)
+                       bytespersec /= elapsed;
+       }
+       for (bi = 1; bytespersec >= 1024000 && bi < sizeof(prefixes); bi++)
+               bytespersec >>= 10;
+
+       nspaces = MIN(get_tty_width() - 79, sizeof(spaces) - 1);
+
+#ifdef HAVE_LONG_LONG_INT
+       snprintf(buf, sizeof(buf),
+           "\r%-45.45s%.*s%3d%% %4lld%c%c %3lld.%01d%cB/s",
+           curfile,
+           nspaces,
+           spaces,
+           ratio,
+           (long long)abbrevsize,
+           prefixes[ai],
+           ai == 0 ? ' ' : 'B',
+           (long long)(bytespersec / 1024),
+           (int)((bytespersec % 1024) * 10 / 1024),
+           prefixes[bi]
+       );
+#else
+               /* XXX: Handle integer overflow? */
+       snprintf(buf, sizeof(buf),
+           "\r%-45.45s%.*s%3d%% %4lu%c%c %3lu.%01d%cB/s",
+           curfile,
+           nspaces,
+           spaces,
+           ratio,
+           (u_long)abbrevsize,
+           prefixes[ai],
+           ai == 0 ? ' ' : 'B',
+           (u_long)(bytespersec / 1024),
+           (int)((bytespersec % 1024) * 10 / 1024),
+           prefixes[bi]
+       );
+#endif
+
+       if (cursize <= 0 || elapsed <= 0.0 || cursize > totalbytes) {
+               snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+                   "   --:-- ETA");
+       } else if (wait.tv_sec >= STALLTIME) {
+               snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+                   " - stalled -");
+       } else {
+               if (cursize != totalbytes)
+                       remaining = (int)(totalbytes / (cursize / elapsed) -
+                           elapsed);
+               else
+                       remaining = elapsed;
+
+               i = remaining / 3600;
+               if (i)
+                       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+                           "%2d:", i);
+               else
+                       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+                           "   ");
+               i = remaining % 3600;
+               snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+                   "%02d:%02d%s", i / 60, i % 60,
+                   (cursize != totalbytes) ? " ETA" : "    ");
+       }
+       atomicio(write, fileno(stdout), buf, strlen(buf));
+}
+
+static int
+get_tty_width(void)
+{
+       struct winsize winsize;
+
+       if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) != -1)
+               return (winsize.ws_col ? winsize.ws_col : 80);
+       else
+               return (80);
+}
diff --git a/openssh/progressmeter.h b/openssh/progressmeter.h
new file mode 100644 (file)
index 0000000..bfb9a0b
--- /dev/null
@@ -0,0 +1,27 @@
+/*     $OpenBSD: progressmeter.h,v 1.1 2003/01/10 08:19:07 fgsch Exp $ */
+/*
+ * Copyright (c) 2002 Nils Nordman.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+void   start_progress_meter(char *, off_t, off_t *);
+void   stop_progress_meter(void);
diff --git a/openssh/regress/agent-getpeereid.sh b/openssh/regress/agent-getpeereid.sh
new file mode 100644 (file)
index 0000000..0889fe8
--- /dev/null
@@ -0,0 +1,34 @@
+#      $OpenBSD: agent-getpeereid.sh,v 1.1 2002/12/09 16:05:02 markus Exp $
+#      Placed in the Public Domain.
+
+tid="disallow agent attach from other uid"
+
+UNPRIV=nobody
+ASOCK=${OBJ}/agent
+SSH_AUTH_SOCK=/nonexistant
+
+trace "start agent"
+eval `${SSHAGENT} -s -a ${ASOCK}` > /dev/null
+r=$?
+if [ $r -ne 0 ]; then
+       fail "could not start ssh-agent: exit code $r"
+else
+       chmod 644 ${SSH_AUTH_SOCK}
+
+       ssh-add -l > /dev/null 2>&1
+       r=$?
+       if [ $r -ne 1 ]; then
+               fail "ssh-add failed with $r != 1"
+       fi
+
+       < /dev/null sudo -S -u ${UNPRIV} ssh-add -l > /dev/null 2>&1
+       r=$?
+       if [ $r -lt 2 ]; then
+               fail "ssh-add did not fail for ${UNPRIV}: $r < 2"
+       fi
+
+       trace "kill agent"
+       ${SSHAGENT} -k > /dev/null
+fi
+
+rm -f ${OBJ}/agent
diff --git a/openssh/regress/agent-ptrace.sh b/openssh/regress/agent-ptrace.sh
new file mode 100644 (file)
index 0000000..9f9c999
--- /dev/null
@@ -0,0 +1,28 @@
+#      $OpenBSD: agent-ptrace.sh,v 1.1 2002/12/09 15:38:30 markus Exp $
+#      Placed in the Public Domain.
+
+tid="disallow agent ptrace attach"
+
+trace "start agent"
+eval `${SSHAGENT} -s` > /dev/null
+r=$?
+if [ $r -ne 0 ]; then
+       fail "could not start ssh-agent: exit code $r"
+else
+       # ls -l ${SSH_AUTH_SOCK}
+       gdb ${SSHAGENT} ${SSH_AGENT_PID} > ${OBJ}/gdb.out 2>&1 << EOF
+               quit
+EOF
+       if [ $? -ne 0 ]; then
+               fail "gdb failed: exit code $?"
+       fi
+       grep -q 'ptrace: Operation not permitted.' ${OBJ}/gdb.out
+       r=$?
+       rm -f ${OBJ}/gdb.out
+       if [ $r -ne 0 ]; then
+               fail "ptrace succeeded?: exit code $r"
+       fi
+
+       trace "kill agent"
+       ${SSHAGENT} -k > /dev/null
+fi
diff --git a/openssh/regress/agent-timeout.sh b/openssh/regress/agent-timeout.sh
new file mode 100644 (file)
index 0000000..28b1be0
--- /dev/null
@@ -0,0 +1,36 @@
+#      $OpenBSD: agent-timeout.sh,v 1.1 2002/06/06 00:38:40 markus Exp $
+#      Placed in the Public Domain.
+
+tid="agent timeout test"
+
+TIMEOUT=5
+
+trace "start agent"
+eval `${SSHAGENT} -s` > /dev/null
+r=$?
+if [ $r -ne 0 ]; then
+       fail "could not start ssh-agent: exit code $r"
+else
+       trace "add keys with timeout"
+       for t in rsa rsa1; do
+               ${SSHADD} -t ${TIMEOUT} $OBJ/$t > /dev/null 2>&1
+               if [ $? -ne 0 ]; then
+                       fail "ssh-add did succeed exit code 0"
+               fi
+       done
+       n=`${SSHADD} -l 2> /dev/null | wc -l`
+       trace "agent has $n keys"
+       if [ $n -ne 2 ]; then
+               fail "ssh-add -l did not return 2 keys: $n"
+       fi
+       trace "sleeping 2*${TIMEOUT} seconds"
+       sleep ${TIMEOUT}
+       sleep ${TIMEOUT}
+       ${SSHADD} -l 2> /dev/null | grep -q 'The agent has no identities.'
+       if [ $? -ne 0 ]; then
+               fail "ssh-add -l still returns keys after timeout"
+       fi
+
+       trace "kill agent"
+       ${SSHAGENT} -k > /dev/null
+fi
diff --git a/openssh/regress/keygen-change.sh b/openssh/regress/keygen-change.sh
new file mode 100644 (file)
index 0000000..08d3590
--- /dev/null
@@ -0,0 +1,23 @@
+#      $OpenBSD: keygen-change.sh,v 1.2 2002/07/16 09:15:55 markus Exp $
+#      Placed in the Public Domain.
+
+tid="change passphrase for key"
+
+S1="secret1"
+S2="2secret"
+
+for t in rsa dsa rsa1; do
+       # generate user key for agent
+       trace "generating $t key"
+       rm -f $OBJ/$t-key
+       ${SSHKEYGEN} -q -N ${S1} -t $t -f $OBJ/$t-key
+       if [ $? -eq 0 ]; then
+               ${SSHKEYGEN} -p -P ${S1} -N ${S2} -f $OBJ/$t-key > /dev/null
+               if [ $? -ne 0 ]; then
+                       fail "ssh-keygen -p failed for $t-key"
+               fi
+       else
+               fail "ssh-keygen for $t-key failed"
+       fi
+       rm -f $OBJ/$t-key $OBJ/$t-key.pub
+done
diff --git a/openssh/regress/sftp-batch.sh b/openssh/regress/sftp-batch.sh
new file mode 100644 (file)
index 0000000..cffacb6
--- /dev/null
@@ -0,0 +1,57 @@
+#      $OpenBSD: sftp-batch.sh,v 1.2 2003/01/10 07:52:41 djm Exp $
+#      Placed in the Public Domain.
+
+tid="sftp batchfile"
+
+DATA=/bin/ls
+COPY=${OBJ}/copy
+BATCH=${OBJ}/sftp-batch
+
+rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${BATCH}.*
+
+cat << EOF > ${BATCH}.pass.1
+       get $DATA $COPY
+       put ${COPY} ${COPY}.1
+       rm ${COPY}
+       -put ${COPY} ${COPY}.2
+EOF
+
+cat << EOF > ${BATCH}.pass.2
+       # This is a comment
+
+       # That was a blank line
+       ls
+EOF
+
+cat << EOF > ${BATCH}.fail.1
+       get $DATA $COPY
+       put ${COPY} ${COPY}.3
+       rm ${COPY}.*
+       # The next command should fail
+       put ${COPY}.3 ${COPY}.4
+EOF
+
+cat << EOF > ${BATCH}.fail.2
+       # The next command should fail
+       jajajajaja
+EOF
+
+verbose "$tid: good commands"
+${SFTP} -b ${BATCH}.pass.1 -P ${SFTPSERVER} >/dev/null 2>&1 \
+       || fail "good commands failed"
+
+verbose "$tid: bad commands"
+${SFTP} -b ${BATCH}.fail.1 -P ${SFTPSERVER} >/dev/null 2>&1 \
+       && fail "bad commands succeeded"
+
+verbose "$tid: comments and blanks"
+${SFTP} -b ${BATCH}.pass.2 -P ${SFTPSERVER} >/dev/null 2>&1 \
+       || fail "comments & blanks failed"
+
+verbose "$tid: junk command"
+${SFTP} -b ${BATCH}.fail.2 -P ${SFTPSERVER} >/dev/null 2>&1 \
+       && fail "junk command succeeded"
+
+rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${BATCH}.*
+
+
diff --git a/openssh/regress/sftp-cmds.sh b/openssh/regress/sftp-cmds.sh
new file mode 100644 (file)
index 0000000..462c680
--- /dev/null
@@ -0,0 +1,100 @@
+#      $OpenBSD: sftp-cmds.sh,v 1.2 2003/01/10 07:52:41 djm Exp $
+#      Placed in the Public Domain.
+
+# XXX - TODO: 
+# - globbed operations
+# - chmod / chown / chgrp
+# - -p flag for get & put
+
+tid="sftp commands"
+
+DATA=/bin/ls
+COPY=${OBJ}/copy
+
+rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${BATCH}.*
+
+verbose "$tid: lls"
+echo "lls ${OBJ}" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
+       || fail "lls failed"
+# XXX always successful
+
+verbose "$tid: ls"
+echo "ls ${OBJ}" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
+       || fail "ls failed"
+# XXX always successful
+
+verbose "$tid: shell"
+echo "!echo hi there" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
+       || fail "shell failed"
+# XXX always successful
+
+verbose "$tid: pwd"
+echo "pwd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
+       || fail "pwd failed"
+# XXX always successful
+
+verbose "$tid: lpwd"
+echo "lpwd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
+       || fail "lpwd failed"
+# XXX always successful
+
+verbose "$tid: quit"
+echo "quit" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
+       || fail "quit failed"
+# XXX always successful
+
+verbose "$tid: help"
+echo "help" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
+       || fail "help failed"
+# XXX always successful
+
+rm -f ${COPY}
+verbose "$tid: get"
+echo "get $DATA $COPY" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
+       || fail "get failed"
+cmp $DATA ${COPY} || fail "corrupted copy after get"
+
+rm -f ${COPY}
+verbose "$tid: put"
+echo "put $DATA $COPY" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
+       || fail "put failed"
+cmp $DATA ${COPY} || fail "corrupted copy after put"
+
+verbose "$tid: rename"
+echo "rename $COPY ${COPY}.1" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
+       || fail "rename failed"
+test -f ${COPY}.1 || fail "missing file after rename"
+cmp $DATA ${COPY}.1 >/dev/null 2>&1 || fail "corrupted copy after rename"
+
+verbose "$tid: ln"
+echo "ln ${COPY}.1 ${COPY}.2" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 || fail "ln failed"
+test -L ${COPY}.2 || fail "missing file after ln"
+
+verbose "$tid: mkdir"
+echo "mkdir ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
+       || fail "mkdir failed"
+test -d ${COPY}.dd || fail "missing directory after mkdir"
+
+# XXX do more here
+verbose "$tid: chdir"
+echo "chdir ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
+       || fail "chdir failed"
+
+verbose "$tid: rmdir"
+echo "rmdir ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
+       || fail "rmdir failed"
+test -d ${COPY}.1 && fail "present directory after rmdir"
+
+verbose "$tid: lmkdir"
+echo "lmkdir ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
+       || fail "lmkdir failed"
+test -d ${COPY}.dd || fail "missing directory after lmkdir"
+
+# XXX do more here
+verbose "$tid: lchdir"
+echo "lchdir ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
+       || fail "lchdir failed"
+
+rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${BATCH}.*
+
+
This page took 0.151289 seconds and 5 git commands to generate.