From 9e1f6eaec731eaf00a64257101e3b6fd6cc84bd0 Mon Sep 17 00:00:00 2001 From: "James T. Sprinkle" Date: Sun, 1 Oct 2017 16:50:39 -0700 Subject: [PATCH] New files for previous update. --- crypto/external/bsd/openssh/dist/CREDITS | 105 + crypto/external/bsd/openssh/dist/ChangeLog | 9133 +++++++++++++++++ crypto/external/bsd/openssh/dist/INSTALL | 262 + crypto/external/bsd/openssh/dist/README.dns | 47 + .../external/bsd/openssh/dist/README.platform | 96 + .../external/bsd/openssh/dist/README.privsep | 63 + crypto/external/bsd/openssh/dist/README.tun | 132 + crypto/external/bsd/openssh/dist/TODO | 86 + crypto/external/bsd/openssh/dist/audit-bsm.c | 457 + .../external/bsd/openssh/dist/audit-linux.c | 126 + crypto/external/bsd/openssh/dist/audit.c | 186 + crypto/external/bsd/openssh/dist/audit.h | 57 + .../external/bsd/openssh/dist/auth-shadow.c | 142 + crypto/external/bsd/openssh/dist/auth-sia.c | 114 + crypto/external/bsd/openssh/dist/auth-sia.h | 31 + .../external/bsd/openssh/dist/bindresvport.c | 1 + crypto/external/bsd/openssh/dist/bsd-misc.c | 1 + .../external/bsd/openssh/dist/bsd-setres_id.c | 1 + crypto/external/bsd/openssh/dist/cipher-aes.c | 161 + crypto/external/bsd/openssh/dist/cipher-ctr.c | 146 + crypto/external/bsd/openssh/dist/config.h | 1708 +++ .../bsd/openssh/dist/contrib/Makefile | 17 + .../external/bsd/openssh/dist/contrib/README | 70 + .../bsd/openssh/dist/contrib/aix/README | 50 + .../bsd/openssh/dist/contrib/aix/buildbff.sh | 381 + .../bsd/openssh/dist/contrib/aix/inventory.sh | 63 + .../bsd/openssh/dist/contrib/aix/pam.conf | 20 + .../bsd/openssh/dist/contrib/cygwin/Makefile | 77 + .../bsd/openssh/dist/contrib/cygwin/README | 90 + .../dist/contrib/cygwin/ssh-host-config | 718 ++ .../dist/contrib/cygwin/ssh-user-config | 257 + .../openssh/dist/contrib/cygwin/sshd-inetd | 4 + .../bsd/openssh/dist/contrib/findssl.sh | 186 + .../openssh/dist/contrib/gnome-ssh-askpass1.c | 171 + .../openssh/dist/contrib/gnome-ssh-askpass2.c | 223 + .../bsd/openssh/dist/contrib/hpux/README | 45 + .../bsd/openssh/dist/contrib/hpux/egd | 15 + .../bsd/openssh/dist/contrib/hpux/egd.rc | 98 + .../bsd/openssh/dist/contrib/hpux/sshd | 5 + .../bsd/openssh/dist/contrib/hpux/sshd.rc | 90 + .../dist/contrib/redhat/gnome-ssh-askpass.csh | 1 + .../dist/contrib/redhat/gnome-ssh-askpass.sh | 2 + .../openssh/dist/contrib/redhat/openssh.spec | 811 ++ .../bsd/openssh/dist/contrib/redhat/sshd.init | 106 + .../openssh/dist/contrib/redhat/sshd.init.old | 172 + .../bsd/openssh/dist/contrib/redhat/sshd.pam | 6 + .../openssh/dist/contrib/redhat/sshd.pam.old | 8 + .../bsd/openssh/dist/contrib/solaris/README | 30 + .../bsd/openssh/dist/contrib/ssh-copy-id | 300 + .../bsd/openssh/dist/contrib/ssh-copy-id.1 | 186 + .../bsd/openssh/dist/contrib/sshd.pam.freebsd | 5 + .../bsd/openssh/dist/contrib/sshd.pam.generic | 8 + .../openssh/dist/contrib/suse/openssh.spec | 243 + .../openssh/dist/contrib/suse/rc.config.sshd | 5 + .../bsd/openssh/dist/contrib/suse/rc.sshd | 121 + .../openssh/dist/contrib/suse/sysconfig.ssh | 9 + crypto/external/bsd/openssh/dist/defines.h | 853 ++ crypto/external/bsd/openssh/dist/entropy.c | 244 + crypto/external/bsd/openssh/dist/entropy.h | 37 + .../bsd/openssh/dist/explicit_bzero.c | 1 + crypto/external/bsd/openssh/dist/loginrec.c | 1726 ++++ crypto/external/bsd/openssh/dist/loginrec.h | 131 + crypto/external/bsd/openssh/dist/logintest.c | 308 + crypto/external/bsd/openssh/dist/md5crypt.c | 167 + crypto/external/bsd/openssh/dist/md5crypt.h | 24 + crypto/external/bsd/openssh/dist/moduli.0 | 74 + .../openssh/dist/openbsd-compat/.cvsignore | 1 + .../bsd/openssh/dist/openbsd-compat/Makefile | 42 + .../openssh/dist/openbsd-compat/Makefile.in | 42 + .../openssh/dist/openbsd-compat/arc4random.c | 328 + .../bsd/openssh/dist/openbsd-compat/base64.c | 315 + .../bsd/openssh/dist/openbsd-compat/base64.h | 65 + .../openssh/dist/openbsd-compat/basename.c | 67 + .../dist/openbsd-compat/bcrypt_pbkdf.c | 179 + .../dist/openbsd-compat/bindresvport.c | 118 + .../bsd/openssh/dist/openbsd-compat/blf.h | 88 + .../openssh/dist/openbsd-compat/blowfish.c | 696 ++ .../dist/openbsd-compat/bsd-asprintf.c | 101 + .../dist/openbsd-compat/bsd-closefrom.c | 109 + .../openssh/dist/openbsd-compat/bsd-cray.c | 817 ++ .../openssh/dist/openbsd-compat/bsd-cray.h | 61 + .../dist/openbsd-compat/bsd-cygwin_util.c | 119 + .../dist/openbsd-compat/bsd-cygwin_util.h | 67 + .../dist/openbsd-compat/bsd-getpeereid.c | 73 + .../openssh/dist/openbsd-compat/bsd-misc.c | 278 + .../openssh/dist/openbsd-compat/bsd-misc.h | 125 + .../dist/openbsd-compat/bsd-nextstep.c | 103 + .../dist/openbsd-compat/bsd-nextstep.h | 59 + .../openssh/dist/openbsd-compat/bsd-openpty.c | 220 + .../openssh/dist/openbsd-compat/bsd-poll.c | 119 + .../openssh/dist/openbsd-compat/bsd-poll.h | 61 + .../dist/openbsd-compat/bsd-setres_id.c | 100 + .../dist/openbsd-compat/bsd-setres_id.h | 24 + .../dist/openbsd-compat/bsd-snprintf.c | 892 ++ .../openssh/dist/openbsd-compat/bsd-statvfs.c | 82 + .../openssh/dist/openbsd-compat/bsd-statvfs.h | 71 + .../openssh/dist/openbsd-compat/bsd-waitpid.c | 53 + .../openssh/dist/openbsd-compat/bsd-waitpid.h | 51 + .../dist/openbsd-compat/chacha_private.h | 222 + .../openssh/dist/openbsd-compat/charclass.h | 31 + .../bsd/openssh/dist/openbsd-compat/daemon.c | 82 + .../bsd/openssh/dist/openbsd-compat/dirname.c | 72 + .../dist/openbsd-compat/explicit_bzero.c | 40 + .../dist/openbsd-compat/fake-rfc2553.c | 235 + .../dist/openbsd-compat/fake-rfc2553.h | 178 + .../openssh/dist/openbsd-compat/fmt_scaled.c | 274 + .../bsd/openssh/dist/openbsd-compat/getcwd.c | 240 + .../dist/openbsd-compat/getgrouplist.c | 95 + .../bsd/openssh/dist/openbsd-compat/getopt.h | 74 + .../openssh/dist/openbsd-compat/getopt_long.c | 532 + .../dist/openbsd-compat/getrrsetbyname-ldns.c | 284 + .../dist/openbsd-compat/getrrsetbyname.c | 610 ++ .../dist/openbsd-compat/getrrsetbyname.h | 110 + .../bsd/openssh/dist/openbsd-compat/glob.c | 1065 ++ .../bsd/openssh/dist/openbsd-compat/glob.h | 103 + .../openssh/dist/openbsd-compat/inet_aton.c | 179 + .../openssh/dist/openbsd-compat/inet_ntoa.c | 59 + .../openssh/dist/openbsd-compat/inet_ntop.c | 211 + .../dist/openbsd-compat/kludge-fd_set.c | 28 + .../bsd/openssh/dist/openbsd-compat/md5.c | 251 + .../bsd/openssh/dist/openbsd-compat/md5.h | 51 + .../bsd/openssh/dist/openbsd-compat/mktemp.c | 141 + .../dist/openbsd-compat/openbsd-compat.h | 302 + .../dist/openbsd-compat/openssl-compat.c | 84 + .../dist/openbsd-compat/openssl-compat.h | 96 + .../openssh/dist/openbsd-compat/port-aix.c | 472 + .../openssh/dist/openbsd-compat/port-aix.h | 127 + .../openssh/dist/openbsd-compat/port-irix.c | 90 + .../openssh/dist/openbsd-compat/port-irix.h | 39 + .../openssh/dist/openbsd-compat/port-linux.c | 311 + .../openssh/dist/openbsd-compat/port-linux.h | 35 + .../dist/openbsd-compat/port-solaris.c | 229 + .../dist/openbsd-compat/port-solaris.h | 30 + .../openssh/dist/openbsd-compat/port-tun.c | 282 + .../openssh/dist/openbsd-compat/port-tun.h | 33 + .../bsd/openssh/dist/openbsd-compat/port-uw.c | 150 + .../bsd/openssh/dist/openbsd-compat/port-uw.h | 30 + .../bsd/openssh/dist/openbsd-compat/pwcache.c | 114 + .../dist/openbsd-compat/readpassphrase.c | 213 + .../dist/openbsd-compat/readpassphrase.h | 44 + .../dist/openbsd-compat/reallocarray.c | 46 + .../openssh/dist/openbsd-compat/realpath.c | 200 + .../dist/openbsd-compat/regress/.cvsignore | 6 + .../dist/openbsd-compat/regress/Makefile | 38 + .../dist/openbsd-compat/regress/Makefile.in | 38 + .../openbsd-compat/regress/closefromtest.c | 63 + .../openbsd-compat/regress/opensslvertest.c | 69 + .../openbsd-compat/regress/snprintftest.c | 73 + .../dist/openbsd-compat/regress/strduptest.c | 45 + .../openbsd-compat/regress/strtonumtest.c | 80 + .../bsd/openssh/dist/openbsd-compat/rmd160.c | 378 + .../bsd/openssh/dist/openbsd-compat/rmd160.h | 61 + .../openssh/dist/openbsd-compat/rresvport.c | 108 + .../bsd/openssh/dist/openbsd-compat/setenv.c | 226 + .../dist/openbsd-compat/setproctitle.c | 169 + .../bsd/openssh/dist/openbsd-compat/sha1.c | 177 + .../bsd/openssh/dist/openbsd-compat/sha1.h | 58 + .../bsd/openssh/dist/openbsd-compat/sha2.c | 904 ++ .../bsd/openssh/dist/openbsd-compat/sha2.h | 134 + .../bsd/openssh/dist/openbsd-compat/sigact.c | 132 + .../bsd/openssh/dist/openbsd-compat/sigact.h | 90 + .../bsd/openssh/dist/openbsd-compat/strlcat.c | 62 + .../bsd/openssh/dist/openbsd-compat/strlcpy.c | 58 + .../bsd/openssh/dist/openbsd-compat/strmode.c | 148 + .../bsd/openssh/dist/openbsd-compat/strnlen.c | 37 + .../openssh/dist/openbsd-compat/strptime.c | 401 + .../bsd/openssh/dist/openbsd-compat/strsep.c | 79 + .../bsd/openssh/dist/openbsd-compat/strtoll.c | 148 + .../openssh/dist/openbsd-compat/strtonum.c | 72 + .../bsd/openssh/dist/openbsd-compat/strtoul.c | 108 + .../openssh/dist/openbsd-compat/strtoull.c | 110 + .../openssh/dist/openbsd-compat/sys-queue.h | 653 ++ .../openssh/dist/openbsd-compat/sys-tree.h | 755 ++ .../dist/openbsd-compat/timingsafe_bcmp.c | 34 + .../bsd/openssh/dist/openbsd-compat/vis.c | 225 + .../bsd/openssh/dist/openbsd-compat/vis.h | 95 + .../bsd/openssh/dist/openbsd-compat/xcrypt.c | 122 + .../bsd/openssh/dist/openbsd-compat/xmmap.c | 88 + crypto/external/bsd/openssh/dist/openssh.xml | 90 + .../external/bsd/openssh/dist/opensshd.init | 92 + .../bsd/openssh/dist/openssl-compat.c | 1 + .../bsd/openssh/dist/openssl-compat.h | 1 + crypto/external/bsd/openssh/dist/platform.c | 215 + crypto/external/bsd/openssh/dist/platform.h | 33 + .../external/bsd/openssh/dist/reallocarray.c | 1 + crypto/external/bsd/openssh/dist/realpath.c | 1 + .../bsd/openssh/dist/regress/.cvsignore | 31 + .../bsd/openssh/dist/regress/Makefile | 221 + .../bsd/openssh/dist/regress/README.regress | 104 + .../bsd/openssh/dist/regress/addrmatch.sh | 56 + .../openssh/dist/regress/agent-getpeereid.sh | 45 + .../bsd/openssh/dist/regress/agent-pkcs11.sh | 71 + .../bsd/openssh/dist/regress/agent-ptrace.sh | 61 + .../bsd/openssh/dist/regress/agent-timeout.sh | 36 + .../bsd/openssh/dist/regress/agent.sh | 81 + .../bsd/openssh/dist/regress/banner.sh | 44 + .../bsd/openssh/dist/regress/broken-pipe.sh | 15 + .../bsd/openssh/dist/regress/brokenkeys.sh | 23 + .../bsd/openssh/dist/regress/cert-hostkey.sh | 302 + .../bsd/openssh/dist/regress/cert-userkey.sh | 362 + .../bsd/openssh/dist/regress/cfgmatch.sh | 127 + .../bsd/openssh/dist/regress/cfgparse.sh | 75 + .../bsd/openssh/dist/regress/cipher-speed.sh | 51 + .../bsd/openssh/dist/regress/conch-ciphers.sh | 28 + .../openssh/dist/regress/connect-privsep.sh | 36 + .../bsd/openssh/dist/regress/connect.sh | 13 + .../bsd/openssh/dist/regress/core.13225 | Bin 0 -> 2372468 bytes .../bsd/openssh/dist/regress/dhgex.sh | 58 + .../bsd/openssh/dist/regress/dsa_ssh2.prv | 14 + .../bsd/openssh/dist/regress/dsa_ssh2.pub | 13 + .../openssh/dist/regress/dynamic-forward.sh | 59 + .../bsd/openssh/dist/regress/envpass.sh | 60 + .../bsd/openssh/dist/regress/exit-status.sh | 24 + .../bsd/openssh/dist/regress/forcecommand.sh | 44 + .../openssh/dist/regress/forward-control.sh | 168 + .../bsd/openssh/dist/regress/forwarding.sh | 143 + .../bsd/openssh/dist/regress/host-expand.sh | 19 + .../bsd/openssh/dist/regress/hostkey-agent.sh | 53 + .../openssh/dist/regress/hostkey-rotate.sh | 128 + .../bsd/openssh/dist/regress/integrity.sh | 75 + .../bsd/openssh/dist/regress/kextype.sh | 25 + .../bsd/openssh/dist/regress/key-options.sh | 71 + .../bsd/openssh/dist/regress/keygen-change.sh | 28 + .../openssh/dist/regress/keygen-convert.sh | 33 + .../openssh/dist/regress/keygen-knownhosts.sh | 197 + .../bsd/openssh/dist/regress/keys-command.sh | 76 + .../bsd/openssh/dist/regress/keyscan.sh | 24 + .../bsd/openssh/dist/regress/keytype.sh | 73 + .../external/bsd/openssh/dist/regress/krl.sh | 185 + .../bsd/openssh/dist/regress/limit-keytype.sh | 80 + .../bsd/openssh/dist/regress/localcommand.sh | 15 + .../bsd/openssh/dist/regress/login-timeout.sh | 32 + .../bsd/openssh/dist/regress/modpipe.c | 175 + .../bsd/openssh/dist/regress/multiplex.sh | 190 + .../bsd/openssh/dist/regress/multipubkey.sh | 66 + .../bsd/openssh/dist/regress/netcat.c | 1696 +++ .../bsd/openssh/dist/regress/portnum.sh | 34 + .../dist/regress/principals-command.sh | 145 + .../openssh/dist/regress/proto-mismatch.sh | 21 + .../bsd/openssh/dist/regress/proto-version.sh | 36 + .../bsd/openssh/dist/regress/proxy-connect.sh | 31 + .../bsd/openssh/dist/regress/putty-ciphers.sh | 26 + .../bsd/openssh/dist/regress/putty-kex.sh | 23 + .../openssh/dist/regress/putty-transfer.sh | 41 + .../bsd/openssh/dist/regress/reconfigure.sh | 47 + .../bsd/openssh/dist/regress/reexec.sh | 73 + .../bsd/openssh/dist/regress/rekey.sh | 170 + .../bsd/openssh/dist/regress/rsa_openssh.prv | 15 + .../bsd/openssh/dist/regress/rsa_openssh.pub | 1 + .../bsd/openssh/dist/regress/rsa_ssh2.prv | 16 + .../openssh/dist/regress/scp-ssh-wrapper.sh | 59 + .../external/bsd/openssh/dist/regress/scp.sh | 126 + .../bsd/openssh/dist/regress/setuid-allowed.c | 57 + .../bsd/openssh/dist/regress/sftp-badcmds.sh | 65 + .../bsd/openssh/dist/regress/sftp-batch.sh | 55 + .../bsd/openssh/dist/regress/sftp-chroot.sh | 26 + .../bsd/openssh/dist/regress/sftp-cmds.sh | 232 + .../bsd/openssh/dist/regress/sftp-glob.sh | 75 + .../bsd/openssh/dist/regress/sftp-perm.sh | 269 + .../external/bsd/openssh/dist/regress/sftp.sh | 32 + .../openssh/dist/regress/ssh-com-client.sh | 130 + .../openssh/dist/regress/ssh-com-keygen.sh | 74 + .../bsd/openssh/dist/regress/ssh-com-sftp.sh | 65 + .../bsd/openssh/dist/regress/ssh-com.sh | 119 + .../bsd/openssh/dist/regress/ssh2putty.sh | 34 + .../openssh/dist/regress/sshd-log-wrapper.sh | 11 + .../openssh/dist/regress/stderr-after-eof.sh | 24 + .../bsd/openssh/dist/regress/stderr-data.sh | 29 + .../external/bsd/openssh/dist/regress/t11.ok | 1 + .../external/bsd/openssh/dist/regress/t4.ok | 1 + .../external/bsd/openssh/dist/regress/t5.ok | 1 + .../bsd/openssh/dist/regress/test-exec.sh | 564 + .../bsd/openssh/dist/regress/transfer.sh | 26 + .../bsd/openssh/dist/regress/try-ciphers.sh | 42 + .../openssh/dist/regress/unittests/Makefile | 5 + .../dist/regress/unittests/Makefile.inc | 59 + .../dist/regress/unittests/bitmap/Makefile | 12 + .../dist/regress/unittests/bitmap/tests.c | 135 + .../dist/regress/unittests/hostkeys/Makefile | 12 + .../regress/unittests/hostkeys/mktestdata.sh | 94 + .../regress/unittests/hostkeys/test_iterate.c | 1171 +++ .../unittests/hostkeys/testdata/dsa_1.pub | 1 + .../unittests/hostkeys/testdata/dsa_2.pub | 1 + .../unittests/hostkeys/testdata/dsa_3.pub | 1 + .../unittests/hostkeys/testdata/dsa_4.pub | 1 + .../unittests/hostkeys/testdata/dsa_5.pub | 1 + .../unittests/hostkeys/testdata/dsa_6.pub | 1 + .../unittests/hostkeys/testdata/ecdsa_1.pub | 1 + .../unittests/hostkeys/testdata/ecdsa_2.pub | 1 + .../unittests/hostkeys/testdata/ecdsa_3.pub | 1 + .../unittests/hostkeys/testdata/ecdsa_4.pub | 1 + .../unittests/hostkeys/testdata/ecdsa_5.pub | 1 + .../unittests/hostkeys/testdata/ecdsa_6.pub | 1 + .../unittests/hostkeys/testdata/ed25519_1.pub | 1 + .../unittests/hostkeys/testdata/ed25519_2.pub | 1 + .../unittests/hostkeys/testdata/ed25519_3.pub | 1 + .../unittests/hostkeys/testdata/ed25519_4.pub | 1 + .../unittests/hostkeys/testdata/ed25519_5.pub | 1 + .../unittests/hostkeys/testdata/ed25519_6.pub | 1 + .../unittests/hostkeys/testdata/known_hosts | 61 + .../unittests/hostkeys/testdata/rsa1_1.pub | 1 + .../unittests/hostkeys/testdata/rsa1_2.pub | 1 + .../unittests/hostkeys/testdata/rsa1_3.pub | 1 + .../unittests/hostkeys/testdata/rsa1_4.pub | 1 + .../unittests/hostkeys/testdata/rsa1_5.pub | 1 + .../unittests/hostkeys/testdata/rsa1_6.pub | 1 + .../unittests/hostkeys/testdata/rsa_1.pub | 1 + .../unittests/hostkeys/testdata/rsa_2.pub | 1 + .../unittests/hostkeys/testdata/rsa_3.pub | 1 + .../unittests/hostkeys/testdata/rsa_4.pub | 1 + .../unittests/hostkeys/testdata/rsa_5.pub | 1 + .../unittests/hostkeys/testdata/rsa_6.pub | 1 + .../dist/regress/unittests/hostkeys/tests.c | 16 + .../dist/regress/unittests/kex/Makefile | 14 + .../dist/regress/unittests/kex/test_kex.c | 202 + .../dist/regress/unittests/kex/tests.c | 14 + .../dist/regress/unittests/sshbuf/Makefile | 14 + .../regress/unittests/sshbuf/test_sshbuf.c | 240 + .../unittests/sshbuf/test_sshbuf_fixed.c | 126 + .../unittests/sshbuf/test_sshbuf_fuzz.c | 127 + .../sshbuf/test_sshbuf_getput_basic.c | 484 + .../sshbuf/test_sshbuf_getput_crypto.c | 409 + .../sshbuf/test_sshbuf_getput_fuzz.c | 130 + .../unittests/sshbuf/test_sshbuf_misc.c | 138 + .../dist/regress/unittests/sshbuf/tests.c | 28 + .../dist/regress/unittests/sshkey/Makefile | 13 + .../dist/regress/unittests/sshkey/common.c | 84 + .../dist/regress/unittests/sshkey/common.h | 16 + .../regress/unittests/sshkey/mktestdata.sh | 192 + .../dist/regress/unittests/sshkey/test_file.c | 460 + .../dist/regress/unittests/sshkey/test_fuzz.c | 411 + .../regress/unittests/sshkey/test_sshkey.c | 521 + .../regress/unittests/sshkey/testdata/dsa_1 | 12 + .../unittests/sshkey/testdata/dsa_1-cert.fp | 1 + .../unittests/sshkey/testdata/dsa_1-cert.pub | 1 + .../unittests/sshkey/testdata/dsa_1.fp | 1 + .../unittests/sshkey/testdata/dsa_1.fp.bb | 1 + .../unittests/sshkey/testdata/dsa_1.param.g | 1 + .../sshkey/testdata/dsa_1.param.priv | 1 + .../unittests/sshkey/testdata/dsa_1.param.pub | 1 + .../unittests/sshkey/testdata/dsa_1.pub | 1 + .../unittests/sshkey/testdata/dsa_1_pw | 15 + .../regress/unittests/sshkey/testdata/dsa_2 | 12 + .../unittests/sshkey/testdata/dsa_2.fp | 1 + .../unittests/sshkey/testdata/dsa_2.fp.bb | 1 + .../unittests/sshkey/testdata/dsa_2.pub | 1 + .../regress/unittests/sshkey/testdata/dsa_n | 12 + .../unittests/sshkey/testdata/dsa_n_pw | 21 + .../regress/unittests/sshkey/testdata/ecdsa_1 | 5 + .../unittests/sshkey/testdata/ecdsa_1-cert.fp | 1 + .../sshkey/testdata/ecdsa_1-cert.pub | 1 + .../unittests/sshkey/testdata/ecdsa_1.fp | 1 + .../unittests/sshkey/testdata/ecdsa_1.fp.bb | 1 + .../sshkey/testdata/ecdsa_1.param.curve | 1 + .../sshkey/testdata/ecdsa_1.param.priv | 1 + .../sshkey/testdata/ecdsa_1.param.pub | 1 + .../unittests/sshkey/testdata/ecdsa_1.pub | 1 + .../unittests/sshkey/testdata/ecdsa_1_pw | 8 + .../regress/unittests/sshkey/testdata/ecdsa_2 | 7 + .../unittests/sshkey/testdata/ecdsa_2.fp | 1 + .../unittests/sshkey/testdata/ecdsa_2.fp.bb | 1 + .../sshkey/testdata/ecdsa_2.param.curve | 1 + .../sshkey/testdata/ecdsa_2.param.priv | 1 + .../sshkey/testdata/ecdsa_2.param.pub | 1 + .../unittests/sshkey/testdata/ecdsa_2.pub | 1 + .../regress/unittests/sshkey/testdata/ecdsa_n | 5 + .../unittests/sshkey/testdata/ecdsa_n_pw | 9 + .../unittests/sshkey/testdata/ed25519_1 | 7 + .../sshkey/testdata/ed25519_1-cert.fp | 1 + .../sshkey/testdata/ed25519_1-cert.pub | 1 + .../unittests/sshkey/testdata/ed25519_1.fp | 1 + .../unittests/sshkey/testdata/ed25519_1.fp.bb | 1 + .../unittests/sshkey/testdata/ed25519_1.pub | 1 + .../unittests/sshkey/testdata/ed25519_1_pw | 8 + .../unittests/sshkey/testdata/ed25519_2 | 7 + .../unittests/sshkey/testdata/ed25519_2.fp | 1 + .../unittests/sshkey/testdata/ed25519_2.fp.bb | 1 + .../unittests/sshkey/testdata/ed25519_2.pub | 1 + .../dist/regress/unittests/sshkey/testdata/pw | 1 + .../regress/unittests/sshkey/testdata/rsa1_1 | Bin 0 -> 533 bytes .../unittests/sshkey/testdata/rsa1_1.fp | 1 + .../unittests/sshkey/testdata/rsa1_1.fp.bb | 1 + .../unittests/sshkey/testdata/rsa1_1.param.n | 1 + .../unittests/sshkey/testdata/rsa1_1.pub | 1 + .../unittests/sshkey/testdata/rsa1_1_pw | Bin 0 -> 533 bytes .../regress/unittests/sshkey/testdata/rsa1_2 | Bin 0 -> 981 bytes .../unittests/sshkey/testdata/rsa1_2.fp | 1 + .../unittests/sshkey/testdata/rsa1_2.fp.bb | 1 + .../unittests/sshkey/testdata/rsa1_2.param.n | 1 + .../unittests/sshkey/testdata/rsa1_2.pub | 1 + .../regress/unittests/sshkey/testdata/rsa_1 | 15 + .../unittests/sshkey/testdata/rsa_1-cert.fp | 1 + .../unittests/sshkey/testdata/rsa_1-cert.pub | 1 + .../unittests/sshkey/testdata/rsa_1.fp | 1 + .../unittests/sshkey/testdata/rsa_1.fp.bb | 1 + .../unittests/sshkey/testdata/rsa_1.param.n | 1 + .../unittests/sshkey/testdata/rsa_1.param.p | 1 + .../unittests/sshkey/testdata/rsa_1.param.q | 1 + .../unittests/sshkey/testdata/rsa_1.pub | 1 + .../unittests/sshkey/testdata/rsa_1_pw | 18 + .../regress/unittests/sshkey/testdata/rsa_2 | 27 + .../unittests/sshkey/testdata/rsa_2.fp | 1 + .../unittests/sshkey/testdata/rsa_2.fp.bb | 1 + .../unittests/sshkey/testdata/rsa_2.param.n | 1 + .../unittests/sshkey/testdata/rsa_2.param.p | 1 + .../unittests/sshkey/testdata/rsa_2.param.q | 1 + .../unittests/sshkey/testdata/rsa_2.pub | 1 + .../regress/unittests/sshkey/testdata/rsa_n | 15 + .../unittests/sshkey/testdata/rsa_n_pw | 17 + .../dist/regress/unittests/sshkey/tests.c | 27 + .../regress/unittests/test_helper/Makefile | 16 + .../dist/regress/unittests/test_helper/fuzz.c | 438 + .../unittests/test_helper/test_helper.c | 526 + .../unittests/test_helper/test_helper.h | 303 + .../bsd/openssh/dist/regress/valgrind-unit.sh | 20 + .../bsd/openssh/dist/regress/yes-head.sh | 15 + .../bsd/openssh/dist/sandbox-capsicum.c | 122 + .../bsd/openssh/dist/sandbox-darwin.c | 98 + .../external/bsd/openssh/dist/sandbox-null.c | 72 + .../bsd/openssh/dist/sandbox-seccomp-filter.c | 318 + .../bsd/openssh/dist/scard/.cvsignore | 2 + crypto/external/bsd/openssh/dist/scp.0 | 165 + .../external/bsd/openssh/dist/sftp-server.0 | 96 + crypto/external/bsd/openssh/dist/sftp.0 | 383 + crypto/external/bsd/openssh/dist/ssh-add.0 | 129 + crypto/external/bsd/openssh/dist/ssh-keygen.0 | 566 + .../external/bsd/openssh/dist/ssh-keyscan.0 | 109 + .../bsd/openssh/dist/ssh-pkcs11-helper.0 | 25 + crypto/external/bsd/openssh/dist/ssh.0 | 972 ++ crypto/external/bsd/openssh/dist/ssh_config.0 | 1026 ++ crypto/external/bsd/openssh/dist/strtonum.c | 1 + .../bsd/openssh/dist/timingsafe_bcmp.c | 1 + crypto/external/bsd/openssh/dist/xcrypt.c | 1 + crypto/external/bsd/openssh/dist/xmmap.c | 1 + 434 files changed, 60639 insertions(+) create mode 100644 crypto/external/bsd/openssh/dist/CREDITS create mode 100644 crypto/external/bsd/openssh/dist/ChangeLog create mode 100644 crypto/external/bsd/openssh/dist/INSTALL create mode 100644 crypto/external/bsd/openssh/dist/README.dns create mode 100644 crypto/external/bsd/openssh/dist/README.platform create mode 100644 crypto/external/bsd/openssh/dist/README.privsep create mode 100644 crypto/external/bsd/openssh/dist/README.tun create mode 100644 crypto/external/bsd/openssh/dist/TODO create mode 100644 crypto/external/bsd/openssh/dist/audit-bsm.c create mode 100644 crypto/external/bsd/openssh/dist/audit-linux.c create mode 100644 crypto/external/bsd/openssh/dist/audit.c create mode 100644 crypto/external/bsd/openssh/dist/audit.h create mode 100644 crypto/external/bsd/openssh/dist/auth-shadow.c create mode 100644 crypto/external/bsd/openssh/dist/auth-sia.c create mode 100644 crypto/external/bsd/openssh/dist/auth-sia.h create mode 120000 crypto/external/bsd/openssh/dist/bindresvport.c create mode 120000 crypto/external/bsd/openssh/dist/bsd-misc.c create mode 120000 crypto/external/bsd/openssh/dist/bsd-setres_id.c create mode 100644 crypto/external/bsd/openssh/dist/cipher-aes.c create mode 100644 crypto/external/bsd/openssh/dist/cipher-ctr.c create mode 100644 crypto/external/bsd/openssh/dist/config.h create mode 100644 crypto/external/bsd/openssh/dist/contrib/Makefile create mode 100644 crypto/external/bsd/openssh/dist/contrib/README create mode 100644 crypto/external/bsd/openssh/dist/contrib/aix/README create mode 100755 crypto/external/bsd/openssh/dist/contrib/aix/buildbff.sh create mode 100755 crypto/external/bsd/openssh/dist/contrib/aix/inventory.sh create mode 100644 crypto/external/bsd/openssh/dist/contrib/aix/pam.conf create mode 100644 crypto/external/bsd/openssh/dist/contrib/cygwin/Makefile create mode 100644 crypto/external/bsd/openssh/dist/contrib/cygwin/README create mode 100644 crypto/external/bsd/openssh/dist/contrib/cygwin/ssh-host-config create mode 100644 crypto/external/bsd/openssh/dist/contrib/cygwin/ssh-user-config create mode 100644 crypto/external/bsd/openssh/dist/contrib/cygwin/sshd-inetd create mode 100644 crypto/external/bsd/openssh/dist/contrib/findssl.sh create mode 100644 crypto/external/bsd/openssh/dist/contrib/gnome-ssh-askpass1.c create mode 100644 crypto/external/bsd/openssh/dist/contrib/gnome-ssh-askpass2.c create mode 100644 crypto/external/bsd/openssh/dist/contrib/hpux/README create mode 100644 crypto/external/bsd/openssh/dist/contrib/hpux/egd create mode 100755 crypto/external/bsd/openssh/dist/contrib/hpux/egd.rc create mode 100644 crypto/external/bsd/openssh/dist/contrib/hpux/sshd create mode 100755 crypto/external/bsd/openssh/dist/contrib/hpux/sshd.rc create mode 100644 crypto/external/bsd/openssh/dist/contrib/redhat/gnome-ssh-askpass.csh create mode 100644 crypto/external/bsd/openssh/dist/contrib/redhat/gnome-ssh-askpass.sh create mode 100644 crypto/external/bsd/openssh/dist/contrib/redhat/openssh.spec create mode 100755 crypto/external/bsd/openssh/dist/contrib/redhat/sshd.init create mode 100755 crypto/external/bsd/openssh/dist/contrib/redhat/sshd.init.old create mode 100644 crypto/external/bsd/openssh/dist/contrib/redhat/sshd.pam create mode 100644 crypto/external/bsd/openssh/dist/contrib/redhat/sshd.pam.old create mode 100644 crypto/external/bsd/openssh/dist/contrib/solaris/README create mode 100644 crypto/external/bsd/openssh/dist/contrib/ssh-copy-id create mode 100644 crypto/external/bsd/openssh/dist/contrib/ssh-copy-id.1 create mode 100644 crypto/external/bsd/openssh/dist/contrib/sshd.pam.freebsd create mode 100644 crypto/external/bsd/openssh/dist/contrib/sshd.pam.generic create mode 100644 crypto/external/bsd/openssh/dist/contrib/suse/openssh.spec create mode 100644 crypto/external/bsd/openssh/dist/contrib/suse/rc.config.sshd create mode 100644 crypto/external/bsd/openssh/dist/contrib/suse/rc.sshd create mode 100644 crypto/external/bsd/openssh/dist/contrib/suse/sysconfig.ssh create mode 100644 crypto/external/bsd/openssh/dist/defines.h create mode 100644 crypto/external/bsd/openssh/dist/entropy.c create mode 100644 crypto/external/bsd/openssh/dist/entropy.h create mode 120000 crypto/external/bsd/openssh/dist/explicit_bzero.c create mode 100644 crypto/external/bsd/openssh/dist/loginrec.c create mode 100644 crypto/external/bsd/openssh/dist/loginrec.h create mode 100644 crypto/external/bsd/openssh/dist/logintest.c create mode 100644 crypto/external/bsd/openssh/dist/md5crypt.c create mode 100644 crypto/external/bsd/openssh/dist/md5crypt.h create mode 100644 crypto/external/bsd/openssh/dist/moduli.0 create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/.cvsignore create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/Makefile create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/Makefile.in create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/arc4random.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/base64.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/base64.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/basename.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bcrypt_pbkdf.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bindresvport.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/blf.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/blowfish.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bsd-asprintf.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bsd-closefrom.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bsd-cray.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bsd-cray.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bsd-cygwin_util.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bsd-cygwin_util.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bsd-getpeereid.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bsd-misc.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bsd-misc.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bsd-nextstep.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bsd-nextstep.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bsd-openpty.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bsd-poll.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bsd-poll.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bsd-setres_id.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bsd-setres_id.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bsd-snprintf.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bsd-statvfs.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bsd-statvfs.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bsd-waitpid.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/bsd-waitpid.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/chacha_private.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/charclass.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/daemon.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/dirname.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/explicit_bzero.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/fake-rfc2553.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/fake-rfc2553.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/fmt_scaled.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/getcwd.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/getgrouplist.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/getopt.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/getopt_long.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/getrrsetbyname-ldns.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/getrrsetbyname.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/getrrsetbyname.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/glob.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/glob.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/inet_aton.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/inet_ntoa.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/inet_ntop.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/kludge-fd_set.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/md5.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/md5.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/mktemp.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/openbsd-compat.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/openssl-compat.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/openssl-compat.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/port-aix.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/port-aix.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/port-irix.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/port-irix.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/port-linux.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/port-linux.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/port-solaris.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/port-solaris.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/port-tun.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/port-tun.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/port-uw.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/port-uw.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/pwcache.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/readpassphrase.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/readpassphrase.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/reallocarray.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/realpath.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/regress/.cvsignore create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/regress/Makefile create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/regress/Makefile.in create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/regress/closefromtest.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/regress/opensslvertest.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/regress/snprintftest.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/regress/strduptest.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/regress/strtonumtest.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/rmd160.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/rmd160.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/rresvport.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/setenv.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/setproctitle.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/sha1.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/sha1.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/sha2.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/sha2.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/sigact.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/sigact.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/strlcat.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/strlcpy.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/strmode.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/strnlen.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/strptime.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/strsep.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/strtoll.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/strtonum.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/strtoul.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/strtoull.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/sys-queue.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/sys-tree.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/timingsafe_bcmp.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/vis.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/vis.h create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/xcrypt.c create mode 100644 crypto/external/bsd/openssh/dist/openbsd-compat/xmmap.c create mode 100644 crypto/external/bsd/openssh/dist/openssh.xml create mode 100644 crypto/external/bsd/openssh/dist/opensshd.init create mode 120000 crypto/external/bsd/openssh/dist/openssl-compat.c create mode 120000 crypto/external/bsd/openssh/dist/openssl-compat.h create mode 100644 crypto/external/bsd/openssh/dist/platform.c create mode 100644 crypto/external/bsd/openssh/dist/platform.h create mode 120000 crypto/external/bsd/openssh/dist/reallocarray.c create mode 120000 crypto/external/bsd/openssh/dist/realpath.c create mode 100644 crypto/external/bsd/openssh/dist/regress/.cvsignore create mode 100644 crypto/external/bsd/openssh/dist/regress/Makefile create mode 100644 crypto/external/bsd/openssh/dist/regress/README.regress create mode 100644 crypto/external/bsd/openssh/dist/regress/addrmatch.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/agent-getpeereid.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/agent-pkcs11.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/agent-ptrace.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/agent-timeout.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/agent.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/banner.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/broken-pipe.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/brokenkeys.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/cert-hostkey.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/cert-userkey.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/cfgmatch.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/cfgparse.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/cipher-speed.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/conch-ciphers.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/connect-privsep.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/connect.sh create mode 100755 crypto/external/bsd/openssh/dist/regress/core.13225 create mode 100644 crypto/external/bsd/openssh/dist/regress/dhgex.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/dsa_ssh2.prv create mode 100644 crypto/external/bsd/openssh/dist/regress/dsa_ssh2.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/dynamic-forward.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/envpass.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/exit-status.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/forcecommand.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/forward-control.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/forwarding.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/host-expand.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/hostkey-agent.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/hostkey-rotate.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/integrity.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/kextype.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/key-options.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/keygen-change.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/keygen-convert.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/keygen-knownhosts.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/keys-command.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/keyscan.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/keytype.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/krl.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/limit-keytype.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/localcommand.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/login-timeout.sh create mode 100755 crypto/external/bsd/openssh/dist/regress/modpipe.c create mode 100644 crypto/external/bsd/openssh/dist/regress/multiplex.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/multipubkey.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/netcat.c create mode 100644 crypto/external/bsd/openssh/dist/regress/portnum.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/principals-command.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/proto-mismatch.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/proto-version.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/proxy-connect.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/putty-ciphers.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/putty-kex.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/putty-transfer.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/reconfigure.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/reexec.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/rekey.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/rsa_openssh.prv create mode 100644 crypto/external/bsd/openssh/dist/regress/rsa_openssh.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/rsa_ssh2.prv create mode 100644 crypto/external/bsd/openssh/dist/regress/scp-ssh-wrapper.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/scp.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/setuid-allowed.c create mode 100644 crypto/external/bsd/openssh/dist/regress/sftp-badcmds.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/sftp-batch.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/sftp-chroot.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/sftp-cmds.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/sftp-glob.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/sftp-perm.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/sftp.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/ssh-com-client.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/ssh-com-keygen.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/ssh-com-sftp.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/ssh-com.sh create mode 100755 crypto/external/bsd/openssh/dist/regress/ssh2putty.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/sshd-log-wrapper.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/stderr-after-eof.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/stderr-data.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/t11.ok create mode 100644 crypto/external/bsd/openssh/dist/regress/t4.ok create mode 100644 crypto/external/bsd/openssh/dist/regress/t5.ok create mode 100644 crypto/external/bsd/openssh/dist/regress/test-exec.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/transfer.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/try-ciphers.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/Makefile create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/Makefile.inc create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/bitmap/Makefile create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/bitmap/tests.c create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/Makefile create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/mktestdata.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/test_iterate.c create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_1.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_2.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_3.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_4.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_5.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_6.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_1.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_2.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_3.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_4.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_5.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_6.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_1.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_2.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_3.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_4.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_5.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_6.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/known_hosts create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_1.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_2.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_3.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_4.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_5.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_6.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_1.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_2.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_3.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_4.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_5.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_6.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/tests.c create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/kex/Makefile create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/kex/test_kex.c create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/kex/tests.c create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/Makefile create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf.c create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_fixed.c create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_fuzz.c create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_getput_basic.c create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_misc.c create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/tests.c create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/Makefile create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/common.c create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/common.h create mode 100755 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/mktestdata.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/test_file.c create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/test_fuzz.c create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/test_sshkey.c create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1 create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1-cert.fp create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1-cert.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.fp create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.fp.bb create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.param.g create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.param.priv create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.param.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1_pw create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_2 create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_2.fp create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_2.fp.bb create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_2.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_n create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_n_pw create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1 create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1-cert.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.fp create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.fp.bb create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.param.curve create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.param.priv create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.param.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1_pw create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2 create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.fp create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.fp.bb create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.param.curve create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.param.priv create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.param.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_n create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_n_pw create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1 create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1-cert.fp create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1-cert.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1.fp create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1.fp.bb create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1_pw create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_2 create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_2.fp create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_2.fp.bb create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_2.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/pw create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1 create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1.fp create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1.fp.bb create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1.param.n create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1_pw create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_2 create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_2.fp create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_2.fp.bb create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_2.param.n create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_2.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1 create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1-cert.fp create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1-cert.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.fp create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.fp.bb create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.param.n create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.param.p create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.param.q create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1_pw create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2 create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.fp create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.fp.bb create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.param.n create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.param.p create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.param.q create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.pub create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_n create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_n_pw create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/sshkey/tests.c create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/test_helper/Makefile create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/test_helper/fuzz.c create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/test_helper/test_helper.c create mode 100644 crypto/external/bsd/openssh/dist/regress/unittests/test_helper/test_helper.h create mode 100755 crypto/external/bsd/openssh/dist/regress/valgrind-unit.sh create mode 100644 crypto/external/bsd/openssh/dist/regress/yes-head.sh create mode 100644 crypto/external/bsd/openssh/dist/sandbox-capsicum.c create mode 100644 crypto/external/bsd/openssh/dist/sandbox-darwin.c create mode 100644 crypto/external/bsd/openssh/dist/sandbox-null.c create mode 100644 crypto/external/bsd/openssh/dist/sandbox-seccomp-filter.c create mode 100644 crypto/external/bsd/openssh/dist/scard/.cvsignore create mode 100644 crypto/external/bsd/openssh/dist/scp.0 create mode 100644 crypto/external/bsd/openssh/dist/sftp-server.0 create mode 100644 crypto/external/bsd/openssh/dist/sftp.0 create mode 100644 crypto/external/bsd/openssh/dist/ssh-add.0 create mode 100644 crypto/external/bsd/openssh/dist/ssh-keygen.0 create mode 100644 crypto/external/bsd/openssh/dist/ssh-keyscan.0 create mode 100644 crypto/external/bsd/openssh/dist/ssh-pkcs11-helper.0 create mode 100644 crypto/external/bsd/openssh/dist/ssh.0 create mode 100644 crypto/external/bsd/openssh/dist/ssh_config.0 create mode 120000 crypto/external/bsd/openssh/dist/strtonum.c create mode 120000 crypto/external/bsd/openssh/dist/timingsafe_bcmp.c create mode 120000 crypto/external/bsd/openssh/dist/xcrypt.c create mode 120000 crypto/external/bsd/openssh/dist/xmmap.c diff --git a/crypto/external/bsd/openssh/dist/CREDITS b/crypto/external/bsd/openssh/dist/CREDITS new file mode 100644 index 000000000..eaf105a91 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/CREDITS @@ -0,0 +1,105 @@ +Tatu Ylonen - Creator of SSH + +Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, +Theo de Raadt, and Dug Song - Creators of OpenSSH + +Ahsan Rashid - UnixWare long passwords +Alain St-Denis - Irix fix +Alexandre Oliva - AIX fixes +Andre Lucas - new login code, many fixes +Andreas Steinmetz - Shadow password expiry support +Andrew McGill - SCO fixes +Andrew Morgan - PAM bugfixes +Andrew Stribblehill - Bugfixes +Andy Sloane - bugfixes +Aran Cox - SCO bugfixes +Arkadiusz Miskiewicz - IPv6 compat fixes +Ben Lindstrom - NeXT support +Ben Taylor - Solaris debugging and fixes +Bratislav ILICH - Configure fix +Charles Levert - SunOS 4 & bug fixes +Chip Salzenberg - Assorted patches +Chris Adams - OSF SIA support +Chris Saia - SuSE packaging +Chris, the Young One - Password auth fixes +Christos Zoulas - Autoconf fixes +Chun-Chung Chen - RPM fixes +Corinna Vinschen - Cygwin support +Chad Mynhier - Solaris Process Contract support +Dan Brosemer - Autoconf support, build fixes +Darren Hall - AIX patches +Darren Tucker - AIX BFF package scripts +David Agraz - Build fixes +David Del Piero - bug fixes +David Hesprich - Configure fixes +David Rankin - libwrap, AIX, NetBSD fixes +Dag-Erling Smørgrav - Challenge-Response PAM code. +Dhiraj Gulati - UnixWare long passwords +Ed Eden - configure fixes +Garrick James - configure fixes +Gary E. Miller - SCO support +Ged Lodder - HPUX fixes and enhancements +Gert Doering - bug and portability fixes +HARUYAMA Seigo - Translations & doc fixes +Hideaki YOSHIFUJI - IPv6 and bug fixes +Hiroshi Takekawa - Configure fixes +Holger Trapp - KRB4/AFS config patch +IWAMURO Motonori - bugfixes +Jani Hakala - Patches +Jarno Huuskonen - Bugfixes +Jim Knoble - Many patches +Jonchen (email unknown) - the original author of PAM support of SSH +Juergen Keil - scp bugfixing +KAMAHARA Junzo - Configure fixes +Kees Cook - scp fixes +Kenji Miyake - Configure fixes +Kevin Cawlfield - AIX fixes. +Kevin O'Connor - RSAless operation +Kevin Steves - HP support, bugfixes, improvements +Kiyokazu SUTO - Bugfixes +Larry Jones - Bugfixes +Lutz Jaenicke - Bugfixes +Marc G. Fournier - Solaris patches +Mark D. Baushke - bug fixes +Martin Johansson - Linux fixes +Mark D. Roth - Features, bug fixes +Mark Miller - Bugfixes +Matt Richards - AIX patches +Michael Steffens - HP-UX fixes +Michael Stone - Irix enhancements +Nakaji Hiroyuki - Sony News-OS patch +Nalin Dahyabhai - PAM environment patch +Nate Itkin - SunOS 4.1.x fixes +Niels Kristian Bech Jensen - Assorted patches +Pavel Kankovsky - Security fixes +Pavel Troller - Bugfixes +Pekka Savola - Bugfixes +Peter Kocks - Makefile fixes +Peter Stuge - mdoc2man.awk script +Phil Hands - Debian scripts, assorted patches +Phil Karn - Autoconf fixes +Philippe WILLEM - Bugfixes +Phill Camp - login code fix +Rip Loomis - Solaris package support, fixes +Robert Dahlem - Reliant Unix fixes +Roumen Petrov - Compile & configure fixes +SAKAI Kiyotaka - Multiple bugfixes +Simon Wilkinson - PAM fixes, Compat with MIT KrbV +Solar Designer - many patches and technical assistance +Svante Signell - Bugfixes +Thomas Neumann - Shadow passwords +Tim Rice - Portability & SCO fixes +Tobias Oetiker - Bugfixes +Tom Bertelson's - AIX auth fixes +Tor-Ake Fransson - AIX support +Tudor Bosman - MD5 password support +Udo Schweigert - ReliantUNIX support +Wendy Palm - Cray support. +Zack Weinberg - GNOME askpass enhancement + +Apologies to anyone I have missed. + +Damien Miller + +$Id: CREDITS,v 1.81 2006/08/30 17:24:41 djm Exp $ + diff --git a/crypto/external/bsd/openssh/dist/ChangeLog b/crypto/external/bsd/openssh/dist/ChangeLog new file mode 100644 index 000000000..0e0dd8787 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/ChangeLog @@ -0,0 +1,9133 @@ +commit e91346dc2bbf460246df2ab591b7613908c1b0ad +Author: Damien Miller +Date: Fri Aug 21 14:49:03 2015 +1000 + + we don't use Github for issues/pull-requests + +commit a4f5b507c708cc3dc2c8dd2d02e4416d7514dc23 +Author: Damien Miller +Date: Fri Aug 21 14:43:55 2015 +1000 + + fix URL for connect.c + +commit d026a8d3da0f8186598442997c7d0a28e7275414 +Author: Damien Miller +Date: Fri Aug 21 13:47:10 2015 +1000 + + update version numbers for 7.1 + +commit 78f8f589f0ca1c9f41e5a9bae3cda5ce8a6b42ed +Author: djm@openbsd.org +Date: Fri Aug 21 03:45:26 2015 +0000 + + upstream commit + + openssh-7.1 + + Upstream-ID: ff7b1ef4b06caddfb45e08ba998128c88be3d73f + +commit 32a181980c62fce94f7f9ffaf6a79d90f0c309cf +Author: djm@openbsd.org +Date: Fri Aug 21 03:42:19 2015 +0000 + + upstream commit + + fix inverted logic that broke PermitRootLogin; reported + by Mantas Mikulenas; ok markus@ + + Upstream-ID: 260dd6a904c1bb7e43267e394b1c9cf70bdd5ea5 + +commit ce445b0ed927e45bd5bdce8f836eb353998dd65c +Author: deraadt@openbsd.org +Date: Thu Aug 20 22:32:42 2015 +0000 + + upstream commit + + Do not cast result of malloc/calloc/realloc* if stdlib.h + is in scope ok krw millert + + Upstream-ID: 5e50ded78cadf3841556649a16cc4b1cb6c58667 + +commit 05291e5288704d1a98bacda269eb5a0153599146 +Author: naddy@openbsd.org +Date: Thu Aug 20 19:20:06 2015 +0000 + + upstream commit + + In the certificates section, be consistent about using + "host_key" and "user_key" for the respective key types. ok sthen@ deraadt@ + + Upstream-ID: 9e037ea3b15577b238604c5533e082a3947f13cb + +commit 8543d4ef6f2e9f98c3e6b77c894ceec30c5e4ae4 +Author: djm@openbsd.org +Date: Wed Aug 19 23:21:42 2015 +0000 + + upstream commit + + Better compat matching for WinSCP, add compat matching + for FuTTY (fork of PuTTY); ok markus@ deraadt@ + + Upstream-ID: 24001d1ac115fa3260fbdc329a4b9aeb283c5389 + +commit ec6eda16ebab771aa3dfc90629b41953b999cb1e +Author: djm@openbsd.org +Date: Wed Aug 19 23:19:01 2015 +0000 + + upstream commit + + fix double-free() in error path of DSA key generation + reported by Mateusz Kocielski; ok markus@ + + Upstream-ID: 4735d8f888b10599a935fa1b374787089116713c + +commit 45b0eb752c94954a6de046bfaaf129e518ad4b5b +Author: djm@openbsd.org +Date: Wed Aug 19 23:18:26 2015 +0000 + + upstream commit + + fix free() of uninitialised pointer reported by Mateusz + Kocielski; ok markus@ + + Upstream-ID: 519552b050618501a06b7b023de5cb104e2c5663 + +commit c837643b93509a3ef538cb6624b678c5fe32ff79 +Author: djm@openbsd.org +Date: Wed Aug 19 23:17:51 2015 +0000 + + upstream commit + + fixed unlink([uninitialised memory]) reported by Mateusz + Kocielski; ok markus@ + + Upstream-ID: 14a0c4e7d891f5a8dabc4b89d4f6b7c0d5a20109 + +commit 1f8d3d629cd553031021068eb9c646a5f1e50994 +Author: jmc@openbsd.org +Date: Fri Aug 14 15:32:41 2015 +0000 + + upstream commit + + match myproposal.h order; from brian conway (i snuck in a + tweak while here) + + ok dtucker + + Upstream-ID: 35174a19b5237ea36aa3798f042bf5933b772c67 + +commit 1dc8d93ce69d6565747eb44446ed117187621b26 +Author: deraadt@openbsd.org +Date: Thu Aug 6 14:53:21 2015 +0000 + + upstream commit + + add prohibit-password as a synonymn for without-password, + since the without-password is causing too many questions. Harden it to ban + all but pubkey, hostbased, and GSSAPI auth (when the latter is enabled) from + djm, ok markus + + Upstream-ID: d53317d7b28942153e6236d3fd6e12ceb482db7a + +commit 90a95a4745a531b62b81ce3b025e892bdc434de5 +Author: Damien Miller +Date: Tue Aug 11 13:53:41 2015 +1000 + + update version in README + +commit 318c37743534b58124f1bab37a8a0087a3a9bd2f +Author: Damien Miller +Date: Tue Aug 11 13:53:09 2015 +1000 + + update versions in *.spec + +commit 5e75f5198769056089fb06c4d738ab0e5abc66f7 +Author: Damien Miller +Date: Tue Aug 11 13:34:12 2015 +1000 + + set sshpam_ctxt to NULL after free + + Avoids use-after-free in monitor when privsep child is compromised. + Reported by Moritz Jodeit; ok dtucker@ + +commit d4697fe9a28dab7255c60433e4dd23cf7fce8a8b +Author: Damien Miller +Date: Tue Aug 11 13:33:24 2015 +1000 + + Don't resend username to PAM; it already has it. + + Pointed out by Moritz Jodeit; ok dtucker@ + +commit 88763a6c893bf3dfe951ba9271bf09715e8d91ca +Author: Darren Tucker +Date: Mon Jul 27 12:14:25 2015 +1000 + + Import updated moduli file from OpenBSD. + +commit 55b263fb7cfeacb81aaf1c2036e0394c881637da +Author: Damien Miller +Date: Mon Aug 10 11:13:44 2015 +1000 + + let principals-command.sh work for noexec /var/run + +commit 2651e34cd11b1aac3a0fe23b86d8c2ff35c07897 +Author: Damien Miller +Date: Thu Aug 6 11:43:42 2015 +1000 + + work around echo -n / sed behaviour in tests + +commit d85dad81778c1aa8106acd46930b25fdf0d15b2a +Author: djm@openbsd.org +Date: Wed Aug 5 05:27:33 2015 +0000 + + upstream commit + + adjust for RSA minimum modulus switch; ok deraadt@ + + Upstream-Regress-ID: 5a72c83431b96224d583c573ca281cd3a3ebfdae + +commit 57e8e229bad5fe6056b5f1199665f5f7008192c6 +Author: djm@openbsd.org +Date: Tue Aug 4 05:23:06 2015 +0000 + + upstream commit + + backout SSH_RSA_MINIMUM_MODULUS_SIZE increase for this + release; problems spotted by sthen@ ok deraadt@ markus@ + + Upstream-ID: d0bd60dde9e8c3cd7030007680371894c1499822 + +commit f097d0ea1e0889ca0fa2e53a00214e43ab7fa22a +Author: djm@openbsd.org +Date: Sun Aug 2 09:56:42 2015 +0000 + + upstream commit + + openssh 7.0; ok deraadt@ + + Upstream-ID: c63afdef537f57f28ae84145c5a8e29e9250221f + +commit 3d5728a0f6874ce4efb16913a12963595070f3a9 +Author: chris@openbsd.org +Date: Fri Jul 31 15:38:09 2015 +0000 + + upstream commit + + Allow PermitRootLogin to be overridden by config + + ok markus@ deeradt@ + + Upstream-ID: 5cf3e26ed702888de84e2dc9d0054ccf4d9125b4 + +commit 6f941396b6835ad18018845f515b0c4fe20be21a +Author: djm@openbsd.org +Date: Thu Jul 30 23:09:15 2015 +0000 + + upstream commit + + fix pty permissions; patch from Nikolay Edigaryev; ok + deraadt + + Upstream-ID: 40ff076d2878b916fbfd8e4f45dbe5bec019e550 + +commit f4373ed1e8fbc7c8ce3fc4ea97d0ba2e0c1d7ef0 +Author: deraadt@openbsd.org +Date: Thu Jul 30 19:23:02 2015 +0000 + + upstream commit + + change default: PermitRootLogin without-password matching + install script changes coming as well ok djm markus + + Upstream-ID: 0e2a6c4441daf5498b47a61767382bead5eb8ea6 + +commit 0c30ba91f87fcda7e975e6ff8a057f624e87ea1c +Author: Damien Miller +Date: Thu Jul 30 12:31:39 2015 +1000 + + downgrade OOM adjustment logging: verbose -> debug + +commit f9eca249d4961f28ae4b09186d7dc91de74b5895 +Author: djm@openbsd.org +Date: Thu Jul 30 00:01:34 2015 +0000 + + upstream commit + + Allow ssh_config and sshd_config kex parameters options be + prefixed by a '+' to indicate that the specified items be appended to the + default rather than replacing it. + + approach suggested by dtucker@, feedback dlg@, ok markus@ + + Upstream-ID: 0f901137298fc17095d5756ff1561a7028e8882a + +commit 5cefe769105a2a2e3ca7479d28d9a325d5ef0163 +Author: djm@openbsd.org +Date: Wed Jul 29 08:34:54 2015 +0000 + + upstream commit + + fix bug in previous; was printing incorrect string for + failed host key algorithms negotiation + + Upstream-ID: 22c0dc6bc61930513065d92e11f0753adc4c6e6e + +commit f319912b0d0e1675b8bb051ed8213792c788bcb2 +Author: djm@openbsd.org +Date: Wed Jul 29 04:43:06 2015 +0000 + + upstream commit + + include the peer's offer when logging a failure to + negotiate a mutual set of algorithms (kex, pubkey, ciphers, etc.) ok markus@ + + Upstream-ID: bbb8caabf5c01790bb845f5ce135565248d7c796 + +commit b6ea0e573042eb85d84defb19227c89eb74cf05a +Author: djm@openbsd.org +Date: Tue Jul 28 23:20:42 2015 +0000 + + upstream commit + + add Cisco to the list of clients that choke on the + hostkeys update extension. Pointed out by Howard Kash + + Upstream-ID: c9eadde28ecec056c73d09ee10ba4570dfba7e84 + +commit 3f628c7b537291c1019ce86af90756fb4e66d0fd +Author: guenther@openbsd.org +Date: Mon Jul 27 16:29:23 2015 +0000 + + upstream commit + + Permit kbind(2) use in the sandbox now, to ease testing + of ld.so work using it + + reminded by miod@, ok deraadt@ + + Upstream-ID: 523922e4d1ba7a091e3824e77a8a3c818ee97413 + +commit ebe27ebe520098bbc0fe58945a87ce8490121edb +Author: millert@openbsd.org +Date: Mon Jul 20 18:44:12 2015 +0000 + + upstream commit + + Move .Pp before .Bl, not after to quiet mandoc -Tlint. + Noticed by jmc@ + + Upstream-ID: 59fadbf8407cec4e6931e50c53cfa0214a848e23 + +commit d5d91d0da819611167782c66ab629159169d94d4 +Author: millert@openbsd.org +Date: Mon Jul 20 18:42:35 2015 +0000 + + upstream commit + + Sync usage with SYNOPSIS + + Upstream-ID: 7a321a170181a54f6450deabaccb6ef60cf3f0b7 + +commit 79ec2142fbc68dd2ed9688608da355fc0b1ed743 +Author: millert@openbsd.org +Date: Mon Jul 20 15:39:52 2015 +0000 + + upstream commit + + Better desciption of Unix domain socket forwarding. + bz#2423; ok jmc@ + + Upstream-ID: 85e28874726897e3f26ae50dfa2e8d2de683805d + +commit d56fd1828074a4031b18b8faa0bf949669eb18a0 +Author: Damien Miller +Date: Mon Jul 20 11:19:51 2015 +1000 + + make realpath.c compile -Wsign-compare clean + +commit c63c9a691dca26bb7648827f5a13668832948929 +Author: djm@openbsd.org +Date: Mon Jul 20 00:30:01 2015 +0000 + + upstream commit + + mention that the default of UseDNS=no implies that + hostnames cannot be used for host matching in sshd_config and + authorized_keys; bz#2045, ok dtucker@ + + Upstream-ID: 0812705d5f2dfa59aab01f2764ee800b1741c4e1 + +commit 63ebcd0005e9894fcd6871b7b80aeea1fec0ff76 +Author: djm@openbsd.org +Date: Sat Jul 18 08:02:17 2015 +0000 + + upstream commit + + don't ignore PKCS#11 hosted keys that return empty + CKA_ID; patch by Jakub Jelen via bz#2429; ok markus + + Upstream-ID: 2f7c94744eb0342f8ee8bf97b2351d4e00116485 + +commit b15fd989c8c62074397160147a8d5bc34b3f3c63 +Author: djm@openbsd.org +Date: Sat Jul 18 08:00:21 2015 +0000 + + upstream commit + + skip uninitialised PKCS#11 slots; patch from Jakub Jelen + in bz#2427 ok markus@ + + Upstream-ID: 744c1e7796e237ad32992d0d02148e8a18f27d29 + +commit 5b64f85bb811246c59ebab70aed331f26ba37b18 +Author: djm@openbsd.org +Date: Sat Jul 18 07:57:14 2015 +0000 + + upstream commit + + only query each keyboard-interactive device once per + authentication request regardless of how many times it is listed; ok markus@ + + Upstream-ID: d73fafba6e86030436ff673656ec1f33d9ffeda1 + +commit cd7324d0667794eb5c236d8a4e0f236251babc2d +Author: djm@openbsd.org +Date: Fri Jul 17 03:34:27 2015 +0000 + + upstream commit + + remove -u flag to diff (only used for error output) to make + things easier for -portable + + Upstream-Regress-ID: a5d6777d2909540d87afec3039d9bb2414ade548 + +commit deb8d99ecba70b67f4af7880b11ca8768df9ec3a +Author: djm@openbsd.org +Date: Fri Jul 17 03:09:19 2015 +0000 + + upstream commit + + direct-streamlocal@openssh.com Unix domain foward + messages do not contain a "reserved for future use" field and in fact, + serverloop.c checks that there isn't one. Remove erroneous mention from + PROTOCOL description. bz#2421 from Daniel Black + + Upstream-ID: 3d51a19e64f72f764682f1b08f35a8aa810a43ac + +commit 356b61f365405b5257f5b2ab446e5d7bd33a7b52 +Author: djm@openbsd.org +Date: Fri Jul 17 03:04:27 2015 +0000 + + upstream commit + + describe magic for setting up Unix domain socket fowards + via the mux channel; bz#2422 patch from Daniel Black + + Upstream-ID: 943080fe3864715c423bdeb7c920bb30c4eee861 + +commit d3e2aee41487d55b8d7d40f538b84ff1db7989bc +Author: Darren Tucker +Date: Fri Jul 17 12:52:34 2015 +1000 + + Check if realpath works on nonexistent files. + + On some platforms the native realpath doesn't work with non-existent + files (this is actually specified in some versions of POSIX), however + the sftp spec says its realpath with "canonicalize any given path name". + On those platforms, use realpath from the compat library. + + In addition, when compiling with -DFORTIFY_SOURCE, glibc redefines + the realpath symbol to the checked version, so redefine ours to + something else so we pick up the compat version we want. + + bz#2428, ok djm@ + +commit 25b14610dab655646a109db5ef8cb4c4bf2a48a0 +Author: djm@openbsd.org +Date: Fri Jul 17 02:47:45 2015 +0000 + + upstream commit + + fix incorrect test for SSH1 keys when compiled without SSH1 + support + + Upstream-ID: 6004d720345b8e481c405e8ad05ce2271726e451 + +commit df56a8035d429b2184ee94aaa7e580c1ff67f73a +Author: djm@openbsd.org +Date: Wed Jul 15 08:00:11 2015 +0000 + + upstream commit + + fix NULL-deref when SSH1 reenabled + + Upstream-ID: f22fd805288c92b3e9646782d15b48894b2d5295 + +commit 41e38c4d49dd60908484e6703316651333f16b93 +Author: djm@openbsd.org +Date: Wed Jul 15 07:19:50 2015 +0000 + + upstream commit + + regen RSA1 test keys; the last batch was missing their + private parts + + Upstream-Regress-ID: 7ccf437305dd63ff0b48dd50c5fd0f4d4230c10a + +commit 5bf0933184cb622ca3f96d224bf3299fd2285acc +Author: markus@openbsd.org +Date: Fri Jul 10 06:23:25 2015 +0000 + + upstream commit + + Adapt tests, now that DSA if off by default; use + PubkeyAcceptedKeyTypes and PubkeyAcceptedKeyTypes to test DSA. + + Upstream-Regress-ID: 0ff2a3ff5ac1ce5f92321d27aa07b98656efcc5c + +commit 7a6e3fd7b41dbd3756b6bf9acd67954c0b1564cc +Author: markus@openbsd.org +Date: Tue Jul 7 14:54:16 2015 +0000 + + upstream commit + + regen test data after mktestdata.sh changes + + Upstream-Regress-ID: 3495ecb082b9a7c048a2d7c5c845d3bf181d25a4 + +commit 7c8c174c69f681d4910fa41c37646763692b28e2 +Author: markus@openbsd.org +Date: Tue Jul 7 14:53:30 2015 +0000 + + upstream commit + + adapt tests to new minimum RSA size and default FP format + + Upstream-Regress-ID: a4b30afd174ce82b96df14eb49fb0b81398ffd0e + +commit 6a977a4b68747ade189e43d302f33403fd4a47ac +Author: djm@openbsd.org +Date: Fri Jul 3 04:39:23 2015 +0000 + + upstream commit + + legacy v00 certificates are gone; adapt and don't try to + test them; "sure" markus@ dtucker@ + + Upstream-Regress-ID: c57321e69b3cd4a3b3396dfcc43f0803d047da12 + +commit 0c4123ad5e93fb90fee9c6635b13a6cdabaac385 +Author: djm@openbsd.org +Date: Wed Jul 1 23:11:18 2015 +0000 + + upstream commit + + don't expect SSH v.1 in unittests + + Upstream-Regress-ID: f8812b16668ba78e6a698646b2a652b90b653397 + +commit 3c099845798a817cdde513c39074ec2063781f18 +Author: djm@openbsd.org +Date: Mon Jun 15 06:38:50 2015 +0000 + + upstream commit + + turn SSH1 back on to match src/usr.bin/ssh being tested + + Upstream-Regress-ID: 6c4f763a2f0cc6893bf33983919e9030ae638333 + +commit b1dc2b33689668c75e95f873a42d5aea1f4af1db +Author: dtucker@openbsd.org +Date: Mon Jul 13 04:57:14 2015 +0000 + + upstream commit + + Add "PuTTY_Local:" to the clients to which we do not + offer DH-GEX. This was the string that was used for development versions + prior to September 2014 and they don't do RFC4419 DH-GEX, but unfortunately + there are some extant products based on those versions. bx2424 from Jay + Rouman, ok markus@ djm@ + + Upstream-ID: be34d41e18b966832fe09ca243d275b81882e1d5 + +commit 3a1638dda19bbc73d0ae02b4c251ce08e564b4b9 +Author: markus@openbsd.org +Date: Fri Jul 10 06:21:53 2015 +0000 + + upstream commit + + Turn off DSA by default; add HostKeyAlgorithms to the + server and PubkeyAcceptedKeyTypes to the client side, so it still can be + tested or turned back on; feedback and ok djm@ + + Upstream-ID: 8450a9e6d83f80c9bfed864ff061dfc9323cec21 + +commit 16db0a7ee9a87945cc594d13863cfcb86038db59 +Author: markus@openbsd.org +Date: Thu Jul 9 09:49:46 2015 +0000 + + upstream commit + + re-enable ed25519-certs if compiled w/o openssl; ok djm + + Upstream-ID: e10c90808b001fd2c7a93778418e9b318f5c4c49 + +commit c355bf306ac33de6545ce9dac22b84a194601e2f +Author: markus@openbsd.org +Date: Wed Jul 8 20:24:02 2015 +0000 + + upstream commit + + no need to include the old buffer/key API + + Upstream-ID: fb13c9f7c0bba2545f3eb0a0e69cb0030819f52b + +commit a3cc48cdf9853f1e832d78cb29bedfab7adce1ee +Author: markus@openbsd.org +Date: Wed Jul 8 19:09:25 2015 +0000 + + upstream commit + + typedefs for Cipher&CipherContext are unused + + Upstream-ID: 50e6a18ee92221d23ad173a96d5b6c42207cf9a7 + +commit a635bd06b5c427a57c3ae760d3a2730bb2c863c0 +Author: markus@openbsd.org +Date: Wed Jul 8 19:04:21 2015 +0000 + + upstream commit + + xmalloc.h is unused + + Upstream-ID: afb532355b7fa7135a60d944ca1e644d1d63cb58 + +commit 2521cf0e36c7f3f6b19f206da0af134f535e4a31 +Author: markus@openbsd.org +Date: Wed Jul 8 19:01:15 2015 +0000 + + upstream commit + + compress.c is gone + + Upstream-ID: 174fa7faa9b9643cba06164b5e498591356fbced + +commit c65a7aa6c43aa7a308ee1ab8a96f216169ae9615 +Author: djm@openbsd.org +Date: Fri Jul 3 04:05:54 2015 +0000 + + upstream commit + + another SSH_RSA_MINIMUM_MODULUS_SIZE that needed + cranking + + Upstream-ID: 9d8826cafe96aab4ae8e2f6fd22800874b7ffef1 + +commit b1f383da5cd3cb921fc7776f17a14f44b8a31757 +Author: djm@openbsd.org +Date: Fri Jul 3 03:56:25 2015 +0000 + + upstream commit + + add an XXX reminder for getting correct key paths from + sshd_config + + Upstream-ID: feae52b209d7782ad742df04a4260e9fe41741db + +commit 933935ce8d093996c34d7efa4d59113163080680 +Author: djm@openbsd.org +Date: Fri Jul 3 03:49:45 2015 +0000 + + upstream commit + + refuse to generate or accept RSA keys smaller than 1024 + bits; feedback and ok dtucker@ + + Upstream-ID: 7ea3d31271366ba264f06e34a3539bf1ac30f0ba + +commit bdfd29f60b74f3e678297269dc6247a5699583c1 +Author: djm@openbsd.org +Date: Fri Jul 3 03:47:00 2015 +0000 + + upstream commit + + turn off 1024 bit diffie-hellman-group1-sha1 key + exchange method (already off in server, this turns it off in the client by + default too) ok dtucker@ + + Upstream-ID: f59b88f449210ab7acf7d9d88f20f1daee97a4fa + +commit c28fc62d789d860c75e23a9fa9fb250eb2beca57 +Author: djm@openbsd.org +Date: Fri Jul 3 03:43:18 2015 +0000 + + upstream commit + + delete support for legacy v00 certificates; "sure" + markus@ dtucker@ + + Upstream-ID: b5b9bb5f9202d09e88f912989d74928601b6636f + +commit 564d63e1b4a9637a209d42a9d49646781fc9caef +Author: djm@openbsd.org +Date: Wed Jul 1 23:10:47 2015 +0000 + + upstream commit + + Compile-time disable SSH v.1 again + + Upstream-ID: 1d4b513a3a06232f02650b73bad25100d1b800af + +commit 868109b650504dd9bcccdb1f51d0906f967c20ff +Author: djm@openbsd.org +Date: Wed Jul 1 02:39:06 2015 +0000 + + upstream commit + + twiddle PermitRootLogin back + + Upstream-ID: 2bd23976305d0512e9f84d054e1fc23cd70b89f2 + +commit 7de4b03a6e4071d454b72927ffaf52949fa34545 +Author: djm@openbsd.org +Date: Wed Jul 1 02:32:17 2015 +0000 + + upstream commit + + twiddle; (this commit marks the openssh-6.9 release) + + Upstream-ID: 78500582819f61dd8adee36ec5cc9b9ac9351234 + +commit 1bf477d3cdf1a864646d59820878783d42357a1d +Author: djm@openbsd.org +Date: Wed Jul 1 02:26:31 2015 +0000 + + upstream commit + + better refuse ForwardX11Trusted=no connections attempted + after ForwardX11Timeout expires; reported by Jann Horn + + Upstream-ID: bf0fddadc1b46a0334e26c080038313b4b6dea21 + +commit 47aa7a0f8551b471fcae0447c1d78464f6dba869 +Author: djm@openbsd.org +Date: Wed Jul 1 01:56:13 2015 +0000 + + upstream commit + + put back default PermitRootLogin=no + + Upstream-ID: 7bdedd5cead99c57ed5571f3b6b7840922d5f728 + +commit 984b064fe2a23733733262f88d2e1b2a1a501662 +Author: djm@openbsd.org +Date: Wed Jul 1 01:55:13 2015 +0000 + + upstream commit + + openssh-6.9 + + Upstream-ID: 6cfe8e1904812531080e6ab6e752d7001b5b2d45 + +commit d921082ed670f516652eeba50705e1e9f6325346 +Author: djm@openbsd.org +Date: Wed Jul 1 01:55:00 2015 +0000 + + upstream commit + + reset default PermitRootLogin to 'yes' (momentarily, for + release) + + Upstream-ID: cad8513527066e65dd7a1c16363d6903e8cefa24 + +commit 66295e0e1ba860e527f191b6325d2d77dec4dbce +Author: Damien Miller +Date: Wed Jul 1 11:49:12 2015 +1000 + + crank version numbers for release + +commit 37035c07d4f26bb1fbe000d2acf78efdb008681d +Author: Damien Miller +Date: Wed Jul 1 10:49:37 2015 +1000 + + s/--with-ssh1/--without-ssh1/ + +commit 629df770dbadc2accfbe1c81b3f31f876d0acd84 +Author: djm@openbsd.org +Date: Tue Jun 30 05:25:07 2015 +0000 + + upstream commit + + fatal() when a remote window update causes the window + value to overflow. Reported by Georg Wicherski, ok markus@ + + Upstream-ID: ead397a9aceb3bf74ebfa5fcaf259d72e569f351 + +commit f715afebe735d61df3fd30ad72d9ac1c8bd3b5f2 +Author: djm@openbsd.org +Date: Tue Jun 30 05:23:25 2015 +0000 + + upstream commit + + Fix math error in remote window calculations that causes + eventual stalls for datagram channels. Reported by Georg Wicherski, ok + markus@ + + Upstream-ID: be54059d11bf64e0d85061f7257f53067842e2ab + +commit 52fb6b9b034fcfd24bf88cc7be313e9c31de9889 +Author: Damien Miller +Date: Tue Jun 30 16:05:40 2015 +1000 + + skip IPv6-related portions on hosts without IPv6 + + with Tim Rice + +commit 512caddf590857af6aa12218461b5c0441028cf5 +Author: djm@openbsd.org +Date: Mon Jun 29 22:35:12 2015 +0000 + + upstream commit + + add getpid to sandbox, reachable by grace_alarm_handler + + reported by Jakub Jelen; bz#2419 + + Upstream-ID: d0da1117c16d4c223954995d35b0f47c8f684cd8 + +commit 78c2a4f883ea9aba866358e2acd9793a7f42ca93 +Author: djm@openbsd.org +Date: Fri Jun 26 05:13:20 2015 +0000 + + upstream commit + + Fix \-escaping bug that caused forward path parsing to skip + two characters and skip past the end of the string. + + Based on patch by Salvador Fandino; ok dtucker@ + + Upstream-ID: 7b879dc446335677cbe4cb549495636a0535f3bd + +commit bc20205c91c9920361d12b15d253d4997dba494a +Author: Damien Miller +Date: Thu Jun 25 09:51:39 2015 +1000 + + add missing pselect6 + + patch from Jakub Jelen + +commit 9d27fb73b4a4e5e99cb880af790d5b1ce44f720a +Author: djm@openbsd.org +Date: Wed Jun 24 23:47:23 2015 +0000 + + upstream commit + + correct test to sshkey_sign(); spotted by Albert S. + + Upstream-ID: 5f7347f40f0ca6abdaca2edb3bd62f4776518933 + +commit 7ed01a96a1911d8b4a9ef4f3d064e1923bfad7e3 +Author: dtucker@openbsd.org +Date: Wed Jun 24 01:49:19 2015 +0000 + + upstream commit + + Revert previous commit. We still want to call setgroups + in the case where there are zero groups to remove any that we might otherwise + inherit (as pointed out by grawity at gmail.com) and since the 2nd argument + to setgroups is always a static global it's always valid to dereference in + this case. ok deraadt@ djm@ + + Upstream-ID: 895b5ac560a10befc6b82afa778641315725fd01 + +commit 882f8bf94f79528caa65b0ba71c185d705bb7195 +Author: dtucker@openbsd.org +Date: Wed Jun 24 01:49:19 2015 +0000 + + upstream commit + + Revert previous commit. We still want to call setgroups in + the case where there are zero groups to remove any that we might otherwise + inherit (as pointed out by grawity at gmail.com) and since the 2nd argument + to setgroups is always a static global it's always valid to dereference in + this case. ok deraadt@ djm@ + + Upstream-ID: 895b5ac560a10befc6b82afa778641315725fd01 + +commit 9488538a726951e82b3a4374f3c558d72c80a89b +Author: djm@openbsd.org +Date: Mon Jun 22 23:42:16 2015 +0000 + + upstream commit + + Don't count successful partial authentication as failures + in monitor; this may have caused the monitor to refuse multiple + authentications that would otherwise have successfully completed; ok markus@ + + Upstream-ID: eb74b8e506714d0f649bd5c300f762a527af04a3 + +commit 63b78d003bd8ca111a736e6cea6333da50f5f09b +Author: dtucker@openbsd.org +Date: Mon Jun 22 12:29:57 2015 +0000 + + upstream commit + + Don't call setgroups if we have zero groups; there's no + guarantee that it won't try to deref the pointer. Based on a patch from mail + at quitesimple.org, ok djm deraadt + + Upstream-ID: 2fff85e11d7a9a387ef7fddf41fbfaf566708ab1 + +commit 5c15e22c691c79a47747bcf5490126656f97cecd +Author: Damien Miller +Date: Thu Jun 18 15:07:56 2015 +1000 + + fix syntax error + +commit 596dbca82f3f567fb3d2d69af4b4e1d3ba1e6403 +Author: jsing@openbsd.org +Date: Mon Jun 15 18:44:22 2015 +0000 + + upstream commit + + If AuthorizedPrincipalsCommand is specified, however + AuthorizedPrincipalsFile is not (or is set to "none"), authentication will + potentially fail due to key_cert_check_authority() failing to locate a + principal that matches the username, even though an authorized principal has + already been matched in the output of the subprocess. Fix this by using the + same logic to determine if pw->pw_name should be passed, as is used to + determine if a authorized principal must be matched earlier on. + + ok djm@ + + Upstream-ID: 43b42302ec846b0ea68aceb40677245391b9409d + +commit aff3e94c0d75d0d0fa84ea392b50ab04f8c57905 +Author: jsing@openbsd.org +Date: Mon Jun 15 18:42:19 2015 +0000 + + upstream commit + + Make the arguments to match_principals_command() similar + to match_principals_file(), by changing the last argument a struct + sshkey_cert * and dereferencing key->cert in the caller. + + No functional change. + + ok djm@ + + Upstream-ID: 533f99b844b21b47342b32b62e198dfffcf8651c + +commit 97e2e1596c202a4693468378b16b2353fd2d6c5e +Author: Damien Miller +Date: Wed Jun 17 14:36:54 2015 +1000 + + trivial optimisation for seccomp-bpf + + When doing arg inspection and the syscall doesn't match, skip + past the instruction that reloads the syscall into the accumulator, + since the accumulator hasn't been modified at this point. + +commit 99f33d7304893bd9fa04d227cb6e870171cded19 +Author: Damien Miller +Date: Wed Jun 17 10:50:51 2015 +1000 + + aarch64 support for seccomp-bpf sandbox + + Also resort and tidy syscall list. Based on patches by Jakub Jelen + bz#2361; ok dtucker@ + +commit 4ef702e1244633c1025ec7cfe044b9ab267097bf +Author: djm@openbsd.org +Date: Mon Jun 15 01:32:50 2015 +0000 + + upstream commit + + return failure on RSA signature error; reported by Albert S + + Upstream-ID: e61bb93dbe0349625807b0810bc213a6822121fa + +commit a170f22baf18af0b1acf2788b8b715605f41a1f9 +Author: Tim Rice +Date: Tue Jun 9 22:41:13 2015 -0700 + + Fix t12 rules for out of tree builds. + +commit ec04dc4a5515c913121bc04ed261857e68fa5c18 +Author: millert@openbsd.org +Date: Fri Jun 5 15:13:13 2015 +0000 + + upstream commit + + For "ssh -L 12345:/tmp/sock" don't fail with "No forward host + name." (we have a path, not a host name). Based on a diff from Jared + Yanovich. OK djm@ + + Upstream-ID: 2846b0a8c7de037e33657f95afbd282837fc213f + +commit 732d61f417a6aea0aa5308b59cb0f563bcd6edd6 +Author: djm@openbsd.org +Date: Fri Jun 5 03:44:14 2015 +0000 + + upstream commit + + typo: accidental repetition; bz#2386 + + Upstream-ID: 45e620d99f6bc301e5949d34a54027374991c88b + +commit adfb24c69d1b6f5e758db200866c711e25a2ba73 +Author: Darren Tucker +Date: Fri Jun 5 14:51:40 2015 +1000 + + Add Linux powerpc64le and powerpcle entries. + + Stopgap to resolve bz#2409 because we are so close to release and will + update config.guess and friends shortly after the release. ok djm@ + +commit a1195a0fdc9eddddb04d3e9e44c4775431cb77da +Merge: 6397eed d2480bc +Author: Tim Rice +Date: Wed Jun 3 21:43:13 2015 -0700 + + Merge branch 'master' of git.mindrot.org:/var/git/openssh + +commit 6397eedf953b2b973d2d7cbb504ab501a07f8ddc +Author: Tim Rice +Date: Wed Jun 3 21:41:11 2015 -0700 + + Remove unneeded backslashes. Patch from Ángel González + +commit d2480bcac1caf31b03068de877a47d6e1027bf6d +Author: Darren Tucker +Date: Thu Jun 4 14:10:55 2015 +1000 + + Remove redundant include of stdarg.h. bz#2410 + +commit 5e67859a623826ccdf2df284cbb37e2d8e2787eb +Author: djm@openbsd.org +Date: Tue Jun 2 09:10:40 2015 +0000 + + upstream commit + + mention CheckHostIP adding addresses to known_hosts; + bz#1993; ok dtucker@ + + Upstream-ID: fd44b68440fd0dc29abf9f2d3f703d74a2396cb7 + +commit d7a58bbac6583e33fd5eca8e2c2cc70c57617818 +Author: Darren Tucker +Date: Tue Jun 2 20:15:26 2015 +1000 + + Replace strcpy with strlcpy. + + ok djm, sanity check by Corinna Vinschen. + +commit 51a1c2115265c6e80ede8a5c9dccada9aeed7143 +Author: Damien Miller +Date: Fri May 29 18:27:21 2015 +1000 + + skip, rather than fatal when run without SUDO set + +commit 599f01142a376645b15cbc9349d7e8975e1cf245 +Author: Damien Miller +Date: Fri May 29 18:03:15 2015 +1000 + + fix merge botch that left ",," in KEX algs + +commit 0c2a81dfc21822f2423edd30751e5ec53467b347 +Author: Damien Miller +Date: Fri May 29 17:08:28 2015 +1000 + + re-enable SSH protocol 1 at compile time + +commit db438f9285d64282d3ac9e8c0944f59f037c0151 +Author: djm@openbsd.org +Date: Fri May 29 03:05:13 2015 +0000 + + upstream commit + + make this work without SUDO set; ok dtucker@ + + Upstream-Regress-ID: bca88217b70bce2fe52b23b8e06bdeb82d98c715 + +commit 1d9a2e2849c9864fe75daabf433436341c968e14 +Author: djm@openbsd.org +Date: Thu May 28 07:37:31 2015 +0000 + + upstream commit + + wrap all moduli-related code in #ifdef WITH_OPENSSL. + based on patch from Reuben Hawkins; bz#2388 feedback and ok dtucker@ + + Upstream-ID: d80cfc8be3e6ec65b3fac9e87c4466533b31b7cf + +commit 496aeb25bc2d6c434171292e4714771b594bd00e +Author: dtucker@openbsd.org +Date: Thu May 28 05:41:29 2015 +0000 + + upstream commit + + Increase the allowed length of the known host file name + in the log message to be consistent with other cases. Part of bz#1993, ok + deraadt. + + Upstream-ID: a9e97567be49f25daf286721450968251ff78397 + +commit dd2cfeb586c646ff8d70eb93567b2e559ace5b14 +Author: dtucker@openbsd.org +Date: Thu May 28 05:09:45 2015 +0000 + + upstream commit + + Fix typo (keywork->keyword) + + Upstream-ID: 8aacd0f4089c0a244cf43417f4f9045dfaeab534 + +commit 9cc6842493fbf23025ccc1edab064869640d3bec +Author: djm@openbsd.org +Date: Thu May 28 04:50:53 2015 +0000 + + upstream commit + + add error message on ftruncate failure; bz#2176 + + Upstream-ID: cbcc606e0b748520c74a210d8f3cc9718d3148cf + +commit d1958793a0072c22be26d136dbda5ae263e717a0 +Author: djm@openbsd.org +Date: Thu May 28 04:40:13 2015 +0000 + + upstream commit + + make ssh-keygen default to ed25519 keys when compiled + without OpenSSL; bz#2388, ok dtucker@ + + Upstream-ID: 85a471fa6d3fa57a7b8e882d22cfbfc1d84cdc71 + +commit 3ecde664c9fc5fb3667aedf9e6671462600f6496 +Author: dtucker@openbsd.org +Date: Wed May 27 23:51:10 2015 +0000 + + upstream commit + + Reorder client proposal to prefer + diffie-hellman-group-exchange-sha1 over diffie-hellman-group14-sha1. ok djm@ + + Upstream-ID: 552c08d47347c3ee1a9a57d88441ab50abe17058 + +commit 40f64292b907afd0a674fdbf3e4c2356d17a7d68 +Author: dtucker@openbsd.org +Date: Wed May 27 23:39:18 2015 +0000 + + upstream commit + + Add a stronger (4k bit) fallback group that sshd can use + when the moduli file is missing or broken, sourced from RFC3526. bz#2302, ok + markus@ (earlier version), djm@ + + Upstream-ID: b635215746a25a829d117673d5e5a76d4baee7f4 + +commit 5ab7d5fa03ad55bc438fab45dfb3aeb30a3c237a +Author: Darren Tucker +Date: Thu May 28 10:03:40 2015 +1000 + + New moduli file from OpenBSD, removing 1k groups. + + Remove 1k bit groups. ok deraadt@, markus@ + +commit a71ba58adf34e599f30cdda6e9b93ae6e3937eea +Author: djm@openbsd.org +Date: Wed May 27 05:15:02 2015 +0000 + + upstream commit + + support PKCS#11 devices with external PIN entry devices + bz#2240, based on patch from Dirk-Willem van Gulik; feedback and ok dtucker@ + + Upstream-ID: 504568992b55a8fc984375242b1bd505ced61b0d + +commit b282fec1aa05246ed3482270eb70fc3ec5f39a00 +Author: dtucker@openbsd.org +Date: Tue May 26 23:23:40 2015 +0000 + + upstream commit + + Cap DH-GEX group size at 4kbits for Cisco implementations. + Some of them will choke when asked for preferred sizes >4k instead of + returning the 4k group that they do have. bz#2209, ok djm@ + + Upstream-ID: 54b863a19713446b7431f9d06ad0532b4fcfef8d + +commit 3e91b4e8b0dc2b4b7e7d42cf6e8994a32e4cb55e +Author: djm@openbsd.org +Date: Sun May 24 23:39:16 2015 +0000 + + upstream commit + + add missing 'c' option to getopt(), case statement was + already there; from Felix Bolte + + Upstream-ID: 9b19b4e2e0b54d6fefa0dfac707c51cf4bae3081 + +commit 64a89ec07660abba4d0da7c0095b7371c98bab62 +Author: jsg@openbsd.org +Date: Sat May 23 14:28:37 2015 +0000 + + upstream commit + + fix a memory leak in an error path ok markus@ dtucker@ + + Upstream-ID: bc1da0f205494944918533d8780fde65dff6c598 + +commit f948737449257d2cb83ffcfe7275eb79b677fd4a +Author: djm@openbsd.org +Date: Fri May 22 05:28:45 2015 +0000 + + upstream commit + + mention ssh-keygen -E for comparing legacy MD5 + fingerprints; bz#2332 + + Upstream-ID: 079a3669549041dbf10dbc072d9563f0dc3b2859 + +commit 0882332616e4f0272c31cc47bf2018f9cb258a4e +Author: djm@openbsd.org +Date: Fri May 22 04:45:52 2015 +0000 + + upstream commit + + Reorder EscapeChar option parsing to avoid a single-byte + out- of-bounds read. bz#2396 from Jaak Ristioja; ok dtucker@ + + Upstream-ID: 1dc6b5b63d1c8d9a88619da0b27ade461d79b060 + +commit d7c31da4d42c115843edee2074d7d501f8804420 +Author: djm@openbsd.org +Date: Fri May 22 03:50:02 2015 +0000 + + upstream commit + + add knob to relax GSSAPI host credential check for + multihomed hosts bz#928, patch by Simon Wilkinson; ok dtucker + (kerberos/GSSAPI is not compiled by default on OpenBSD) + + Upstream-ID: 15ddf1c6f7fd9d98eea9962f480079ae3637285d + +commit aa72196a00be6e0b666215edcffbc10af234cb0e +Author: Darren Tucker +Date: Fri May 22 17:49:46 2015 +1000 + + Include signal.h for sig_atomic_t, used by kex.h. + + bz#2402, from tomas.kuthan at oracle com. + +commit 8b02481143d75e91c49d1bfae0876ac1fbf9511a +Author: Darren Tucker +Date: Fri May 22 12:47:24 2015 +1000 + + Import updated moduli file from OpenBSD. + +commit 4739e8d5e1c0be49624082bd9f6b077e9e758db9 +Author: djm@openbsd.org +Date: Thu May 21 12:01:19 2015 +0000 + + upstream commit + + Support "ssh-keygen -lF hostname" to find search known_hosts + and print key hashes. Already advertised by ssh-keygen(1), but not delivered + by code; ok dtucker@ + + Upstream-ID: 459e0e2bf39825e41b0811c336db2d56a1c23387 + +commit e97201feca10b5196da35819ae516d0b87cf3a50 +Author: Damien Miller +Date: Thu May 21 17:55:15 2015 +1000 + + conditionalise util.h inclusion + +commit 13640798c7dd011ece0a7d02841fe48e94cfa0e0 +Author: djm@openbsd.org +Date: Thu May 21 06:44:25 2015 +0000 + + upstream commit + + regress test for AuthorizedPrincipalsCommand + + Upstream-Regress-ID: c658fbf1ab6b6011dc83b73402322e396f1e1219 + +commit 84452c5d03c21f9bfb28c234e0dc1dc67dd817b1 +Author: djm@openbsd.org +Date: Thu May 21 06:40:02 2015 +0000 + + upstream commit + + regress test for AuthorizedKeysCommand arguments + + Upstream-Regress-ID: bbd65c13c6b3be9a442ec115800bff9625898f12 + +commit bcc50d816187fa9a03907ac1f3a52f04a52e10d1 +Author: djm@openbsd.org +Date: Thu May 21 06:43:30 2015 +0000 + + upstream commit + + add AuthorizedPrincipalsCommand that allows getting + authorized_principals from a subprocess rather than a file, which is quite + useful in deployments with large userbases + + feedback and ok markus@ + + Upstream-ID: aa1bdac7b16fc6d2fa3524ef08f04c7258d247f6 + +commit 24232a3e5ab467678a86aa67968bbb915caffed4 +Author: djm@openbsd.org +Date: Thu May 21 06:38:35 2015 +0000 + + upstream commit + + support arguments to AuthorizedKeysCommand + + bz#2081 loosely based on patch by Sami Hartikainen + feedback and ok markus@ + + Upstream-ID: b080387a14aa67dddd8ece67c00f268d626541f7 + +commit d80fbe41a57c72420c87a628444da16d09d66ca7 +Author: djm@openbsd.org +Date: Thu May 21 04:55:51 2015 +0000 + + upstream commit + + refactor: split base64 encoding of pubkey into its own + sshkey_to_base64() function and out of sshkey_write(); ok markus@ + + Upstream-ID: 54fc38f5832e9b91028900819bda46c3959a0c1a + +commit 7cc44ef74133a473734bbcbd3484f24d6a7328c5 +Author: deraadt@openbsd.org +Date: Mon May 18 15:06:05 2015 +0000 + + upstream commit + + getentropy() and sendsyslog() have been around long + enough. openssh-portable may want the #ifdef's but not base. discussed with + djm few weeks back + + Upstream-ID: 0506a4334de108e3fb6c66f8d6e0f9c112866926 + +commit 9173d0fbe44de7ebcad8a15618e13a8b8d78902e +Author: dtucker@openbsd.org +Date: Fri May 15 05:44:21 2015 +0000 + + upstream commit + + Use a salted hash of the lock passphrase instead of plain + text and do constant-time comparisons of it. Should prevent leaking any + information about it via timing, pointed out by Ryan Castellucci. Add a 0.1s + incrementing delay for each failed unlock attempt up to 10s. ok markus@ + (earlier version), djm@ + + Upstream-ID: c599fcc325aa1cc65496b25220b622d22208c85f + +commit d028d5d3a697c71b21e4066d8672cacab3caa0a8 +Author: Damien Miller +Date: Tue May 5 19:10:58 2015 +1000 + + upstream commit + + - tedu@cvs.openbsd.org 2015/01/12 03:20:04 + [bcrypt_pbkdf.c] + rename blocks to words. bcrypt "blocks" are unrelated to blowfish blocks, + nor are they the same size. + +commit f6391d4e59b058984163ab28f4e317e7a72478f1 +Author: Damien Miller +Date: Tue May 5 19:10:23 2015 +1000 + + upstream commit + + - deraadt@cvs.openbsd.org 2015/01/08 00:30:07 + [bcrypt_pbkdf.c] + declare a local version of MIN(), call it MINIMUM() + +commit 8ac6b13cc9113eb47cd9e86c97d7b26b4b71b77f +Author: Damien Miller +Date: Tue May 5 19:09:46 2015 +1000 + + upstream commit + + - djm@cvs.openbsd.org 2014/12/30 01:41:43 + [bcrypt_pbkdf.c] + typo in comment: ouput => output + +commit 1f792489d5cf86a4f4e3003e6e9177654033f0f2 +Author: djm@openbsd.org +Date: Mon May 4 06:10:48 2015 +0000 + + upstream commit + + Remove pattern length argument from match_pattern_list(), we + only ever use it for strlen(pattern). + + Prompted by hanno AT hboeck.de pointing an out-of-bound read + error caused by an incorrect pattern length found using AFL + and his own tools. + + ok markus@ + +commit 639d6bc57b1942393ed12fb48f00bc05d4e093e4 +Author: djm@openbsd.org +Date: Fri May 1 07:10:01 2015 +0000 + + upstream commit + + refactor ssh_dispatch_run_fatal() to use sshpkt_fatal() + to better report error conditions. Teach sshpkt_fatal() about ECONNRESET. + + Improves error messages on TCP connection resets. bz#2257 + + ok dtucker@ + +commit 9559d7de34c572d4d3fd990ca211f8ec99f62c4d +Author: djm@openbsd.org +Date: Fri May 1 07:08:08 2015 +0000 + + upstream commit + + a couple of parse targets were missing activep checks, + causing them to be misapplied in match context; bz#2272 diagnosis and + original patch from Sami Hartikainen ok dtucker@ + +commit 7e8528cad04b2775c3b7db08abf8fb42e47e6b2a +Author: djm@openbsd.org +Date: Fri May 1 04:17:51 2015 +0000 + + upstream commit + + make handling of AuthorizedPrincipalsFile=none more + consistent with other =none options; bz#2288 from Jakub Jelen; ok dtucker@ + +commit ca430d4d9cc0f62eca3b1fb1e2928395b7ce80f7 +Author: djm@openbsd.org +Date: Fri May 1 04:03:20 2015 +0000 + + upstream commit + + remove failed remote forwards established by muliplexing + from the list of active forwards; bz#2363, patch mostly by Yoann Ricordel; ok + dtucker@ + +commit 8312cfb8ad88657517b3e23ac8c56c8e38eb9792 +Author: djm@openbsd.org +Date: Fri May 1 04:01:58 2015 +0000 + + upstream commit + + reduce stderr spam when using ssh -S /path/mux -O forward + -R 0:... ok dtucker@ + +commit 179be0f5e62f1f492462571944e45a3da660d82b +Author: djm@openbsd.org +Date: Fri May 1 03:23:51 2015 +0000 + + upstream commit + + prevent authorized_keys options picked up on public key + tests without a corresponding private key authentication being applied to + other authentication methods. Reported by halex@, ok markus@ + +commit a42d67be65b719a430b7fcaba2a4e4118382723a +Author: djm@openbsd.org +Date: Fri May 1 03:20:54 2015 +0000 + + upstream commit + + Don't make parsing of authorized_keys' environment= + option conditional on PermitUserEnv - always parse it, but only use the + result if the option is enabled. This prevents the syntax of authorized_keys + changing depending on which sshd_config options were enabled. + + bz#2329; based on patch from coladict AT gmail.com, ok dtucker@ + +commit e661a86353e11592c7ed6a847e19a83609f49e77 +Author: djm@openbsd.org +Date: Mon May 4 06:10:48 2015 +0000 + + upstream commit + + Remove pattern length argument from match_pattern_list(), we + only ever use it for strlen(pattern). + + Prompted by hanno AT hboeck.de pointing an out-of-bound read + error caused by an incorrect pattern length found using AFL + and his own tools. + + ok markus@ + +commit 0ef1de742be2ee4b10381193fe90730925b7f027 +Author: dtucker@openbsd.org +Date: Thu Apr 23 05:01:19 2015 +0000 + + upstream commit + + Add a simple regression test for sshd's configuration + parser. Right now, all it does is run the output of sshd -T back through + itself and ensure the output is valid and invariant. + +commit 368f83c793275faa2c52f60eaa9bdac155c4254b +Author: djm@openbsd.org +Date: Wed Apr 22 01:38:36 2015 +0000 + + upstream commit + + use correct key for nested certificate test + +commit 8d4d1bfddbbd7d21f545dc6997081d1ea1fbc99a +Author: djm@openbsd.org +Date: Fri May 1 07:11:47 2015 +0000 + + upstream commit + + mention that the user's shell from /etc/passwd is used + for commands too; bz#1459 ok dtucker@ + +commit 5ab283d0016bbc9d4d71e8e5284d011bc5a930cf +Author: djm@openbsd.org +Date: Fri May 8 07:29:00 2015 +0000 + + upstream commit + + whitespace + + Upstream-Regress-ID: 6b708a3e709d5b7fd37890f874bafdff1f597519 + +commit 8377d5008ad260048192e1e56ad7d15a56d103dd +Author: djm@openbsd.org +Date: Fri May 8 07:26:13 2015 +0000 + + upstream commit + + whitespace at EOL + + Upstream-Regress-ID: 9c48911643d5b05173b36a012041bed4080b8554 + +commit c28a3436fa8737709ea88e4437f8f23a6ab50359 +Author: djm@openbsd.org +Date: Fri May 8 06:45:13 2015 +0000 + + upstream commit + + moar whitespace at eol + + Upstream-ID: 64eaf872a3ba52ed41e494287e80d40aaba4b515 + +commit 2b64c490468fd4ca35ac8d5cc31c0520dc1508bb +Author: djm@openbsd.org +Date: Fri May 8 06:41:56 2015 +0000 + + upstream commit + + whitespace at EOL + + Upstream-ID: 57bcf67d666c6fc1ad798aee448fdc3f70f7ec2c + +commit 4e636cf201ce6e7e3b9088568218f9d4e2c51712 +Author: djm@openbsd.org +Date: Fri May 8 03:56:51 2015 +0000 + + upstream commit + + whitespace at EOL + +commit 38b8272f823dc1dd4e29dbcee83943ed48bb12fa +Author: dtucker@openbsd.org +Date: Mon May 4 01:47:53 2015 +0000 + + upstream commit + + Use diff w/out -u for better portability + +commit 297060f42d5189a4065ea1b6f0afdf6371fb0507 +Author: dtucker@openbsd.org +Date: Fri May 8 03:25:07 2015 +0000 + + upstream commit + + Use xcalloc for permitted_adm_opens instead of xmalloc to + ensure it's zeroed. Fixes post-auth crash with permitopen=none. bz#2355, ok + djm@ + +commit 63ebf019be863b2d90492a85e248cf55a6e87403 +Author: djm@openbsd.org +Date: Fri May 8 03:17:49 2015 +0000 + + upstream commit + + don't choke on new-format private keys encrypted with an + AEAD cipher; bz#2366, patch from Ron Frederick; ok markus@ + +commit f8484dac678ab3098ae522a5f03bb2530f822987 +Author: dtucker@openbsd.org +Date: Wed May 6 05:45:17 2015 +0000 + + upstream commit + + Clarify pseudo-terminal request behaviour and use + "pseudo-terminal" consistently. bz#1716, ok jmc@ "I like it" deraadt@. + +commit ea139507bef8bad26e86ed99a42c7233ad115c38 +Author: dtucker@openbsd.org +Date: Wed May 6 04:07:18 2015 +0000 + + upstream commit + + Blacklist DH-GEX for specific PuTTY versions known to + send non-RFC4419 DH-GEX messages rather than all versions of PuTTY. + According to Simon Tatham, 0.65 and newer versions will send RFC4419 DH-GEX + messages. ok djm@ + +commit b58234f00ee3872eb84f6e9e572a9a34e902e36e +Author: dtucker@openbsd.org +Date: Tue May 5 10:17:49 2015 +0000 + + upstream commit + + WinSCP doesn't implement RFC4419 DH-GEX so flag it so we + don't offer that KEX method. ok markus@ + +commit d5b1507a207253b39e810e91e68f9598691b7a29 +Author: jsg@openbsd.org +Date: Tue May 5 02:48:17 2015 +0000 + + upstream commit + + use the sizeof the struct not the sizeof a pointer to the + struct in ssh_digest_start() + + This file is only used if ssh is built with OPENSSL=no + + ok markus@ + +commit a647b9b8e616c231594b2710c925d31b1b8afea3 +Author: Darren Tucker +Date: Fri May 8 11:07:27 2015 +1000 + + Put brackets around mblen() compat constant. + + This might help with the reported problem cross compiling for Android + ("error: expected identifier or '(' before numeric constant") but + shouldn't hurt in any case. + +commit d1680d36e17244d9af3843aeb5025cb8e40d6c07 +Author: Darren Tucker +Date: Thu Apr 30 09:18:11 2015 +1000 + + xrealloc -> xreallocarray in portable code too. + +commit 531a57a3893f9fcd4aaaba8c312b612bbbcc021e +Author: dtucker@openbsd.org +Date: Wed Apr 29 03:48:56 2015 +0000 + + upstream commit + + Allow ListenAddress, Port and AddressFamily in any + order. bz#68, ok djm@, jmc@ (for the man page bit). + +commit c1d5bcf1aaf1209af02f79e48ba1cbc76a87b56f +Author: jmc@openbsd.org +Date: Tue Apr 28 13:47:38 2015 +0000 + + upstream commit + + enviroment -> environment: apologies to darren for not + spotting that first time round... + +commit 43beea053db191cac47c2cd8d3dc1930158aff1a +Author: dtucker@openbsd.org +Date: Tue Apr 28 10:25:15 2015 +0000 + + upstream commit + + Fix typo in previous + +commit 85b96ef41374f3ddc9139581f87da09b2cd9199e +Author: dtucker@openbsd.org +Date: Tue Apr 28 10:17:58 2015 +0000 + + upstream commit + + Document that the TERM environment variable is not + subject to SendEnv and AcceptEnv. bz#2386, based loosely on a patch from + jjelen at redhat, help and ok jmc@ + +commit 88a7c598a94ff53f76df228eeaae238d2d467565 +Author: djm@openbsd.org +Date: Mon Apr 27 21:42:48 2015 +0000 + + upstream commit + + Make sshd default to PermitRootLogin=no; ok deraadt@ + rpe@ + +commit 734226b4480a6c736096c729fcf6f391400599c7 +Author: djm@openbsd.org +Date: Mon Apr 27 01:52:30 2015 +0000 + + upstream commit + + fix compilation with OPENSSL=no; ok dtucker@ + +commit a4b9d2ce1eb7703eaf0809b0c8a82ded8aa4f1c6 +Author: dtucker@openbsd.org +Date: Mon Apr 27 00:37:53 2015 +0000 + + upstream commit + + Include stdio.h for FILE (used in sshkey.h) so it + compiles with OPENSSL=no. + +commit dbcc652f4ca11fe04e5930c7ef18a219318c6cda +Author: djm@openbsd.org +Date: Mon Apr 27 00:21:21 2015 +0000 + + upstream commit + + allow "sshd -f none" to skip reading the config file, + much like "ssh -F none" does. ok dtucker + +commit b7ca276fca316c952f0b90f5adb1448c8481eedc +Author: jmc@openbsd.org +Date: Fri Apr 24 06:26:49 2015 +0000 + + upstream commit + + combine -Dd onto one line and update usage(); + +commit 2ea974630d7017e4c7666d14d9dc939707613e96 +Author: djm@openbsd.org +Date: Fri Apr 24 05:26:44 2015 +0000 + + upstream commit + + add ssh-agent -D to leave ssh-agent in foreground + without enabling debug mode; bz#2381 ok dtucker@ + +commit 8ac2ffd7aa06042f6b924c87139f2fea5c5682f7 +Author: deraadt@openbsd.org +Date: Fri Apr 24 01:36:24 2015 +0000 + + upstream commit + + 2*len -> use xreallocarray() ok djm + +commit 657a5fbc0d0aff309079ff8fb386f17e964963c2 +Author: deraadt@openbsd.org +Date: Fri Apr 24 01:36:00 2015 +0000 + + upstream commit + + rename xrealloc() to xreallocarray() since it follows + that form. ok djm + +commit 1108ae242fdd2c304307b68ddf46aebe43ebffaa +Author: dtucker@openbsd.org +Date: Thu Apr 23 04:59:10 2015 +0000 + + upstream commit + + Two small fixes for sshd -T: ListenAddress'es are added + to a list head so reverse the order when printing them to ensure the + behaviour remains the same, and print StreamLocalBindMask as octal with + leading zero. ok deraadt@ + +commit bd902b8473e1168f19378d5d0ae68d0c203525df +Author: dtucker@openbsd.org +Date: Thu Apr 23 04:53:53 2015 +0000 + + upstream commit + + Check for and reject missing arguments for + VersionAddendum and ForceCommand. bz#2281, patch from plautrba at redhat com, + ok djm@ + +commit ca42c1758575e592239de1d5755140e054b91a0d +Author: djm@openbsd.org +Date: Wed Apr 22 01:24:01 2015 +0000 + + upstream commit + + unknown certificate extensions are non-fatal, so don't + fatal when they are encountered; bz#2387 reported by Bob Van Zant; ok + dtucker@ + +commit 39bfbf7caad231cc4bda6909fb1af0705bca04d8 +Author: jsg@openbsd.org +Date: Tue Apr 21 07:01:00 2015 +0000 + + upstream commit + + Add back a backslash removed in rev 1.42 so + KEX_SERVER_ENCRYPT will include aes again. + + ok deraadt@ + +commit 6b0d576bb87eca3efd2b309fcfe4edfefc289f9c +Author: djm@openbsd.org +Date: Fri Apr 17 13:32:09 2015 +0000 + + upstream commit + + s/recommended/required/ that private keys be og-r this + wording change was made a while ago but got accidentally reverted + +commit 44a8e7ce6f3ab4c2eb1ae49115c210b98e53c4df +Author: djm@openbsd.org +Date: Fri Apr 17 13:25:52 2015 +0000 + + upstream commit + + don't try to cleanup NULL KEX proposals in + kex_prop_free(); found by Jukka Taimisto and Markus Hietava + +commit 3038a191872d2882052306098c1810d14835e704 +Author: djm@openbsd.org +Date: Fri Apr 17 13:19:22 2015 +0000 + + upstream commit + + use error/logit/fatal instead of fprintf(stderr, ...) + and exit(0), fix a few errors that were being printed to stdout instead of + stderr and a few non-errors that were going to stderr instead of stdout + bz#2325; ok dtucker + +commit a58be33cb6cd24441fa7e634db0e5babdd56f07f +Author: djm@openbsd.org +Date: Fri Apr 17 13:16:48 2015 +0000 + + upstream commit + + debug log missing DISPLAY environment when X11 + forwarding requested; bz#1682 ok dtucker@ + +commit 17d4d9d9fbc8fb80e322f94d95eecc604588a474 +Author: djm@openbsd.org +Date: Fri Apr 17 04:32:31 2015 +0000 + + upstream commit + + don't call record_login() in monitor when UseLogin is + enabled; bz#278 reported by drk AT sgi.com; ok dtucker + +commit 40132ff87b6cbc3dc05fb5df2e9d8e3afa06aafd +Author: dtucker@openbsd.org +Date: Fri Apr 17 04:12:35 2015 +0000 + + upstream commit + + Add some missing options to sshd -T and fix the output + of VersionAddendum HostCertificate. bz#2346, patch from jjelen at redhat + com, ok djm. + +commit 6cc7cfa936afde2d829e56ee6528c7ea47a42441 +Author: dtucker@openbsd.org +Date: Thu Apr 16 23:25:50 2015 +0000 + + upstream commit + + Document "none" for PidFile XAuthLocation + TrustedUserCAKeys and RevokedKeys. bz#2382, feedback from jmc@, ok djm@ + +commit 15fdfc9b1c6808b26bc54d4d61a38b54541763ed +Author: dtucker@openbsd.org +Date: Wed Apr 15 23:23:25 2015 +0000 + + upstream commit + + Plug leak of address passed to logging. bz#2373, patch + from jjelen at redhat, ok markus@ + +commit bb2289e2a47d465eaaaeff3dee2a6b7777b4c291 +Author: dtucker@openbsd.org +Date: Tue Apr 14 04:17:03 2015 +0000 + + upstream commit + + Output remote username in debug output since with Host + and Match it's not always obvious what it will be. bz#2368, ok djm@ + +commit 70860b6d07461906730632f9758ff1b7c98c695a +Author: Darren Tucker +Date: Fri Apr 17 10:56:13 2015 +1000 + + Format UsePAM setting when using sshd -T. + + Part of bz#2346, patch from jjelen at redhat com. + +commit ee15d9c9f0720f5a8b0b34e4b10ecf21f9824814 +Author: Darren Tucker +Date: Fri Apr 17 10:40:23 2015 +1000 + + Wrap endian.h include inside ifdef (bz#2370). + +commit 408f4c2ad4a4c41baa7b9b2b7423d875abbfa70b +Author: Darren Tucker +Date: Fri Apr 17 09:39:58 2015 +1000 + + Look for '${host}-ar' before 'ar'. + + This changes configure.ac to look for '${host}-ar' as set by + AC_CANONICAL_HOST before looking for the unprefixed 'ar'. + Useful when cross-compiling when all your binutils are prefixed. + + Patch from moben at exherbo org via astrand at lysator liu se and + bz#2352. + +commit 673a1c16ad078d41558247ce739fe812c960acc8 +Author: Damien Miller +Date: Thu Apr 16 11:40:20 2015 +1000 + + remove dependency on arpa/telnet.h + +commit 202d443eeda1829d336595a3cfc07827e49f45ed +Author: Darren Tucker +Date: Wed Apr 15 15:59:49 2015 +1000 + + Remove duplicate include of pwd.h. bz#2337, patch from Mordy Ovits. + +commit 597986493412c499f2bc2209420cb195f97b3668 +Author: Damien Miller +Date: Thu Apr 9 10:14:48 2015 +1000 + + platform's with openpty don't need pty_release + +commit 318be28cda1fd9108f2e6f2f86b0b7589ba2aed0 +Author: djm@openbsd.org +Date: Mon Apr 13 02:04:08 2015 +0000 + + upstream commit + + deprecate ancient, pre-RFC4419 and undocumented + SSH2_MSG_KEX_DH_GEX_REQUEST_OLD message; ok markus@ deraadt@ "seems + reasonable" dtucker@ + +commit d8f391caef62378463a0e6b36f940170dadfe605 +Author: dtucker@openbsd.org +Date: Fri Apr 10 05:16:50 2015 +0000 + + upstream commit + + Don't send hostkey advertisments + (hostkeys-00@openssh.com) to current versions of Tera Term as they can't + handle them. Newer versions should be OK. Patch from Bryan Drewery and + IWAMOTO Kouichi, ok djm@ + +commit 2c2cfe1a1c97eb9a08cc9817fd0678209680c636 +Author: djm@openbsd.org +Date: Fri Apr 10 00:08:55 2015 +0000 + + upstream commit + + include port number if a non-default one has been + specified; based on patch from Michael Handler + +commit 4492a4f222da4cf1e8eab12689196322e27b08c4 +Author: djm@openbsd.org +Date: Tue Apr 7 23:00:42 2015 +0000 + + upstream commit + + treat Protocol=1,2|2,1 as Protocol=2 when compiled + without SSH1 support; ok dtucker@ millert@ + +commit c265e2e6e932efc6d86f6cc885dea33637a67564 +Author: miod@openbsd.org +Date: Sun Apr 5 15:43:43 2015 +0000 + + upstream commit + + Do not use int for sig_atomic_t; spotted by + christos@netbsd; ok markus@ + +commit e7bf3a5eda6a1b02bef6096fed78527ee11e54cc +Author: Darren Tucker +Date: Tue Apr 7 10:48:04 2015 +1000 + + Use do{}while(0) for no-op functions. + + From FreeBSD. + +commit bb99844abae2b6447272f79e7fa84134802eb4df +Author: Darren Tucker +Date: Tue Apr 7 10:47:15 2015 +1000 + + Wrap blf.h include in ifdef. From FreeBSD. + +commit d9b9b43656091cf0ad55c122f08fadb07dad0abd +Author: Darren Tucker +Date: Tue Apr 7 09:10:00 2015 +1000 + + Fix misspellings of regress CONFOPTS env variables. + + Patch from Bryan Drewery. + +commit 3f4ea3c9ab1d32d43c9222c4351f58ca11144156 +Author: djm@openbsd.org +Date: Fri Apr 3 22:17:27 2015 +0000 + + upstream commit + + correct return value in pubkey parsing, spotted by Ben Hawkes + ok markus@ + +commit 7da2be0cb9601ed25460c83aa4d44052b967ba0f +Author: djm@openbsd.org +Date: Tue Mar 31 22:59:01 2015 +0000 + + upstream commit + + adapt to recent hostfile.c change: when parsing + known_hosts without fully parsing the keys therein, hostkeys_foreach() will + now correctly identify KEY_RSA1 keys; ok markus@ miod@ + +commit 9e1777a0d1c706714b055811c12ab8cc21033e4a +Author: markus@openbsd.org +Date: Tue Mar 24 20:19:15 2015 +0000 + + upstream commit + + use ${SSH} for -Q instead of installed ssh + +commit ce1b358ea414a2cc88e4430cd5a2ea7fecd9de57 +Author: djm@openbsd.org +Date: Mon Mar 16 22:46:14 2015 +0000 + + upstream commit + + make CLEANFILES clean up more of the tests' droppings + +commit 398f9ef192d820b67beba01ec234d66faca65775 +Author: djm@openbsd.org +Date: Tue Mar 31 22:57:06 2015 +0000 + + upstream commit + + downgrade error() for known_hosts parse errors to debug() + to quiet warnings from ssh1 keys present when compiled !ssh1. + + also identify ssh1 keys when scanning, even when compiled !ssh1 + + ok markus@ miod@ + +commit 9a47ab80030a31f2d122b8fd95bd48c408b9fcd9 +Author: djm@openbsd.org +Date: Tue Mar 31 22:55:50 2015 +0000 + + upstream commit + + fd leak for !ssh1 case; found by unittests; ok markus@ + +commit c9a0805a6280681901c270755a7cd630d7c5280e +Author: djm@openbsd.org +Date: Tue Mar 31 22:55:24 2015 +0000 + + upstream commit + + don't fatal when a !ssh1 sshd is reexeced from a w/ssh1 + listener; reported by miod@; ok miod@ markus@ + +commit 704d8c88988cae38fb755a6243b119731d223222 +Author: tobias@openbsd.org +Date: Tue Mar 31 11:06:49 2015 +0000 + + upstream commit + + Comments are only supported for RSA1 keys. If a user + tried to add one and entered his passphrase, explicitly clear it before exit. + This is done in all other error paths, too. + + ok djm + +commit 78de1673c05ea2c33e0d4a4b64ecb5186b6ea2e9 +Author: jmc@openbsd.org +Date: Mon Mar 30 18:28:37 2015 +0000 + + upstream commit + + ssh-askpass(1) is the default, overridden by SSH_ASKPASS; + diff originally from jiri b; + +commit 26e0bcf766fadb4a44fb6199386fb1dcab65ad00 +Author: djm@openbsd.org +Date: Mon Mar 30 00:00:29 2015 +0000 + + upstream commit + + fix uninitialised memory read when parsing a config file + consisting of a single nul byte. Found by hanno AT hboeck.de using AFL; ok + dtucker + +commit fecede00a76fbb33a349f5121c0b2f9fbc04a777 +Author: markus@openbsd.org +Date: Thu Mar 26 19:32:19 2015 +0000 + + upstream commit + + sigp and lenp are not optional in ssh_agent_sign(); ok + djm@ + +commit 1b0ef3813244c78669e6d4d54c624f600945327d +Author: naddy@openbsd.org +Date: Thu Mar 26 12:32:38 2015 +0000 + + upstream commit + + don't try to load .ssh/identity by default if SSH1 is + disabled; ok markus@ + +commit f9b78852379b74a2d14e6fc94fe52af30b7e9c31 +Author: djm@openbsd.org +Date: Thu Mar 26 07:00:04 2015 +0000 + + upstream commit + + ban all-zero curve25519 keys as recommended by latest + CFRG curves draft; ok markus + +commit b8afbe2c1aaf573565e4da775261dfafc8b1ba9c +Author: djm@openbsd.org +Date: Thu Mar 26 06:59:28 2015 +0000 + + upstream commit + + relax bits needed check to allow + diffie-hellman-group1-sha1 key exchange to complete for chacha20-poly1305 was + selected as symmetric cipher; ok markus + +commit 47842f71e31da130555353c1d57a1e5a8937f1c0 +Author: markus@openbsd.org +Date: Wed Mar 25 19:29:58 2015 +0000 + + upstream commit + + ignore v1 errors on ssh-add -D; only try v2 keys on + -l/-L (unless WITH_SSH1) ok djm@ + +commit 5f57e77f91bf2230c09eca96eb5ecec39e5f2da6 +Author: markus@openbsd.org +Date: Wed Mar 25 19:21:48 2015 +0000 + + upstream commit + + unbreak ssh_agent_sign (lenp vs *lenp) + +commit 4daeb67181054f2a377677fac919ee8f9ed3490e +Author: markus@openbsd.org +Date: Tue Mar 24 20:10:08 2015 +0000 + + upstream commit + + don't leak 'setp' on error; noted by Nicholas Lemonias; + ok djm@ + +commit 7d4f96f9de2a18af0d9fa75ea89a4990de0344f5 +Author: markus@openbsd.org +Date: Tue Mar 24 20:09:11 2015 +0000 + + upstream commit + + consistent check for NULL as noted by Nicholas + Lemonias; ok djm@ + +commit df100be51354e447d9345cf1ec22e6013c0eed50 +Author: markus@openbsd.org +Date: Tue Mar 24 20:03:44 2015 +0000 + + upstream commit + + correct fmt-string for size_t as noted by Nicholas + Lemonias; ok djm@ + +commit a22b9ef21285e81775732436f7c84a27bd3f71e0 +Author: djm@openbsd.org +Date: Tue Mar 24 09:17:21 2015 +0000 + + upstream commit + + promote chacha20-poly1305@openssh.com to be the default + cipher; ok markus + +commit 2aa9da1a3b360cf7b13e96fe1521534b91501fb5 +Author: djm@openbsd.org +Date: Tue Mar 24 01:29:19 2015 +0000 + + upstream commit + + Compile-time disable SSH protocol 1. You can turn it + back on using the Makefile.inc knob if you need it to talk to ancient + devices. + +commit 53097b2022154edf96b4e8526af5666f979503f7 +Author: djm@openbsd.org +Date: Tue Mar 24 01:11:12 2015 +0000 + + upstream commit + + fix double-negative error message "ssh1 is not + unsupported" + +commit 5c27e3b6ec2db711dfcd40e6359c0bcdd0b62ea9 +Author: djm@openbsd.org +Date: Mon Mar 23 06:06:38 2015 +0000 + + upstream commit + + for ssh-keygen -A, don't try (and fail) to generate ssh + v.1 keys when compiled without SSH1 support RSA/DSA/ECDSA keys when compiled + without OpenSSL based on patch by Mike Frysinger; bz#2369 + +commit 725fd22a8c41db7de73a638539a5157b7e4424ae +Author: djm@openbsd.org +Date: Wed Mar 18 01:44:21 2015 +0000 + + upstream commit + + KRL support doesn't need OpenSSL anymore, remove #ifdefs + from around call + +commit b07011c18e0b2e172c5fd09d21fb159a0bf5fcc7 +Author: djm@openbsd.org +Date: Mon Mar 16 11:09:52 2015 +0000 + + upstream commit + + #if 0 some more arrays used only for decrypting (we don't + use since we only need encrypt for AES-CTR) + +commit 1cb3016635898d287e9d58b50c430995652d5358 +Author: jsg@openbsd.org +Date: Wed Mar 11 00:48:39 2015 +0000 + + upstream commit + + add back the changes from rev 1.206, djm reverted this by + mistake in rev 1.207 + +commit 4d24b3b6a4a6383e05e7da26d183b79fa8663697 +Author: Damien Miller +Date: Fri Mar 20 09:11:59 2015 +1100 + + remove error() accidentally inserted for debugging + + pointed out by Christian Hesse + +commit 9f82e5a9042f2d872e98f48a876fcab3e25dd9bb +Author: Tim Rice +Date: Mon Mar 16 22:49:20 2015 -0700 + + portability fix: Solaris systems may not have a grep that understands -q + +commit 8ef691f7d9ef500257a549d0906d78187490668f +Author: Damien Miller +Date: Wed Mar 11 10:35:26 2015 +1100 + + fix compile with clang + +commit 4df590cf8dc799e8986268d62019b487a8ed63ad +Author: Damien Miller +Date: Wed Mar 11 10:02:39 2015 +1100 + + make unit tests work for !OPENSSH_HAS_ECC + +commit 307bb40277ca2c32e97e61d70d1ed74b571fd6ba +Author: djm@openbsd.org +Date: Sat Mar 7 04:41:48 2015 +0000 + + upstream commit + + unbreak for w/SSH1 (default) case; ok markus@ deraadt@ + +commit b44ee0c998fb4c5f3c3281f2398af5ce42840b6f +Author: Damien Miller +Date: Thu Mar 5 18:39:20 2015 -0800 + + unbreak hostkeys test for w/ SSH1 case + +commit 55e5bdeb519cb60cc18b7ba0545be581fb8598b4 +Author: djm@openbsd.org +Date: Fri Mar 6 01:40:56 2015 +0000 + + upstream commit + + fix sshkey_certify() return value for unsupported key types; + ok markus@ deraadt@ + +commit be8f658e550a434eac04256bfbc4289457a24e99 +Author: Damien Miller +Date: Wed Mar 4 15:38:03 2015 -0800 + + update version numbers to match version.h + +commit ac5e8acefa253eb5e5ba186e34236c0e8007afdc +Author: djm@openbsd.org +Date: Wed Mar 4 23:22:35 2015 +0000 + + upstream commit + + make these work with !SSH1; ok markus@ deraadt@ + +commit 2f04af92f036b0c87a23efb259c37da98cd81fe6 +Author: djm@openbsd.org +Date: Wed Mar 4 21:12:59 2015 +0000 + + upstream commit + + make ssh-add -D work with !SSH1 agent + +commit a05adf95d2af6abb2b7826ddaa7a0ec0cdc1726b +Author: Damien Miller +Date: Wed Mar 4 00:55:48 2015 -0800 + + netcat needs poll.h portability goop + +commit dad2b1892b4c1b7e58df483a8c5b983c4454e099 +Author: markus@openbsd.org +Date: Tue Mar 3 22:35:19 2015 +0000 + + upstream commit + + make it possible to run tests w/o ssh1 support; ok djm@ + +commit d48a22601bdd3eec054794c535f4ae8d8ae4c6e2 +Author: djm@openbsd.org +Date: Wed Mar 4 18:53:53 2015 +0000 + + upstream commit + + crank; ok markus, deraadt + +commit bbffb23daa0b002dd9f296e396a9ab8a5866b339 +Author: Damien Miller +Date: Tue Mar 3 13:50:27 2015 -0800 + + more --without-ssh1 fixes + +commit 6c2039286f503e2012a58a1d109e389016e7a99b +Author: Damien Miller +Date: Tue Mar 3 13:48:48 2015 -0800 + + fix merge both that broke --without-ssh1 compile + +commit 111dfb225478a76f89ecbcd31e96eaf1311b59d3 +Author: djm@openbsd.org +Date: Tue Mar 3 21:21:13 2015 +0000 + + upstream commit + + add SSH1 Makefile knob to make it easier to build without + SSH1 support; ok markus@ + +commit 3f7f5e6c5d2aa3f6710289c1a30119e534e56c5c +Author: djm@openbsd.org +Date: Tue Mar 3 20:42:49 2015 +0000 + + upstream commit + + expand __unused to full __attribute__ for better portability + +commit 2fab9b0f8720baf990c931e3f68babb0bf9949c6 +Author: Damien Miller +Date: Wed Mar 4 07:41:27 2015 +1100 + + avoid warning + +commit d1bc844322461f882b4fd2277ba9a8d4966573d2 +Author: Damien Miller +Date: Wed Mar 4 06:31:45 2015 +1100 + + Revert "define __unused to nothing if not already defined" + + This reverts commit 1598419e38afbaa8aa5df8dd6b0af98301e2c908. + + Some system headers have objects named __unused + +commit 00797e86b2d98334d1bb808f65fa1fd47f328ff1 +Author: Damien Miller +Date: Wed Mar 4 05:02:45 2015 +1100 + + check for crypt and DES_crypt in openssl block + + fixes builds on systems that use DES_crypt; based on patch + from Roumen Petrov + +commit 1598419e38afbaa8aa5df8dd6b0af98301e2c908 +Author: Damien Miller +Date: Wed Mar 4 04:59:13 2015 +1100 + + define __unused to nothing if not already defined + + fixes builds on BSD/OS + +commit d608a51daad4f14ad6ab43d7cf74ef4801cc3fe9 +Author: djm@openbsd.org +Date: Tue Mar 3 17:53:40 2015 +0000 + + upstream commit + + reorder logic for better portability; patch from Roumen + Petrov + +commit 68d2dfc464fbcdf8d6387884260f9801f4352393 +Author: djm@openbsd.org +Date: Tue Mar 3 06:48:58 2015 +0000 + + upstream commit + + Allow "ssh -Q protocol-version" to list supported SSH + protocol versions. Useful for detecting builds without SSH v.1 support; idea + and ok markus@ + +commit 39e2f1229562e1195169905607bc12290d21f021 +Author: millert@openbsd.org +Date: Sun Mar 1 15:44:40 2015 +0000 + + upstream commit + + Make sure we only call getnameinfo() for AF_INET or AF_INET6 + sockets. getpeername() of a Unix domain socket may return without error on + some systems without actually setting ss_family so getnameinfo() was getting + called with ss_family set to AF_UNSPEC. OK djm@ + +commit e47536ba9692d271b8ad89078abdecf0a1c11707 +Author: Damien Miller +Date: Sat Feb 28 08:20:11 2015 -0800 + + portability fixes for regress/netcat.c + + Mostly avoiding "err(1, NULL)" + +commit 02973ad5f6f49d8420e50a392331432b0396c100 +Author: Damien Miller +Date: Sat Feb 28 08:05:27 2015 -0800 + + twiddle another test for portability + + from Tom G. Christensen + +commit f7f3116abf2a6e2f309ab096b08c58d19613e5d0 +Author: Damien Miller +Date: Fri Feb 27 15:52:49 2015 -0800 + + twiddle test for portability + +commit 1ad3a77cc9d5568f5437ff99d377aa7a41859b83 +Author: Damien Miller +Date: Thu Feb 26 20:33:22 2015 -0800 + + make regress/netcat.c fd passing (more) portable + +commit 9e1cfca7e1fe9cf8edb634fc894e43993e4da1ea +Author: Damien Miller +Date: Thu Feb 26 20:32:58 2015 -0800 + + create OBJ/valgrind-out before running unittests + +commit bd58853102cee739f0e115e6d4b5334332ab1442 +Author: Damien Miller +Date: Wed Feb 25 16:58:22 2015 -0800 + + valgrind support + +commit f43d17269194761eded9e89f17456332f4c83824 +Author: djm@openbsd.org +Date: Thu Feb 26 20:45:47 2015 +0000 + + upstream commit + + don't printf NULL key comments; reported by Tom Christensen + +commit 6e6458b476ec854db33e3e68ebf4f489d0ab3df8 +Author: djm@openbsd.org +Date: Wed Feb 25 23:05:47 2015 +0000 + + upstream commit + + zero cmsgbuf before use; we initialise the bits we use + but valgrind still spams warning on it + +commit a63cfa26864b93ab6afefad0b630e5358ed8edfa +Author: djm@openbsd.org +Date: Wed Feb 25 19:54:02 2015 +0000 + + upstream commit + + fix small memory leak when UpdateHostkeys=no + +commit e6b950341dd75baa8526f1862bca39e52f5b879b +Author: Tim Rice +Date: Wed Feb 25 09:56:48 2015 -0800 + + Revert "Work around finicky USL linker so netcat will build." + + This reverts commit d1db656021d0cd8c001a6692f772f1de29b67c8b. + + No longer needed with commit 678e473e2af2e4802f24dd913985864d9ead7fb3 + +commit 6f621603f9cff2a5d6016a404c96cb2f8ac2dec0 +Author: djm@openbsd.org +Date: Wed Feb 25 17:29:38 2015 +0000 + + upstream commit + + don't leak validity of user in "too many authentication + failures" disconnect message; reported by Sebastian Reitenbach + +commit 6288e3a935494df12519164f52ca5c8c65fc3ca5 +Author: naddy@openbsd.org +Date: Tue Feb 24 15:24:05 2015 +0000 + + upstream commit + + add -v (show ASCII art) to -l's synopsis; ok djm@ + +commit 678e473e2af2e4802f24dd913985864d9ead7fb3 +Author: Darren Tucker +Date: Thu Feb 26 04:12:58 2015 +1100 + + Remove dependency on xmalloc. + + Remove ssh_get_progname's dependency on xmalloc, which should reduce + link order problems. ok djm@ + +commit 5d5ec165c5b614b03678afdad881f10e25832e46 +Author: Darren Tucker +Date: Wed Feb 25 15:32:49 2015 +1100 + + Restrict ECDSA and ECDH tests. + + ifdef out some more ECDSA and ECDH tests when built against an OpenSSL + that does not have eliptic curve functionality. + +commit 1734e276d99b17e92d4233fac7aef3a3180aaca7 +Author: Darren Tucker +Date: Wed Feb 25 13:40:45 2015 +1100 + + Move definition of _NSIG. + + _NSIG is only unsed in one file, so move it there prevent redefinition + warnings reported by Kevin Brott. + +commit a47ead7c95cfbeb72721066c4da2312e5b1b9f3d +Author: Darren Tucker +Date: Wed Feb 25 13:17:40 2015 +1100 + + Add includes.h for compatibility stuff. + +commit 38806bda6d2e48ad32812b461eebe17672ada771 +Author: Damien Miller +Date: Tue Feb 24 16:50:06 2015 -0800 + + include netdb.h to look for MAXHOSTNAMELEN; ok tim + +commit d1db656021d0cd8c001a6692f772f1de29b67c8b +Author: Tim Rice +Date: Tue Feb 24 10:42:08 2015 -0800 + + Work around finicky USL linker so netcat will build. + +commit cb030ce25f555737e8ba97bdd7883ac43f3ff2a3 +Author: Damien Miller +Date: Tue Feb 24 09:23:04 2015 -0800 + + include includes.h to avoid build failure on AIX + +commit 13af342458f5064144abbb07e5ac9bbd4eb42567 +Author: Tim Rice +Date: Tue Feb 24 07:56:47 2015 -0800 + + Original portability patch from djm@ for platforms missing err.h. + Fix name space clash on Solaris 10. Still more to do for Solaris 10 + to deal with msghdr structure differences. ok djm@ + +commit 910209203d0cd60c5083901cbcc0b7b44d9f48d2 +Author: Tim Rice +Date: Mon Feb 23 22:06:56 2015 -0800 + + cleaner way fix dispatch.h portion of commit + a88dd1da119052870bb2654c1a32c51971eade16 + (some systems have sig_atomic_t in signal.h, some in sys/signal.h) + Sounds good to me djm@ + +commit 676c38d7cbe65b76bbfff796861bb6615cc6a596 +Author: Tim Rice +Date: Mon Feb 23 21:51:33 2015 -0800 + + portability fix: if we can't dind a better define for HOST_NAME_MAX, use 255 + +commit 1221b22023dce38cbc90ba77eae4c5d78c77a5e6 +Author: Tim Rice +Date: Mon Feb 23 21:50:34 2015 -0800 + + portablity fix: s/__inline__/inline/ + +commit 4c356308a88d309c796325bb75dce90ca16591d5 +Author: Darren Tucker +Date: Tue Feb 24 13:49:31 2015 +1100 + + Wrap stdint.h includes in HAVE_STDINT_H. + +commit c9c88355c6a27a908e7d1e5003a2b35ea99c1614 +Author: Darren Tucker +Date: Tue Feb 24 13:43:57 2015 +1100 + + Add AI_NUMERICSERV to fake-rfc2553. + + Our getaddrinfo implementation always returns numeric values already. + +commit ef342ab1ce6fb9a4b30186c89c309d0ae9d0eeb4 +Author: Darren Tucker +Date: Tue Feb 24 13:39:57 2015 +1100 + + Include OpenSSL's objects.h before bn.h. + + Prevents compile errors on some platforms (at least old GCCs and AIX's + XLC compilers). + +commit dcc8997d116f615195aa7c9ec019fb36c28c6228 +Author: Darren Tucker +Date: Tue Feb 24 12:30:59 2015 +1100 + + Convert two macros into functions. + + Convert packet_send_debug and packet_disconnect from macros to + functions. Some older GCCs (2.7.x, 2.95.x) see to have problems with + variadic macros with only one argument so we convert these two into + functions. ok djm@ + +commit 2285c30d51b7e2052c6526445abe7e7cc7e170a1 +Author: djm@openbsd.org +Date: Mon Feb 23 22:21:21 2015 +0000 + + upstream commit + + further silence spurious error message even when -v is + specified (e.g. to get visual host keys); reported by naddy@ + +commit 9af21979c00652029e160295e988dea40758ece2 +Author: Damien Miller +Date: Tue Feb 24 09:04:32 2015 +1100 + + don't include stdint.h unless HAVE_STDINT_H set + +commit 62f678dd51660d6f8aee1da33d3222c5de10a89e +Author: Damien Miller +Date: Tue Feb 24 09:02:54 2015 +1100 + + nother sys/queue.h -> sys-queue.h fix + + spotted by Tom Christensen + +commit b3c19151cba2c0ed01b27f55de0d723ad07ca98f +Author: djm@openbsd.org +Date: Mon Feb 23 20:32:15 2015 +0000 + + upstream commit + + fix a race condition by using a mux socket rather than an + ineffectual wait statement + +commit a88dd1da119052870bb2654c1a32c51971eade16 +Author: Damien Miller +Date: Tue Feb 24 06:30:29 2015 +1100 + + various include fixes for portable + +commit 5248429b5ec524d0a65507cff0cdd6e0cb99effd +Author: djm@openbsd.org +Date: Mon Feb 23 16:55:51 2015 +0000 + + upstream commit + + add an XXX to remind me to improve sshkey_load_public + +commit e94e4b07ef2eaead38b085a60535df9981cdbcdb +Author: djm@openbsd.org +Date: Mon Feb 23 16:55:31 2015 +0000 + + upstream commit + + silence a spurious error message when listing + fingerprints for known_hosts; bz#2342 + +commit f2293a65392b54ac721f66bc0b44462e8d1d81f8 +Author: djm@openbsd.org +Date: Mon Feb 23 16:33:25 2015 +0000 + + upstream commit + + fix setting/clearing of TTY raw mode around + UpdateHostKeys=ask confirmation question; reported by Herb Goldman + +commit f2004cd1adf34492eae0a44b1ef84e0e31b06088 +Author: Darren Tucker +Date: Mon Feb 23 05:04:21 2015 +1100 + + Repair for non-ECC OpenSSL. + + Ifdef out the ECC parts when building with an OpenSSL that doesn't have + it. + +commit 37f9220db8d1a52c75894c3de1e5f2ae5bd71b6f +Author: Darren Tucker +Date: Mon Feb 23 03:07:24 2015 +1100 + + Wrap stdint.h includes in ifdefs. + +commit f81f1bbc5b892c8614ea740b1f92735652eb43f0 +Author: Tim Rice +Date: Sat Feb 21 18:12:10 2015 -0800 + + out of tree build fix + +commit 2e13a1e4d22f3b503c3bfc878562cc7386a1d1ae +Author: Tim Rice +Date: Sat Feb 21 18:08:51 2015 -0800 + + mkdir kex unit test directory so testing out of tree builds works + +commit 1797f49b1ba31e8700231cd6b1d512d80bb50d2c +Author: halex@openbsd.org +Date: Sat Feb 21 21:46:57 2015 +0000 + + upstream commit + + make "ssh-add -d" properly remove a corresponding + certificate, and also not whine and fail if there is none + + ok djm@ + +commit 7faaa32da83a609059d95dbfcb0649fdb04caaf6 +Author: Damien Miller +Date: Sun Feb 22 07:57:27 2015 +1100 + + mkdir hostkey and bitmap unit test directories + +commit bd49da2ef197efac5e38f5399263a8b47990c538 +Author: djm@openbsd.org +Date: Fri Feb 20 23:46:01 2015 +0000 + + upstream commit + + sort options useable under Match case-insensitively; prodded + jmc@ + +commit 1a779a0dd6cd8b4a1a40ea33b5415ab8408128ac +Author: djm@openbsd.org +Date: Sat Feb 21 20:51:02 2015 +0000 + + upstream commit + + correct paths to configuration files being written/updated; + they live in $OBJ not cwd; some by Roumen Petrov + +commit 28ba006c1acddff992ae946d0bc0b500b531ba6b +Author: Darren Tucker +Date: Sat Feb 21 15:41:07 2015 +1100 + + More correct checking of HAVE_DECL_AI_NUMERICSERV. + +commit e50e8c97a9cecae1f28febccaa6ca5ab3bc10f54 +Author: Darren Tucker +Date: Sat Feb 21 15:10:33 2015 +1100 + + Add null declaration of AI_NUMERICINFO. + + Some platforms (older FreeBSD and DragonFly versions) do have + getaddrinfo() but do not have AI_NUMERICINFO. so define it to zero + in those cases. + +commit 18a208d6a460d707a45916db63a571e805f5db46 +Author: djm@openbsd.org +Date: Fri Feb 20 22:40:32 2015 +0000 + + upstream commit + + more options that are available under Match; bz#2353 reported + by calestyo AT scientia.net + +commit 44732de06884238049f285f1455b2181baa7dc82 +Author: djm@openbsd.org +Date: Fri Feb 20 22:17:21 2015 +0000 + + upstream commit + + UpdateHostKeys fixes: + + I accidentally changed the format of the hostkeys@openssh.com messages + last week without changing the extension name, and this has been causing + connection failures for people who are running -current. First reported + by sthen@ + + s/hostkeys@openssh.com/hostkeys-00@openssh.com/ + Change the name of the proof message too, and reorder it a little. + + Also, UpdateHostKeys=ask is incompatible with ControlPersist (no TTY + available to read the response) so disable UpdateHostKeys if it is in + ask mode and ControlPersist is active (and document this) + +commit 13a39414d25646f93e6d355521d832a03aaaffe2 +Author: djm@openbsd.org +Date: Tue Feb 17 00:14:05 2015 +0000 + + upstream commit + + Regression: I broke logging of public key fingerprints in + 1.46. Pointed out by Pontus Lundkvist + +commit 773dda25e828c4c9a52f7bdce6e1e5924157beab +Author: Damien Miller +Date: Fri Jan 30 23:10:17 2015 +1100 + + repair --without-openssl; broken in refactor + +commit e89c780886b23600de1e1c8d74aabd1ff61f43f0 +Author: Damien Miller +Date: Tue Feb 17 10:04:55 2015 +1100 + + hook up hostkeys unittest to portable Makefiles + +commit 0abf41f99aa16ff09b263bead242d6cb2dbbcf99 +Author: djm@openbsd.org +Date: Mon Feb 16 22:21:03 2015 +0000 + + upstream commit + + enable hostkeys unit tests + +commit 68a5d647ccf0fb6782b2f749433a1eee5bc9044b +Author: djm@openbsd.org +Date: Mon Feb 16 22:20:50 2015 +0000 + + upstream commit + + check string/memory compare arguments aren't NULL + +commit ef575ef20d09f20722e26b45dab80b3620469687 +Author: djm@openbsd.org +Date: Mon Feb 16 22:18:34 2015 +0000 + + upstream commit + + unit tests for hostfile.c code, just hostkeys_foreach so + far + +commit 8ea3365e6aa2759ccf5c76eaea62cbc8a280b0e7 +Author: markus@openbsd.org +Date: Sat Feb 14 12:43:16 2015 +0000 + + upstream commit + + test server rekey limit + +commit ce63c4b063c39b2b22d4ada449c9e3fbde788cb3 +Author: djm@openbsd.org +Date: Mon Feb 16 22:30:03 2015 +0000 + + upstream commit + + partial backout of: + + revision 1.441 + date: 2015/01/31 20:30:05; author: djm; state: Exp; lines: +17 -10; commitid + : x8klYPZMJSrVlt3O; + Let sshd load public host keys even when private keys are missing. + Allows sshd to advertise additional keys for future key rotation. + Also log fingerprint of hostkeys loaded; ok markus@ + + hostkey updates now require access to the private key, so we can't + load public keys only. The improved log messages (fingerprints of keys + loaded) are kept. + +commit 523463a3a2a9bfc6cfc5afa01bae9147f76a37cc +Author: djm@openbsd.org +Date: Mon Feb 16 22:13:32 2015 +0000 + + upstream commit + + Revise hostkeys@openssh.com hostkey learning extension. + + The client will not ask the server to prove ownership of the private + halves of any hitherto-unseen hostkeys it offers to the client. + + Allow UpdateHostKeys option to take an 'ask' argument to let the + user manually review keys offered. + + ok markus@ + +commit 6c5c949782d86a6e7d58006599c7685bfcd01685 +Author: djm@openbsd.org +Date: Mon Feb 16 22:08:57 2015 +0000 + + upstream commit + + Refactor hostkeys_foreach() and dependent code Deal with + IP addresses (i.e. CheckHostIP) Don't clobber known_hosts when nothing + changed ok markus@ as part of larger commit + +commit 51b082ccbe633dc970df1d1f4c9c0497115fe721 +Author: miod@openbsd.org +Date: Mon Feb 16 18:26:26 2015 +0000 + + upstream commit + + Declare ge25519_base as extern, to prevent it from + becoming a common. Gets us rid of ``lignment 4 of symbol + `crypto_sign_ed25519_ref_ge25519_base' in mod_ge25519.o is smaller than 16 in + mod_ed25519.o'' warnings at link time. + +commit 02db468bf7e3281a8e3c058ced571b38b6407c34 +Author: markus@openbsd.org +Date: Fri Feb 13 18:57:00 2015 +0000 + + upstream commit + + make rekey_limit for sshd w/privsep work; ok djm@ + dtucker@ + +commit 8ec67d505bd23c8bf9e17b7a364b563a07a58ec8 +Author: dtucker@openbsd.org +Date: Thu Feb 12 20:34:19 2015 +0000 + + upstream commit + + Prevent sshd spamming syslog with + "ssh_dispatch_run_fatal: disconnected". ok markus@ + +commit d4c0295d1afc342057ba358237acad6be8af480b +Author: djm@openbsd.org +Date: Wed Feb 11 01:20:38 2015 +0000 + + upstream commit + + Some packet error messages show the address of the peer, + but might be generated after the socket to the peer has suffered a TCP reset. + In these cases, getpeername() won't work so cache the address earlier. + + spotted in the wild via deraadt@ and tedu@ + +commit 4af1709cf774475ce5d1bc3ddcc165f6c222897d +Author: jsg@openbsd.org +Date: Mon Feb 9 23:22:37 2015 +0000 + + upstream commit + + fix some leaks in error paths ok markus@ + +commit fd36834871d06a03e1ff8d69e41992efa1bbf85f +Author: millert@openbsd.org +Date: Fri Feb 6 23:21:59 2015 +0000 + + upstream commit + + SIZE_MAX is standard, we should be using it in preference to + the obsolete SIZE_T_MAX. OK miod@ beck@ + +commit 1910a286d7771eab84c0b047f31c0a17505236fa +Author: millert@openbsd.org +Date: Thu Feb 5 12:59:57 2015 +0000 + + upstream commit + + Include stdint.h, not limits.h to get SIZE_MAX. OK guenther@ + +commit ce4f59b2405845584f45e0b3214760eb0008c06c +Author: deraadt@openbsd.org +Date: Tue Feb 3 08:07:20 2015 +0000 + + upstream commit + + missing ; djm and mlarkin really having great + interactions recently + +commit 5d34aa94938abb12b877a25be51862757f25d54b +Author: halex@openbsd.org +Date: Tue Feb 3 00:34:14 2015 +0000 + + upstream commit + + slightly extend the passphrase prompt if running with -c + in order to give the user a chance to notice if unintentionally running + without it + + wording tweak and ok djm@ + +commit cb3bde373e80902c7d5d0db429f85068d19b2918 +Author: djm@openbsd.org +Date: Mon Feb 2 22:48:53 2015 +0000 + + upstream commit + + handle PKCS#11 C_Login returning + CKR_USER_ALREADY_LOGGED_IN; based on patch from Yuri Samoilenko; ok markus@ + +commit 15ad750e5ec3cc69765b7eba1ce90060e7083399 +Author: djm@openbsd.org +Date: Mon Feb 2 07:41:40 2015 +0000 + + upstream commit + + turn UpdateHostkeys off by default until I figure out + mlarkin@'s warning message; requested by deraadt@ + +commit 3cd5103c1e1aaa59bd66f7f52f6ebbcd5deb12f9 +Author: deraadt@openbsd.org +Date: Mon Feb 2 01:57:44 2015 +0000 + + upstream commit + + increasing encounters with difficult DNS setups in + darknets has convinced me UseDNS off by default is better ok djm + +commit 6049a548a8a68ff0bbe581ab1748ea6a59ecdc38 +Author: djm@openbsd.org +Date: Sat Jan 31 20:30:05 2015 +0000 + + upstream commit + + Let sshd load public host keys even when private keys are + missing. Allows sshd to advertise additional keys for future key rotation. + Also log fingerprint of hostkeys loaded; ok markus@ + +commit 46347ed5968f582661e8a70a45f448e0179ca0ab +Author: djm@openbsd.org +Date: Fri Jan 30 11:43:14 2015 +0000 + + upstream commit + + Add a ssh_config HostbasedKeyType option to control which + host public key types are tried during hostbased authentication. + + This may be used to prevent too many keys being sent to the server, + and blowing past its MaxAuthTries limit. + + bz#2211 based on patch by Iain Morgan; ok markus@ + +commit 802660cb70453fa4d230cb0233bc1bbdf8328de1 +Author: djm@openbsd.org +Date: Fri Jan 30 10:44:49 2015 +0000 + + upstream commit + + set a timeout to prevent hangs when talking to busted + servers; ok markus@ + +commit 86936ec245a15c7abe71a0722610998b0a28b194 +Author: djm@openbsd.org +Date: Fri Jan 30 01:11:39 2015 +0000 + + upstream commit + + regression test for 'wildcard CA' serial/key ID revocations + +commit 4509b5d4a4fa645a022635bfa7e86d09b285001f +Author: djm@openbsd.org +Date: Fri Jan 30 01:13:33 2015 +0000 + + upstream commit + + avoid more fatal/exit in the packet.c paths that + ssh-keyscan uses; feedback and "looks good" markus@ + +commit 669aee994348468af8b4b2ebd29b602cf2860b22 +Author: djm@openbsd.org +Date: Fri Jan 30 01:10:33 2015 +0000 + + upstream commit + + permit KRLs that revoke certificates by serial number or + key ID without scoping to a particular CA; ok markus@ + +commit 7a2c368477e26575d0866247d3313da4256cb2b5 +Author: djm@openbsd.org +Date: Fri Jan 30 00:59:19 2015 +0000 + + upstream commit + + missing parentheses after if in do_convert_from() broke + private key conversion from other formats some time in 2010; bz#2345 reported + by jjelen AT redhat.com + +commit 25f5f78d8bf5c22d9cea8b49de24ebeee648a355 +Author: djm@openbsd.org +Date: Fri Jan 30 00:22:25 2015 +0000 + + upstream commit + + fix ssh protocol 1, spotted by miod@ + +commit 9ce86c926dfa6e0635161b035e3944e611cbccf0 +Author: djm@openbsd.org +Date: Wed Jan 28 22:36:00 2015 +0000 + + upstream commit + + update to new API (key_fingerprint => sshkey_fingerprint) + check sshkey_fingerprint return values; ok markus + +commit 9125525c37bf73ad3ee4025520889d2ce9d10f29 +Author: djm@openbsd.org +Date: Wed Jan 28 22:05:31 2015 +0000 + + upstream commit + + avoid fatal() calls in packet code makes ssh-keyscan more + reliable against server failures ok dtucker@ markus@ + +commit fae7bbe544cba7a9e5e4ab47ff6faa3d978646eb +Author: djm@openbsd.org +Date: Wed Jan 28 21:15:47 2015 +0000 + + upstream commit + + avoid fatal() calls in packet code makes ssh-keyscan more + reliable against server failures ok dtucker@ markus@ + +commit 1a3d14f6b44a494037c7deab485abe6496bf2c60 +Author: djm@openbsd.org +Date: Wed Jan 28 11:07:25 2015 +0000 + + upstream commit + + remove obsolete comment + +commit 80c25b7bc0a71d75c43a4575d9a1336f589eb639 +Author: okan@openbsd.org +Date: Tue Jan 27 12:54:06 2015 +0000 + + upstream commit + + Since r1.2 removed the use of PRI* macros, inttypes.h is + no longer required. + + ok djm@ + +commit 69ff64f69615c2a21c97cb5878a0996c21423257 +Author: Damien Miller +Date: Tue Jan 27 23:07:43 2015 +1100 + + compile on systems without TCP_MD5SIG (e.g. OSX) + +commit 358964f3082fb90b2ae15bcab07b6105cfad5a43 +Author: Damien Miller +Date: Tue Jan 27 23:07:25 2015 +1100 + + use ssh-keygen under test rather than system's + +commit a2c95c1bf33ea53038324d1fdd774bc953f98236 +Author: Damien Miller +Date: Tue Jan 27 23:06:59 2015 +1100 + + OSX lacks HOST_NAME_MAX, has _POSIX_HOST_NAME_MAX + +commit ade31d7b6f608a19b85bee29a7a00b1e636a2919 +Author: Damien Miller +Date: Tue Jan 27 23:06:23 2015 +1100 + + these need active_state defined to link on OSX + + temporary measure until active_state goes away entirely + +commit e56aa87502f22c5844918c10190e8b4f785f067b +Author: djm@openbsd.org +Date: Tue Jan 27 12:01:36 2015 +0000 + + upstream commit + + use printf instead of echo -n to reduce diff against + -portable + +commit 9f7637f56eddfaf62ce3c0af89c25480f2cf1068 +Author: jmc@openbsd.org +Date: Mon Jan 26 13:55:29 2015 +0000 + + upstream commit + + sort previous; + +commit 3076ee7d530d5b16842fac7a6229706c7e5acd26 +Author: djm@openbsd.org +Date: Mon Jan 26 13:36:53 2015 +0000 + + upstream commit + + properly restore umask + +commit d411d395556b73ba1b9e451516a0bd6697c4b03d +Author: djm@openbsd.org +Date: Mon Jan 26 06:12:18 2015 +0000 + + upstream commit + + regression test for host key rotation + +commit fe8a3a51699afbc6407a8fae59b73349d01e49f8 +Author: djm@openbsd.org +Date: Mon Jan 26 06:11:28 2015 +0000 + + upstream commit + + adapt to sshkey API tweaks + +commit 7dd355fb1f0038a3d5cdca57ebab4356c7a5b434 +Author: miod@openbsd.org +Date: Sat Jan 24 10:39:21 2015 +0000 + + upstream commit + + Move -lz late in the linker commandline for things to + build on static arches. + +commit 0dad3b806fddb93c475b30853b9be1a25d673a33 +Author: miod@openbsd.org +Date: Fri Jan 23 21:21:23 2015 +0000 + + upstream commit + + -Wpointer-sign is supported by gcc 4 only. + +commit 2b3b1c1e4bd9577b6e780c255c278542ea66c098 +Author: djm@openbsd.org +Date: Tue Jan 20 22:58:57 2015 +0000 + + upstream commit + + use SUBDIR to recuse into unit tests; makes "make obj" + actually work + +commit 1d1092bff8db27080155541212b420703f8b9c92 +Author: djm@openbsd.org +Date: Mon Jan 26 12:16:36 2015 +0000 + + upstream commit + + correct description of UpdateHostKeys in ssh_config.5 and + add it to -o lists for ssh, scp and sftp; pointed out by jmc@ + +commit 5104db7cbd6cdd9c5971f4358e74414862fc1022 +Author: djm@openbsd.org +Date: Mon Jan 26 06:10:03 2015 +0000 + + upstream commit + + correctly match ECDSA subtype (== curve) for + offered/recevied host keys. Fixes connection-killing host key mismatches when + a server offers multiple ECDSA keys with different curve type (an extremely + unlikely configuration). + + ok markus, "looks mechanical" deraadt@ + +commit 8d4f87258f31cb6def9b3b55b6a7321d84728ff2 +Author: djm@openbsd.org +Date: Mon Jan 26 03:04:45 2015 +0000 + + upstream commit + + Host key rotation support. + + Add a hostkeys@openssh.com protocol extension (global request) for + a server to inform a client of all its available host key after + authentication has completed. The client may record the keys in + known_hosts, allowing it to upgrade to better host key algorithms + and a server to gracefully rotate its keys. + + The client side of this is controlled by a UpdateHostkeys config + option (default on). + + ok markus@ + +commit 60b1825262b1f1e24fc72050b907189c92daf18e +Author: djm@openbsd.org +Date: Mon Jan 26 02:59:11 2015 +0000 + + upstream commit + + small refactor and add some convenience functions; ok + markus + +commit a5a3e3328ddce91e76f71ff479022d53e35c60c9 +Author: jmc@openbsd.org +Date: Thu Jan 22 21:00:42 2015 +0000 + + upstream commit + + heirarchy -> hierarchy; + +commit dcff5810a11195c57e1b3343c0d6b6f2b9974c11 +Author: deraadt@openbsd.org +Date: Thu Jan 22 20:24:41 2015 +0000 + + upstream commit + + Provide a warning about chroot misuses (which sadly, seem + to have become quite popular because shiny). sshd cannot detect/manage/do + anything about these cases, best we can do is warn in the right spot in the + man page. ok markus + +commit 087266ec33c76fc8d54ac5a19efacf2f4a4ca076 +Author: deraadt@openbsd.org +Date: Tue Jan 20 23:14:00 2015 +0000 + + upstream commit + + Reduce use of and transition to + throughout. ok djm markus + +commit 57e783c8ba2c0797f93977e83b2a8644a03065d8 +Author: markus@openbsd.org +Date: Tue Jan 20 20:16:21 2015 +0000 + + upstream commit + + kex_setup errors are fatal() + +commit 1d6424a6ff94633c221297ae8f42d54e12a20912 +Author: djm@openbsd.org +Date: Tue Jan 20 08:02:33 2015 +0000 + + upstream commit + + this test would accidentally delete agent.sh if run without + obj/ + +commit 12b5f50777203e12575f1b08568281e447249ed3 +Author: djm@openbsd.org +Date: Tue Jan 20 07:56:44 2015 +0000 + + upstream commit + + make this compile with KERBEROS5 enabled + +commit e2cc6bef08941256817d44d146115b3478586ad4 +Author: djm@openbsd.org +Date: Tue Jan 20 07:55:33 2015 +0000 + + upstream commit + + fix hostkeys in agent; ok markus@ + +commit 1ca3e2155aa5d3801a7ae050f85c71f41fcb95b1 +Author: Damien Miller +Date: Tue Jan 20 10:11:31 2015 +1100 + + fix kex test + +commit c78a578107c7e6dcf5d30a2f34cb6581bef14029 +Author: markus@openbsd.org +Date: Mon Jan 19 20:45:25 2015 +0000 + + upstream commit + + finally enable the KEX tests I wrote some years ago... + +commit 31821d7217e686667d04935aeec99e1fc4a46e7e +Author: markus@openbsd.org +Date: Mon Jan 19 20:42:31 2015 +0000 + + upstream commit + + adapt to new error message (SSH_ERR_MAC_INVALID) + +commit d3716ca19e510e95d956ae14d5b367e364bff7f1 +Author: djm@openbsd.org +Date: Mon Jan 19 17:31:13 2015 +0000 + + upstream commit + + this test was broken in at least two ways, such that it + wasn't checking that a KRL was not excluding valid keys + +commit 3f797653748e7c2b037dacb57574c01d9ef3b4d3 +Author: markus@openbsd.org +Date: Mon Jan 19 20:32:39 2015 +0000 + + upstream commit + + switch ssh-keyscan from setjmp to multiple ssh transport + layer instances ok djm@ + +commit f582f0e917bb0017b00944783cd5f408bf4b0b5e +Author: markus@openbsd.org +Date: Mon Jan 19 20:30:23 2015 +0000 + + upstream commit + + add experimental api for packet layer; ok djm@ + +commit 48b3b2ba75181f11fca7f327058a591f4426cade +Author: markus@openbsd.org +Date: Mon Jan 19 20:20:20 2015 +0000 + + upstream commit + + store compat flags in struct ssh; ok djm@ + +commit 57d10cbe861a235dd269c74fb2fe248469ecee9d +Author: markus@openbsd.org +Date: Mon Jan 19 20:16:15 2015 +0000 + + upstream commit + + adapt kex to sshbuf and struct ssh; ok djm@ + +commit 3fdc88a0def4f86aa88a5846ac079dc964c0546a +Author: markus@openbsd.org +Date: Mon Jan 19 20:07:45 2015 +0000 + + upstream commit + + move dispatch to struct ssh; ok djm@ + +commit 091c302829210c41e7f57c3f094c7b9c054306f0 +Author: markus@openbsd.org +Date: Mon Jan 19 19:52:16 2015 +0000 + + upstream commit + + update packet.c & isolate, introduce struct ssh a) switch + packet.c to buffer api and isolate per-connection info into struct ssh b) + (de)serialization of the state is moved from monitor to packet.c c) the old + packet.c API is implemented in opacket.[ch] d) compress.c/h is removed and + integrated into packet.c with and ok djm@ + +commit 4e62cc68ce4ba20245d208b252e74e91d3785b74 +Author: djm@openbsd.org +Date: Mon Jan 19 17:35:48 2015 +0000 + + upstream commit + + fix format strings in (disabled) debugging + +commit d85e06245907d49a2cd0cfa0abf59150ad616f42 +Author: djm@openbsd.org +Date: Mon Jan 19 06:01:32 2015 +0000 + + upstream commit + + be a bit more careful in these tests to ensure that + known_hosts is clean + +commit 7947810eab5fe0ad311f32a48f4d4eb1f71be6cf +Author: djm@openbsd.org +Date: Sun Jan 18 22:00:18 2015 +0000 + + upstream commit + + regression test for known_host file editing using + ssh-keygen (-H / -R / -F) after hostkeys_foreach() change; feedback and ok + markus@ + +commit 3a2b09d147a565d8a47edf37491e149a02c0d3a3 +Author: djm@openbsd.org +Date: Sun Jan 18 19:54:46 2015 +0000 + + upstream commit + + more and better key tests + + test signatures and verification + test certificate generation + flesh out nested cert test + + removes most of the XXX todo markers + +commit 589e69fd82724cfc9738f128e4771da2e6405d0d +Author: djm@openbsd.org +Date: Sun Jan 18 19:53:58 2015 +0000 + + upstream commit + + make the signature fuzzing test much more rigorous: + ensure that the fuzzed input cases do not match the original (using new + fuzz_matches_original() function) and check that the verification fails in + each case + +commit 80603c0daa2538c349c1c152405580b164d5475f +Author: djm@openbsd.org +Date: Sun Jan 18 19:52:44 2015 +0000 + + upstream commit + + add a fuzz_matches_original() function to the fuzzer to + detect fuzz cases that are identical to the original data. Hacky + implementation, but very useful when you need the fuzz to be different, e.g. + when verifying signature + +commit 87d5495bd337e358ad69c524fcb9495208c0750b +Author: djm@openbsd.org +Date: Sun Jan 18 19:50:55 2015 +0000 + + upstream commit + + better dumps from the fuzzer (shown on errors) - + include the original data as well as the fuzzed copy. + +commit d59ec478c453a3fff05badbbfd96aa856364f2c2 +Author: djm@openbsd.org +Date: Sun Jan 18 19:47:55 2015 +0000 + + upstream commit + + enable hostkey-agent.sh test + +commit 26b3425170bf840e4b095e1c10bf25a0a3e3a105 +Author: djm@openbsd.org +Date: Sat Jan 17 18:54:30 2015 +0000 + + upstream commit + + unit test for hostkeys in ssh-agent + +commit 9e06a0fb23ec55d9223b26a45bb63c7649e2f2f2 +Author: markus@openbsd.org +Date: Thu Jan 15 23:41:29 2015 +0000 + + upstream commit + + add kex unit tests + +commit d2099dec6da21ae627f6289aedae6bc1d41a22ce +Author: deraadt@openbsd.org +Date: Mon Jan 19 00:32:54 2015 +0000 + + upstream commit + + djm, your /usr/include tree is old + +commit 2b3c3c76c30dc5076fe09d590f5b26880f148a54 +Author: djm@openbsd.org +Date: Sun Jan 18 21:51:19 2015 +0000 + + upstream commit + + some feedback from markus@: comment hostkeys_foreach() + context and avoid a member in it. + +commit cecb30bc2ba6d594366e657d664d5c494b6c8a7f +Author: djm@openbsd.org +Date: Sun Jan 18 21:49:42 2015 +0000 + + upstream commit + + make ssh-keygen use hostkeys_foreach(). Removes some + horrendous code; ok markus@ + +commit ec3d065df3a9557ea96b02d061fd821a18c1a0b9 +Author: djm@openbsd.org +Date: Sun Jan 18 21:48:09 2015 +0000 + + upstream commit + + convert load_hostkeys() (hostkey ordering and + known_host matching) to use the new hostkey_foreach() iterator; ok markus + +commit c29811cc480a260e42fd88849fc86a80c1e91038 +Author: djm@openbsd.org +Date: Sun Jan 18 21:40:23 2015 +0000 + + upstream commit + + introduce hostkeys_foreach() to allow iteration over a + known_hosts file or controlled subset thereof. This will allow us to pull out + some ugly and duplicated code, and will be used to implement hostkey rotation + later. + + feedback and ok markus + +commit f101d8291da01bbbfd6fb8c569cfd0cc61c0d346 +Author: deraadt@openbsd.org +Date: Sun Jan 18 14:01:00 2015 +0000 + + upstream commit + + string truncation due to sizeof(size) ok djm markus + +commit 35d6022b55b7969fc10c261cb6aa78cc4a5fcc41 +Author: djm@openbsd.org +Date: Sun Jan 18 13:33:34 2015 +0000 + + upstream commit + + avoid trailing ',' in host key algorithms + +commit 7efb455789a0cb76bdcdee91c6060a3dc8f5c007 +Author: djm@openbsd.org +Date: Sun Jan 18 13:22:28 2015 +0000 + + upstream commit + + infer key length correctly when user specified a fully- + qualified key name instead of using the -b bits option; ok markus@ + +commit 83f8ffa6a55ccd0ce9d8a205e3e7439ec18fedf5 +Author: djm@openbsd.org +Date: Sat Jan 17 18:53:34 2015 +0000 + + upstream commit + + fix hostkeys on ssh agent; found by unit test I'm about + to commit + +commit 369d61f17657b814124268f99c033e4dc6e436c1 +Author: schwarze@openbsd.org +Date: Fri Jan 16 16:20:23 2015 +0000 + + upstream commit + + garbage collect empty .No macros mandoc warns about + +commit bb8b442d32dbdb8521d610e10d8b248d938bd747 +Author: djm@openbsd.org +Date: Fri Jan 16 15:55:07 2015 +0000 + + upstream commit + + regression: incorrect error message on + otherwise-successful ssh-keygen -A. Reported by Dmitry Orlov, via deraadt@ + +commit 9010902954a40b59d0bf3df3ccbc3140a653e2bc +Author: djm@openbsd.org +Date: Fri Jan 16 07:19:48 2015 +0000 + + upstream commit + + when hostname canonicalisation is enabled, try to parse + hostnames as addresses before looking them up for canonicalisation. fixes + bz#2074 and avoids needless DNS lookups in some cases; ok markus + +commit 2ae4f337b2a5fb2841b6b0053b49496fef844d1c +Author: deraadt@openbsd.org +Date: Fri Jan 16 06:40:12 2015 +0000 + + upstream commit + + Replace with and other less + dirty headers where possible. Annotate lines with their + current reasons. Switch to PATH_MAX, NGROUPS_MAX, HOST_NAME_MAX+1, + LOGIN_NAME_MAX, etc. Change MIN() and MAX() to local definitions of + MINIMUM() and MAXIMUM() where sensible to avoid pulling in the pollution. + These are the files confirmed through binary verification. ok guenther, + millert, doug (helped with the verification protocol) + +commit 3c4726f4c24118e8f1bb80bf75f1456c76df072c +Author: markus@openbsd.org +Date: Thu Jan 15 21:38:50 2015 +0000 + + upstream commit + + remove xmalloc, switch to sshbuf + +commit e17ac01f8b763e4b83976b9e521e90a280acc097 +Author: markus@openbsd.org +Date: Thu Jan 15 21:37:14 2015 +0000 + + upstream commit + + switch to sshbuf + +commit ddef9995a1fa6c7a8ff3b38bfe6cf724bebf13d0 +Author: naddy@openbsd.org +Date: Thu Jan 15 18:32:54 2015 +0000 + + upstream commit + + handle UMAC128 initialization like UMAC; ok djm@ markus@ + +commit f14564c1f7792446bca143580aef0e7ac25dcdae +Author: djm@openbsd.org +Date: Thu Jan 15 11:04:36 2015 +0000 + + upstream commit + + fix regression reported by brad@ for passworded keys without + agent present + +commit 45c0fd70bb2a88061319dfff20cb12ef7b1bc47e +Author: Damien Miller +Date: Thu Jan 15 22:08:23 2015 +1100 + + make bitmap test compile + +commit d333f89abf7179021e5c3f28673f469abe032062 +Author: djm@openbsd.org +Date: Thu Jan 15 07:36:28 2015 +0000 + + upstream commit + + unit tests for KRL bitmap + +commit 7613f828f49c55ff356007ae9645038ab6682556 +Author: markus@openbsd.org +Date: Wed Jan 14 09:58:21 2015 +0000 + + upstream commit + + re-add comment about full path + +commit 6c43b48b307c41cd656b415621a644074579a578 +Author: markus@openbsd.org +Date: Wed Jan 14 09:54:38 2015 +0000 + + upstream commit + + don't reset to the installed sshd; connect before + reconfigure, too + +commit 771bb47a1df8b69061f09462e78aa0b66cd594bf +Author: djm@openbsd.org +Date: Tue Jan 13 14:51:51 2015 +0000 + + upstream commit + + implement a SIGINFO handler so we can discern a stuck + fuzz test from a merely glacial one; prompted by and ok markus + +commit cfaa57962f8536f3cf0fd7daf4d6a55d6f6de45f +Author: djm@openbsd.org +Date: Tue Jan 13 08:23:26 2015 +0000 + + upstream commit + + use $SSH instead of installed ssh to allow override; + spotted by markus@ + +commit 0920553d0aee117a596b03ed5b49b280d34a32c5 +Author: djm@openbsd.org +Date: Tue Jan 13 07:49:49 2015 +0000 + + upstream commit + + regress test for PubkeyAcceptedKeyTypes; ok markus@ + +commit 27ca1a5c0095eda151934bca39a77e391f875d17 +Author: markus@openbsd.org +Date: Mon Jan 12 20:13:27 2015 +0000 + + upstream commit + + unbreak parsing of pubkey comments; with gerhard; ok + djm/deraadt + +commit 55358f0b4e0b83bc0df81c5f854c91b11e0bb4dc +Author: djm@openbsd.org +Date: Mon Jan 12 11:46:32 2015 +0000 + + upstream commit + + fatal if soft-PKCS11 library is missing rather (rather + than continue and fail with a more cryptic error) + +commit c3554cdd2a1a62434b8161017aa76fa09718a003 +Author: djm@openbsd.org +Date: Mon Jan 12 11:12:38 2015 +0000 + + upstream commit + + let this test all supporte key types; pointed out/ok + markus@ + +commit 1129dcfc5a3e508635004bcc05a3574cb7687167 +Author: djm@openbsd.org +Date: Thu Jan 15 09:40:00 2015 +0000 + + upstream commit + + sync ssh-keysign, ssh-keygen and some dependencies to the + new buffer/key API; mostly mechanical, ok markus@ + +commit e4ebf5586452bf512da662ac277aaf6ecf0efe7c +Author: djm@openbsd.org +Date: Thu Jan 15 07:57:08 2015 +0000 + + upstream commit + + remove commented-out test code now that it has moved to a + proper unit test + +commit e81cba066c1e9eb70aba0f6e7c0ff220611b370f +Author: djm@openbsd.org +Date: Wed Jan 14 20:54:29 2015 +0000 + + upstream commit + + whitespace + +commit 141efe49542f7156cdbc2e4cd0a041d8b1aab622 +Author: djm@openbsd.org +Date: Wed Jan 14 20:05:27 2015 +0000 + + upstream commit + + move authfd.c and its tentacles to the new buffer/key + API; ok markus@ + +commit 0088c57af302cda278bd26d8c3ae81d5b6f7c289 +Author: djm@openbsd.org +Date: Wed Jan 14 19:33:41 2015 +0000 + + upstream commit + + fix small regression: ssh-agent would return a success + message but an empty signature if asked to sign using an unknown key; ok + markus@ + +commit b03ebe2c22b8166e4f64c37737f4278676e3488d +Author: Damien Miller +Date: Thu Jan 15 03:08:58 2015 +1100 + + more --without-openssl + + fix some regressions caused by upstream merges + + enable KRLs now that they no longer require BIGNUMs + +commit bc42cc6fe784f36df225c44c93b74830027cb5a2 +Author: Damien Miller +Date: Thu Jan 15 03:08:29 2015 +1100 + + kludge around tun API mismatch betterer + +commit c332110291089b624fa0951fbf2d1ee6de525b9f +Author: Damien Miller +Date: Thu Jan 15 02:59:51 2015 +1100 + + some systems lack SO_REUSEPORT + +commit 83b9678a62cbdc74eb2031cf1e1e4ffd58e233ae +Author: Damien Miller +Date: Thu Jan 15 02:35:50 2015 +1100 + + fix merge botch + +commit 0cdc5a3eb6fb383569a4da2a30705d9b90428d6b +Author: Damien Miller +Date: Thu Jan 15 02:35:33 2015 +1100 + + unbreak across API change + +commit 6e2549ac2b5e7f96cbc2d83a6e0784b120444b47 +Author: Damien Miller +Date: Thu Jan 15 02:30:18 2015 +1100 + + need includes.h for portable OpenSSH + +commit 72ef7c148c42db7d5632a29f137f8b87b579f2d9 +Author: Damien Miller +Date: Thu Jan 15 02:21:31 2015 +1100 + + support --without-openssl at configure time + + Disables and removes dependency on OpenSSL. Many features don't + work and the set of crypto options is greatly restricted. This + will only work on system with native arc4random or /dev/urandom. + + Considered highly experimental for now. + +commit 4f38c61c68ae7e3f9ee4b3c38bc86cd39f65ece9 +Author: Damien Miller +Date: Thu Jan 15 02:28:00 2015 +1100 + + add files missed in last commit + +commit a165bab605f7be55940bb8fae977398e8c96a46d +Author: djm@openbsd.org +Date: Wed Jan 14 15:02:39 2015 +0000 + + upstream commit + + avoid BIGNUM in KRL code by using a simple bitmap; + feedback and ok markus + +commit 7d845f4a0b7ec97887be204c3760e44de8bf1f32 +Author: djm@openbsd.org +Date: Wed Jan 14 13:54:13 2015 +0000 + + upstream commit + + update sftp client and server to new buffer API. pretty + much just mechanical changes; with & ok markus + +commit 139ca81866ec1b219c717d17061e5e7ad1059e2a +Author: markus@openbsd.org +Date: Wed Jan 14 13:09:09 2015 +0000 + + upstream commit + + switch to sshbuf/sshkey; with & ok djm@ + +commit 81bfbd0bd35683de5d7f2238b985e5f8150a9180 +Author: Damien Miller +Date: Wed Jan 14 21:48:18 2015 +1100 + + support --without-openssl at configure time + + Disables and removes dependency on OpenSSL. Many features don't + work and the set of crypto options is greatly restricted. This + will only work on system with native arc4random or /dev/urandom. + + Considered highly experimental for now. + +commit 54924b53af15ccdcbb9f89984512b5efef641a31 +Author: djm@openbsd.org +Date: Wed Jan 14 10:46:28 2015 +0000 + + upstream commit + + avoid an warning for the !OPENSSL case + +commit ae8b463217f7c9b66655bfc3945c050ffdaeb861 +Author: markus@openbsd.org +Date: Wed Jan 14 10:30:34 2015 +0000 + + upstream commit + + swith auth-options to new sshbuf/sshkey; ok djm@ + +commit 540e891191b98b89ee90aacf5b14a4a68635e763 +Author: djm@openbsd.org +Date: Wed Jan 14 10:29:45 2015 +0000 + + upstream commit + + make non-OpenSSL aes-ctr work on sshd w/ privsep; ok + markus@ + +commit 60c2c4ea5e1ad0ddfe8b2877b78ed5143be79c53 +Author: markus@openbsd.org +Date: Wed Jan 14 10:24:42 2015 +0000 + + upstream commit + + remove unneeded includes, sync my copyright across files + & whitespace; ok djm@ + +commit 128343bcdb0b60fc826f2733df8cf979ec1627b4 +Author: markus@openbsd.org +Date: Tue Jan 13 19:31:40 2015 +0000 + + upstream commit + + adapt mac.c to ssherr.h return codes (de-fatal) and + simplify dependencies ok djm@ + +commit e7fd952f4ea01f09ceb068721a5431ac2fd416ed +Author: djm@openbsd.org +Date: Tue Jan 13 19:04:35 2015 +0000 + + upstream commit + + sync changes from libopenssh; prepared by markus@ mostly + debug output tweaks, a couple of error return value changes and some other + minor stuff + +commit 76c0480a85675f03a1376167cb686abed01a3583 +Author: Damien Miller +Date: Tue Jan 13 19:38:18 2015 +1100 + + add --without-ssh1 option to configure + + Allows disabling support for SSH protocol 1. + +commit 1f729f0614d1376c3332fa1edb6a5e5cec7e9e03 +Author: djm@openbsd.org +Date: Tue Jan 13 07:39:19 2015 +0000 + + upstream commit + + add sshd_config HostbasedAcceptedKeyTypes and + PubkeyAcceptedKeyTypes options to allow sshd to control what public key types + will be accepted. Currently defaults to all. Feedback & ok markus@ + +commit 816d1538c24209a93ba0560b27c4fda57c3fff65 +Author: markus@openbsd.org +Date: Mon Jan 12 20:13:27 2015 +0000 + + upstream commit + + unbreak parsing of pubkey comments; with gerhard; ok + djm/deraadt + +commit 0097565f849851812df610b7b6b3c4bd414f6c62 +Author: markus@openbsd.org +Date: Mon Jan 12 19:22:46 2015 +0000 + + upstream commit + + missing error assigment on sshbuf_put_string() + +commit a7f49dcb527dd17877fcb8d5c3a9a6f550e0bba5 +Author: djm@openbsd.org +Date: Mon Jan 12 15:18:07 2015 +0000 + + upstream commit + + apparently memcpy(x, NULL, 0) is undefined behaviour + according to C99 (cf. sections 7.21.1 and 7.1.4), so check skip memcpy calls + when length==0; ok markus@ + +commit 905fe30fca82f38213763616d0d26eb6790bde33 +Author: markus@openbsd.org +Date: Mon Jan 12 14:05:19 2015 +0000 + + upstream commit + + free->sshkey_free; ok djm@ + +commit f067cca2bc20c86b110174c3fef04086a7f57b13 +Author: markus@openbsd.org +Date: Mon Jan 12 13:29:27 2015 +0000 + + upstream commit + + allow WITH_OPENSSL w/o WITH_SSH1; ok djm@ + +commit c4bfafcc2a9300d9cfb3c15e75572d3a7d74670d +Author: djm@openbsd.org +Date: Thu Jan 8 13:10:58 2015 +0000 + + upstream commit + + adjust for sshkey_load_file() API change + +commit e752c6d547036c602b89e9e704851463bd160e32 +Author: djm@openbsd.org +Date: Thu Jan 8 13:44:36 2015 +0000 + + upstream commit + + fix ssh_config FingerprintHash evaluation order; from Petr + Lautrbach + +commit ab24ab847b0fc94c8d5e419feecff0bcb6d6d1bf +Author: djm@openbsd.org +Date: Thu Jan 8 10:15:45 2015 +0000 + + upstream commit + + reorder hostbased key attempts to better match the + default hostkey algorithms order in myproposal.h; ok markus@ + +commit 1195f4cb07ef4b0405c839293c38600b3e9bdb46 +Author: djm@openbsd.org +Date: Thu Jan 8 10:14:08 2015 +0000 + + upstream commit + + deprecate key_load_private_pem() and + sshkey_load_private_pem() interfaces. Refactor the generic key loading API to + not require pathnames to be specified (they weren't really used). + + Fixes a few other things en passant: + + Makes ed25519 keys work for hostbased authentication (ssh-keysign + previously used the PEM-only routines). + + Fixes key comment regression bz#2306: key pathnames were being lost as + comment fields. + + ok markus@ + +commit febbe09e4e9aff579b0c5cc1623f756862e4757d +Author: tedu@openbsd.org +Date: Wed Jan 7 18:15:07 2015 +0000 + + upstream commit + + workaround for the Meyer, et al, Bleichenbacher Side + Channel Attack. fake up a bignum key before RSA decryption. discussed/ok djm + markus + +commit 5191df927db282d3123ca2f34a04d8d96153911a +Author: djm@openbsd.org +Date: Tue Dec 23 22:42:48 2014 +0000 + + upstream commit + + KNF and add a little more debug() + +commit 8abd80315d3419b20e6938f74d37e2e2b547f0b7 +Author: jmc@openbsd.org +Date: Mon Dec 22 09:26:31 2014 +0000 + + upstream commit + + add fingerprinthash to the options list; + +commit 296ef0560f60980da01d83b9f0e1a5257826536f +Author: jmc@openbsd.org +Date: Mon Dec 22 09:24:59 2014 +0000 + + upstream commit + + tweak previous; + +commit 462082eacbd37778a173afb6b84c6f4d898a18b5 +Author: Damien Miller +Date: Tue Dec 30 08:16:11 2014 +1100 + + avoid uninitialised free of ldns_res + + If an invalid rdclass was passed to getrrsetbyname() then + this would execute a free on an uninitialised pointer. + OpenSSH only ever calls this with a fixed and valid rdclass. + + Reported by Joshua Rogers + +commit 01b63498801053f131a0740eb9d13faf35d636c8 +Author: Damien Miller +Date: Mon Dec 29 18:10:18 2014 +1100 + + pull updated OpenBSD BCrypt PBKDF implementation + + Includes fix for 1 byte output overflow for large key length + requests (not reachable in OpenSSH). + + Pointed out by Joshua Rogers + +commit c528c1b4af2f06712177b3de9b30705752f7cbcb +Author: Damien Miller +Date: Tue Dec 23 15:26:13 2014 +1100 + + fix variable name for IPv6 case in construct_utmpx + + patch from writeonce AT midipix.org via bz#2296 + +commit 293cac52dcda123244b2e594d15592e5e481c55e +Author: Damien Miller +Date: Mon Dec 22 16:30:42 2014 +1100 + + include and use OpenBSD netcat in regress/ + +commit 8f6784f0cb56dc4fd00af3e81a10050a5785228d +Author: djm@openbsd.org +Date: Mon Dec 22 09:05:17 2014 +0000 + + upstream commit + + mention ssh -Q feature to list supported { MAC, cipher, + KEX, key } algorithms in more places and include the query string used to + list the relevant information; bz#2288 + +commit 449e11b4d7847079bd0a2daa6e3e7ea03d8ef700 +Author: jmc@openbsd.org +Date: Mon Dec 22 08:24:17 2014 +0000 + + upstream commit + + tweak previous; + +commit 4bea0ab3290c0b9dd2aa199e932de8e7e18062d6 +Author: djm@openbsd.org +Date: Mon Dec 22 08:06:03 2014 +0000 + + upstream commit + + regression test for multiple required pubkey authentication; + ok markus@ + +commit f1c4d8ec52158b6f57834b8cd839605b0a33e7f2 +Author: djm@openbsd.org +Date: Mon Dec 22 08:04:23 2014 +0000 + + upstream commit + + correct description of what will happen when a + AuthorizedKeysCommand is specified but AuthorizedKeysCommandUser is not (sshd + will refuse to start) + +commit 161cf419f412446635013ac49e8c660cadc36080 +Author: djm@openbsd.org +Date: Mon Dec 22 07:55:51 2014 +0000 + + upstream commit + + make internal handling of filename arguments of "none" + more consistent with ssh. "none" arguments are now replaced with NULL when + the configuration is finalised. + + Simplifies checking later on (just need to test not-NULL rather than + that + strcmp) and cleans up some inconsistencies. ok markus@ + +commit f69b69b8625be447b8826b21d87713874dac25a6 +Author: djm@openbsd.org +Date: Mon Dec 22 07:51:30 2014 +0000 + + upstream commit + + remember which public keys have been used for + authentication and refuse to accept previously-used keys. + + This allows AuthenticationMethods=publickey,publickey to require + that users authenticate using two _different_ pubkeys. + + ok markus@ + +commit 46ac2ed4677968224c4ca825bc98fc68dae183f0 +Author: djm@openbsd.org +Date: Mon Dec 22 07:24:11 2014 +0000 + + upstream commit + + fix passing of wildcard forward bind addresses when + connection multiplexing is in use; patch from Sami Hartikainen via bz#2324; + ok dtucker@ + +commit 0d1b241a262e4d0a6bbfdd595489ab1b853c43a1 +Author: djm@openbsd.org +Date: Mon Dec 22 06:14:29 2014 +0000 + + upstream commit + + make this slightly easier to diff against portable + +commit 0715bcdddbf68953964058f17255bf54734b8737 +Author: Damien Miller +Date: Mon Dec 22 13:47:07 2014 +1100 + + add missing regress output file + +commit 1e30483c8ad2c2f39445d4a4b6ab20c241e40593 +Author: djm@openbsd.org +Date: Mon Dec 22 02:15:52 2014 +0000 + + upstream commit + + adjust for new SHA256 key fingerprints and + slightly-different MD5 hex fingerprint format + +commit 6b40567ed722df98593ad8e6a2d2448fc2b4b151 +Author: djm@openbsd.org +Date: Mon Dec 22 01:14:49 2014 +0000 + + upstream commit + + poll changes to netcat (usr.bin/netcat.c r1.125) broke + this test; fix it by ensuring more stdio fds are sent to devnull + +commit a5375ccb970f49dddf7d0ef63c9b713ede9e7260 +Author: jmc@openbsd.org +Date: Sun Dec 21 23:35:14 2014 +0000 + + upstream commit + + tweak previous; + +commit b79efde5c3badf5ce4312fe608d8307eade533c5 +Author: djm@openbsd.org +Date: Sun Dec 21 23:12:42 2014 +0000 + + upstream commit + + document FingerprintHash here too + +commit d16bdd8027dd116afa01324bb071a4016cdc1a75 +Author: Damien Miller +Date: Mon Dec 22 10:18:09 2014 +1100 + + missing include for base64 encoding + +commit 56d1c83cdd1ac76f1c6bd41e01e80dad834f3994 +Author: djm@openbsd.org +Date: Sun Dec 21 22:27:55 2014 +0000 + + upstream commit + + Add FingerprintHash option to control algorithm used for + key fingerprints. Default changes from MD5 to SHA256 and format from hex to + base64. + + Feedback and ok naddy@ markus@ + +commit 058f839fe15c51be8b3a844a76ab9a8db550be4f +Author: djm@openbsd.org +Date: Thu Dec 18 23:58:04 2014 +0000 + + upstream commit + + don't count partial authentication success as a failure + against MaxAuthTries; ok deraadt@ + +commit c7219f4f54d64d6dde66dbcf7a2699daa782d2a1 +Author: djm@openbsd.org +Date: Fri Dec 12 00:02:17 2014 +0000 + + upstream commit + + revert chunk I didn't mean to commit yet; via jmc@ + +commit 7de5991aa3997e2981440f39c1ea01273a0a2c7b +Author: Damien Miller +Date: Thu Dec 18 11:44:06 2014 +1100 + + upstream libc change + + revision 1.2 + date: 2014/12/08 03:45:00; author: bcook; state: Exp; lines: +2 -2; commitid: 7zWEBgJJOCZ2hvTV; + avoid left shift overflow in reallocarray. + + Some 64-bit platforms (e.g. Windows 64) have a 32-bit long. So, shifting + 1UL 32-bits to the left causes an overflow. This replaces the constant 1UL with + (size_t)1 so that we get the correct constant size for the platform. + + discussed with tedu@ & deraadt@ + +commit 2048f85a5e6da8bc6e0532efe02ecfd4e63c978c +Author: Damien Miller +Date: Thu Dec 18 10:15:49 2014 +1100 + + include CFLAGS in gnome askpass targets + + from Fedora + +commit 48b68ce19ca42fa488960028048dec023f7899bb +Author: djm@openbsd.org +Date: Thu Dec 11 08:20:09 2014 +0000 + + upstream commit + + explicitly include sys/param.h in files that use the + howmany() macro; from portable + +commit d663bea30a294d440fef4398e5cd816317bd4518 +Author: djm@openbsd.org +Date: Thu Dec 11 05:25:06 2014 +0000 + + upstream commit + + mention AuthorizedKeysCommandUser must be set for + AuthorizedKeysCommand to be run; bz#2287 + +commit 17bf3d81e00f2abb414a4fd271118cf4913f049f +Author: djm@openbsd.org +Date: Thu Dec 11 05:13:28 2014 +0000 + + upstream commit + + show in debug output which hostkeys are being tried when + attempting hostbased auth; patch from Iain Morgan + +commit da0277e3717eadf5b15e03379fc29db133487e94 +Author: djm@openbsd.org +Date: Thu Dec 11 04:16:14 2014 +0000 + + upstream commit + + Make manual reflect reality: sftp-server's -d option + accepts a "%d" option, not a "%h" one. + + bz#2316; reported by Kirk Wolf + +commit 4cf87f4b81fa9380bce5fcff7b0f8382ae3ad996 +Author: djm@openbsd.org +Date: Wed Dec 10 01:24:09 2014 +0000 + + upstream commit + + better error value for invalid signature length + +commit 4bfad14ca56f8ae04f418997816b4ba84e2cfc3c +Author: Darren Tucker +Date: Wed Dec 10 02:12:51 2014 +1100 + + Resync more with OpenBSD's rijndael.c, in particular "#if 0"-ing out some + unused code. Should fix compile error reported by plautrba at redhat. + +commit 642652d280499691c8212ec6b79724b50008ce09 +Author: Darren Tucker +Date: Wed Dec 10 01:32:23 2014 +1100 + + Add reallocarray to compat library + +commit 3dfd8d93dfcc69261f5af99df56f3ff598581979 +Author: djm@openbsd.org +Date: Thu Dec 4 22:31:50 2014 +0000 + + upstream commit + + add tests for new client RevokedHostKeys option; refactor + to make it a bit more readable + +commit a31046cad1aed16a0b55171192faa6d02665ccec +Author: krw@openbsd.org +Date: Wed Nov 19 13:35:37 2014 +0000 + + upstream commit + + Nuke yet more obvious #include duplications. + + ok deraadt@ + +commit a7c762e5b2c1093542c0bc1df25ccec0b4cf479f +Author: djm@openbsd.org +Date: Thu Dec 4 20:47:36 2014 +0000 + + upstream commit + + key_in_file() wrapper is no longer used + +commit 5e39a49930d885aac9c76af3129332b6e772cd75 +Author: djm@openbsd.org +Date: Thu Dec 4 02:24:32 2014 +0000 + + upstream commit + + add RevokedHostKeys option for the client + + Allow textfile or KRL-based revocation of hostkeys. + +commit 74de254bb92c684cf53461da97f52d5ba34ded80 +Author: djm@openbsd.org +Date: Thu Dec 4 01:49:59 2014 +0000 + + upstream commit + + convert KRL code to new buffer API + + ok markus@ + +commit db995f2eed5fc432598626fa3e30654503bf7151 +Author: millert@openbsd.org +Date: Wed Nov 26 18:34:51 2014 +0000 + + upstream commit + + Prefer setvbuf() to setlinebuf() for portability; ok + deraadt@ + +commit 72bba3d179ced8b425272efe6956a309202a91f3 +Author: jsg@openbsd.org +Date: Mon Nov 24 03:39:22 2014 +0000 + + upstream commit + + Fix crashes in the handling of the sshd config file found + with the afl fuzzer. + + ok deraadt@ djm@ + +commit 867f49c666adcfe92bf539d9c37c1accdea08bf6 +Author: Damien Miller +Date: Wed Nov 26 13:22:41 2014 +1100 + + Avoid Cygwin ssh-host-config reading /etc/group + + Patch from Corinna Vinschen + +commit 8b66f36291a721b1ba7c44f24a07fdf39235593e +Author: Damien Miller +Date: Wed Nov 26 13:20:35 2014 +1100 + + allow custom service name for sshd on Cygwin + + Permits the use of multiple sshd running with different service names. + + Patch by Florian Friesdorf via Corinna Vinschen + +commit 08c0eebf55d70a9ae1964399e609288ae3186a0c +Author: jmc@openbsd.org +Date: Sat Nov 22 19:21:03 2014 +0000 + + upstream commit + + restore word zapped in previous, and remove some useless + "No" macros; + +commit a1418a0033fba43f061513e992e1cbcc3343e563 +Author: deraadt@openbsd.org +Date: Sat Nov 22 18:15:41 2014 +0000 + + upstream commit + + /dev/random has created the same effect as /dev/arandom + (and /dev/urandom) for quite some time. Mop up the last few, by using + /dev/random where we actually want it, or not even mentioning arandom where + it is irrelevant. + +commit b6de5ac9ed421362f479d1ad4fa433d2e25dad5b +Author: djm@openbsd.org +Date: Fri Nov 21 01:00:38 2014 +0000 + + upstream commit + + fix NULL pointer dereference crash on invalid timestamp + + found using Michal Zalewski's afl fuzzer + +commit a1f8110cd5ed818d59b3a2964fab7de76e92c18e +Author: mikeb@openbsd.org +Date: Tue Nov 18 22:38:48 2014 +0000 + + upstream commit + + Sync AES code to the one shipped in OpenSSL/LibreSSL. + + This includes a commit made by Andy Polyakov + to the OpenSSL source tree on Wed, 28 Jun 2006 with the following + message: "Mitigate cache-collision timing attack on last round." + + OK naddy, miod, djm + +commit 335c83d5f35d8620e16b8aa26592d4f836e09ad2 +Author: krw@openbsd.org +Date: Tue Nov 18 20:54:28 2014 +0000 + + upstream commit + + Nuke more obvious #include duplications. + + ok deraadt@ millert@ tedu@ + +commit 51b64e44121194ae4bf153dee391228dada2abcb +Author: djm@openbsd.org +Date: Mon Nov 17 00:21:40 2014 +0000 + + upstream commit + + fix KRL generation when multiple CAs are in use + + We would generate an invalid KRL when revoking certs by serial + number for multiple CA keys due to a section being written out + twice. + + Also extend the regress test to catch this case by having it + produce a multi-CA KRL. + + Reported by peter AT pean.org + +commit d2d51003a623e21fb2b25567c4878d915e90aa2a +Author: djm@openbsd.org +Date: Tue Nov 18 01:02:25 2014 +0000 + + upstream commit + + fix NULL pointer dereference crash in key loading + + found by Michal Zalewski's AFL fuzzer + +commit 9f9fad0191028edc43d100d0ded39419b6895fdf +Author: djm@openbsd.org +Date: Mon Nov 17 00:21:40 2014 +0000 + + upstream commit + + fix KRL generation when multiple CAs are in use + + We would generate an invalid KRL when revoking certs by serial + number for multiple CA keys due to a section being written out + twice. + + Also extend the regress test to catch this case by having it + produce a multi-CA KRL. + + Reported by peter AT pean.org + +commit da8af83d3f7ec00099963e455010e0ed1d7d0140 +Author: bentley@openbsd.org +Date: Sat Nov 15 14:41:03 2014 +0000 + + upstream commit + + Reduce instances of `` '' in manuals. + + troff displays these as typographic quotes, but nroff implementations + almost always print them literally, which rarely has the intended effect + with modern fonts, even in stock xterm. + + These uses of `` '' can be replaced either with more semantic alternatives + or with Dq, which prints typographic quotes in a UTF-8 locale (but will + automatically fall back to `` '' in an ASCII locale). + + improvements and ok schwarze@ + +commit fc302561369483bb755b17f671f70fb894aec01d +Author: djm@openbsd.org +Date: Mon Nov 10 22:25:49 2014 +0000 + + upstream commit + + mux-related manual tweaks + + mention ControlPersist=0 is the same as ControlPersist=yes + + recommend that ControlPath sockets be placed in a og-w directory + +commit 0e4cff5f35ed11102fe3783779960ef07e0cd381 +Author: Damien Miller +Date: Wed Nov 5 11:01:31 2014 +1100 + + Prepare scripts for next Cygwin release + + Makes the Cygwin-specific ssh-user-config script independent of the + existence of /etc/passwd. The next Cygwin release will allow to + generate passwd and group entries from the Windows account DBs, so the + scripts have to adapt. + + from Corinna Vinschen + +commit 7d0ba5336651731949762eb8877ce9e3b52df436 +Author: Damien Miller +Date: Thu Oct 30 10:45:41 2014 +1100 + + include version number in OpenSSL-too-old error + +commit 3bcb92e04d9207e9f78d82f7918c6d3422054ce9 +Author: lteo@openbsd.org +Date: Fri Oct 24 02:01:20 2014 +0000 + + upstream commit + + Remove unnecessary include: netinet/in_systm.h is not needed + by these programs. + + NB. skipped for portable + + ok deraadt@ millert@ + +commit 6fdcaeb99532e28a69f1a1599fbd540bb15b70a0 +Author: djm@openbsd.org +Date: Mon Oct 20 03:43:01 2014 +0000 + + upstream commit + + whitespace + +commit 165bc8786299e261706ed60342985f9de93a7461 +Author: daniel@openbsd.org +Date: Tue Oct 14 03:09:59 2014 +0000 + + upstream commit + + plug a memory leak; from Maxime Villard. + + ok djm@ + +commit b1ba15f3885947c245c2dbfaad0a04ba050abea0 +Author: jmc@openbsd.org +Date: Thu Oct 9 06:21:31 2014 +0000 + + upstream commit + + tweak previous; + +commit 259a02ebdf74ad90b41d116ecf70aa823fa4c6e7 +Author: djm@openbsd.org +Date: Mon Oct 13 00:38:35 2014 +0000 + + upstream commit + + whitespace + +commit 957fbceb0f3166e41b76fdb54075ab3b9cc84cba +Author: djm@openbsd.org +Date: Wed Oct 8 22:20:25 2014 +0000 + + upstream commit + + Tweak config reparsing with host canonicalisation + + Make the second pass through the config files always run when + hostname canonicalisation is enabled. + + Add a "Match canonical" criteria that allows ssh_config Match + blocks to trigger only in the second config pass. + + Add a -G option to ssh that causes it to parse its configuration + and dump the result to stdout, similar to "sshd -T" + + Allow ssh_config Port options set in the second config parse + phase to be applied (they were being ignored). + + bz#2267 bz#2286; ok markus + +commit 5c0dafd38bf66feeeb45fa0741a5baf5ad8039ba +Author: djm@openbsd.org +Date: Wed Oct 8 22:15:27 2014 +0000 + + upstream commit + + another -Wpointer-sign from clang + +commit bb005dc815ebda9af3ae4b39ca101c4da918f835 +Author: djm@openbsd.org +Date: Wed Oct 8 22:15:06 2014 +0000 + + upstream commit + + fix a few -Wpointer-sign warnings from clang + +commit 3cc1fbb4fb0e804bfb873fd363cea91b27fc8188 +Author: djm@openbsd.org +Date: Wed Oct 8 21:45:48 2014 +0000 + + upstream commit + + parse cert sections using nested buffers to reduce + copies; ok markus + +commit 4a45922aebf99164e2fc83d34fe55b11ae1866ef +Author: djm@openbsd.org +Date: Mon Oct 6 00:47:15 2014 +0000 + + upstream commit + + correct options in usage(); from mancha1 AT zoho.com + +commit 48dffd5bebae6fed0556dc5c36cece0370690618 +Author: djm@openbsd.org +Date: Tue Sep 9 09:45:36 2014 +0000 + + upstream commit + + mention permissions on tun(4) devices in PermitTunnel + documentation; bz#2273 + +commit a5883d4eccb94b16c355987f58f86a7dee17a0c2 +Author: djm@openbsd.org +Date: Wed Sep 3 18:55:07 2014 +0000 + + upstream commit + + tighten permissions on pty when the "tty" group does + not exist; pointed out by Corinna Vinschen; ok markus + +commit 180bcb406b58bf30723c01a6b010e48ee626dda8 +Author: sobrado@openbsd.org +Date: Sat Aug 30 16:32:25 2014 +0000 + + upstream commit + + typo. + +commit f70b22bcdd52f6bf127047b3584371e6e5d45627 +Author: sobrado@openbsd.org +Date: Sat Aug 30 15:33:50 2014 +0000 + + upstream commit + + improve capitalization for the Ed25519 public-key + signature system. + + ok djm@ + +commit 7df8818409c752cf3f0c3f8044fe9aebed8647bd +Author: doug@openbsd.org +Date: Thu Aug 21 01:08:52 2014 +0000 + + upstream commit + + Free resources on error in mkstemp and fdopen + + ok djm@ + +commit 40ba4c9733aaed08304714faeb61529f18da144b +Author: deraadt@openbsd.org +Date: Wed Aug 20 01:28:55 2014 +0000 + + upstream commit + + djm how did you make a typo like that... + +commit 57d378ec9278ba417a726f615daad67d157de666 +Author: djm@openbsd.org +Date: Tue Aug 19 23:58:28 2014 +0000 + + upstream commit + + When dumping the server configuration (sshd -T), print + correct KEX, MAC and cipher defaults. Spotted by Iain Morgan + +commit 7ff880ede5195d0b17e7f1e3b6cfbc4cb6f85240 +Author: djm@openbsd.org +Date: Tue Aug 19 23:57:18 2014 +0000 + + upstream commit + + ~-expand lcd paths + +commit 4460a7ad0c78d4cd67c467f6e9f4254d0404ed59 +Author: Damien Miller +Date: Sun Oct 12 12:35:48 2014 +1100 + + remove duplicated KEX_DH1 entry + +commit c9b8426a616138d0d762176c94f51aff3faad5ff +Author: Damien Miller +Date: Thu Oct 9 10:34:06 2014 +1100 + + remove ChangeLog file + + Commit logs will be generated from git at release time. + +commit 81d18ff7c93a04affbf3903e0963859763219aed +Author: Damien Miller +Date: Tue Oct 7 21:24:25 2014 +1100 + + delete contrib/caldera directory + +commit 0ec9e87d3638206456968202f05bb5123670607a +Author: Damien Miller +Date: Tue Oct 7 19:57:27 2014 +1100 + + test commit + +commit 8fb65a44568701b779f3d77326bceae63412d28d +Author: Damien Miller +Date: Tue Oct 7 09:21:49 2014 +1100 + + - (djm) Release OpenSSH-6.7 + +commit e8c9f2602c46f6781df5e52e6cd8413dab4602a3 +Author: Damien Miller +Date: Fri Oct 3 09:24:56 2014 +1000 + + - (djm) [sshd_config.5] typo; from Iain Morgan + +commit 703b98a26706f5083801d11059486d77491342ae +Author: Damien Miller +Date: Wed Oct 1 09:43:07 2014 +1000 + + - (djm) [openbsd-compat/Makefile.in openbsd-compat/kludge-fd_set.c] + [openbsd-compat/openbsd-compat.h] Kludge around bad glibc + _FORTIFY_SOURCE check that doesn't grok heap-allocated fd_sets; + ok dtucker@ + +commit 0fa0ed061bbfedb0daa705e220748154a84c3413 +Author: Damien Miller +Date: Wed Sep 10 08:15:34 2014 +1000 + + - (djm) [sandbox-seccomp-filter.c] Allow mremap and exit for DietLibc; + patch from Felix von Leitner; ok dtucker + +commit ad7d23d461c3b7e1dcb15db13aee5f4b94dc1a95 +Author: Darren Tucker +Date: Tue Sep 9 12:23:10 2014 +1000 + + 20140908 + - (dtucker) [INSTALL] Update info about egd. ok djm@ + +commit 2a8699f37cc2515e3bc60e0c677ba060f4d48191 +Author: Damien Miller +Date: Thu Sep 4 03:46:05 2014 +1000 + + - (djm) [openbsd-compat/arc4random.c] Zero seed after keying PRNG + +commit 44988defb1f5e3afe576d86000365e1f07a1b494 +Author: Damien Miller +Date: Wed Sep 3 05:35:32 2014 +1000 + + - (djm) [contrib/cygwin/ssh-host-config] Fix old code leading to + permissions/ACLs; from Corinna Vinschen + +commit 23f269562b7537b2f6f5014e50a25e5dcc55a837 +Author: Damien Miller +Date: Wed Sep 3 05:33:25 2014 +1000 + + - (djm) [defines.h sshbuf.c] Move __predict_true|false to defines.h and + conditionalise to avoid duplicate definition. + +commit 41c8de2c0031cf59e7cf0c06b5bcfbf4852c1fda +Author: Damien Miller +Date: Sat Aug 30 16:23:06 2014 +1000 + + - (djm) [Makefile.in] Make TEST_SHELL a variable; "good idea" tim@ + +commit d7c81e216a7bd9eed6e239c970d9261bb1651947 +Author: Damien Miller +Date: Sat Aug 30 04:18:28 2014 +1000 + + - (djm) [openbsd-compat/openssl-compat.h] add include guard + +commit 4687802dda57365b984b897fc3c8e2867ea09b22 +Author: Damien Miller +Date: Sat Aug 30 03:29:19 2014 +1000 + + - (djm) [misc.c] Missing newline between functions + +commit 51c77e29220dee87c53be2dc47092934acab26fe +Author: Damien Miller +Date: Sat Aug 30 02:30:30 2014 +1000 + + - (djm) [openbsd-compat/openssl-compat.h] add + OPENSSL_[RD]SA_MAX_MODULUS_BITS defines for OpenSSL that lacks them + +commit 3d673d103bad35afaec6e7ef73e5277216ce33a3 +Author: Damien Miller +Date: Wed Aug 27 06:32:01 2014 +1000 + + - (djm) [openbsd-compat/explicit_bzero.c] implement explicit_bzero() + using memset_s() where possible; improve fallback to indirect bzero + via a volatile pointer to give it more of a chance to avoid being + optimised away. + +commit 146218ac11a1eb0dcade6f793d7acdef163b5ddc +Author: Damien Miller +Date: Wed Aug 27 04:11:55 2014 +1000 + + - (djm) [monitor.c sshd.c] SIGXFSZ needs to be ignored in postauth + monitor, not preauth; bz#2263 + +commit 1b215c098b3b37e38aa4e4c91bb908eee41183b1 +Author: Damien Miller +Date: Wed Aug 27 04:04:40 2014 +1000 + + - (djm) [regress/unittests/sshbuf/test_sshbuf_getput_crypto.c] + [regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c] + [regress/unittests/sshkey/common.c] + [regress/unittests/sshkey/test_file.c] + [regress/unittests/sshkey/test_fuzz.c] + [regress/unittests/sshkey/test_sshkey.c] Don't include openssl/ec.h + on !ECC OpenSSL systems + +commit ad013944af0a19e3f612089d0099bb397cf6502d +Author: Damien Miller +Date: Tue Aug 26 09:27:28 2014 +1000 + + - (djm) [INSTALL] Recommend libcrypto be built -fPIC, mention LibreSSL, + update OpenSSL version requirement. + +commit ed126de8ee04c66640a0ea2697c4aaf36801f100 +Author: Damien Miller +Date: Tue Aug 26 08:37:47 2014 +1000 + + - (djm) [bufec.c] Skip this file on !ECC OpenSSL + +commit 9c1dede005746864a4fdb36a7cdf6c51296ca909 +Author: Damien Miller +Date: Sun Aug 24 03:01:06 2014 +1000 + + - (djm) [sftp-server.c] Some systems (e.g. Irix) have prctl() but not + PR_SET_DUMPABLE, so adjust ifdef; reported by Tom Christensen + +commit d244a5816fd1312a33404b436e4dd83594f1119e +Author: Damien Miller +Date: Sat Aug 23 17:06:49 2014 +1000 + + - (djm) [configure.ac] We now require a working vsnprintf everywhere (not + just for systems that lack asprintf); check for it always and extend + test to catch more brokenness. Fixes builds on Solaris <= 9 + +commit 4cec036362a358e398e6a2e6d19d8e5780558634 +Author: Damien Miller +Date: Sat Aug 23 03:11:09 2014 +1000 + + - (djm) [sshd.c] Ignore SIGXFSZ in preauth monitor child; can explode on + lastlog writing on platforms with high UIDs; bz#2263 + +commit 394a60f2598d28b670d934b93942a3370b779b39 +Author: Damien Miller +Date: Fri Aug 22 18:06:20 2014 +1000 + + - (djm) [configure.ac] double braces to appease autoconf + +commit 4d69aeabd6e60afcdc7cca177ca751708ab79a9d +Author: Damien Miller +Date: Fri Aug 22 17:48:27 2014 +1000 + + - (djm) [openbsd-compat/bsd-snprintf.c] Fix compilation failure (prototype/ + definition mismatch) and warning for broken/missing snprintf case. + +commit 0c11f1ac369d2c0aeb0ab0458a7cd04c72fe5e9e +Author: Damien Miller +Date: Fri Aug 22 17:36:56 2014 +1000 + + - (djm) [sshbuf-getput-crypto.c] Fix compilation when OpenSSL lacks ECC + +commit 6d62784b8973340b251fea6b04890f471adf28db +Author: Damien Miller +Date: Fri Aug 22 17:36:19 2014 +1000 + + - (djm) [configure.ac] include leading zero characters in OpenSSL version + number; fixes test for unsupported versions + +commit 4f1ff1ed782117f5d5204d4e91156ed5da07cbb7 +Author: Damien Miller +Date: Thu Aug 21 15:54:50 2014 +1000 + + - (djm) [regress/unittests/test_helper/test_helper.c] Fix for systems that + don't set __progname. Diagnosed by Tom Christensen. + +commit 005a64da0f457410045ef0bfa93c863c2450447d +Author: Damien Miller +Date: Thu Aug 21 10:48:41 2014 +1000 + + - (djm) [key.h] Fix ifdefs for no-ECC OpenSSL + +commit aa6598ebb3343c7380e918388e10e8ca5852b613 +Author: Damien Miller +Date: Thu Aug 21 10:47:54 2014 +1000 + + - (djm) [Makefile.in] fix reference to libtest_helper.a in sshkey test too. + +commit 54703e3cf63f0c80d4157e5ad7dbc2b363ee2c56 +Author: Damien Miller +Date: Wed Aug 20 11:10:51 2014 +1000 + + - (djm) [contrib/cygwin/README] Correct build instructions; from Corinna + +commit f0935698f0461f24d8d1f1107b476ee5fd4db1cb +Author: Damien Miller +Date: Wed Aug 20 11:06:50 2014 +1000 + + - (djm) [sshkey.h] Fix compilation when OpenSSL lacks ECC + +commit c5089ecaec3b2c02f014f4e67518390702a4ba14 +Author: Damien Miller +Date: Wed Aug 20 11:06:20 2014 +1000 + + - (djm) [Makefile.in] refer to libtest_helper.a by explicit path rather than + -L/-l; fixes linking problems on some platforms + +commit 2195847e503a382f83ee969b0a8bd3dfe0e55c18 +Author: Damien Miller +Date: Wed Aug 20 11:05:03 2014 +1000 + + - (djm) [configure.ac] Check OpenSSL version is supported at configure time; + suggested by Kevin Brott + +commit a75aca1bbc989aa9f8b1b08489d37855f3d24d1a +Author: Damien Miller +Date: Tue Aug 19 11:36:07 2014 +1000 + + - (djm) [INSTALL contrib/caldera/openssh.spec contrib/cygwin/README] + [contrib/redhat/openssh.spec contrib/suse/openssh.spec] Remove mentions + of TCP wrappers. + +commit 3f022b5a9477abceeb1bbeab04b055f3cc7ca8f6 +Author: Damien Miller +Date: Tue Aug 19 11:32:34 2014 +1000 + + - (djm) [ssh-dss.c] Include openssl/dsa.h for DSA_SIG + +commit 88137902632aceb923990e98cf5dc923bb3ef2f5 +Author: Damien Miller +Date: Tue Aug 19 11:28:11 2014 +1000 + + - (djm) [sshbuf.h] Fix compilation on systems without OPENSSL_HAS_ECC. + +commit 2f3d1e7fb2eabd3cfbfd8d0f7bdd2f9a1888690b +Author: Damien Miller +Date: Tue Aug 19 11:14:36 2014 +1000 + + - (djm) [myproposal.h] Make curve25519 KEX dependent on + HAVE_EVP_SHA256 instead of OPENSSL_HAS_ECC. + +commit d4e7d59d01a6c7f59e8c1f94a83c086e9a33d8aa +Author: Damien Miller +Date: Tue Aug 19 11:14:17 2014 +1000 + + - (djm) [serverloop.c] Fix syntax error on Cygwin; from Corinna Vinschen + +commit 9eaeea2cf2b6af5f166cfa9ad3c7a90711a147a9 +Author: Damien Miller +Date: Sun Aug 10 11:35:05 2014 +1000 + + - (djm) [README contrib/caldera/openssh.spec] + [contrib/redhat/openssh.spec contrib/suse/openssh.spec] Update versions + +commit f8988fbef0c9801d19fa2f8f4f041690412bec37 +Author: Damien Miller +Date: Fri Aug 1 13:31:52 2014 +1000 + + - (djm) [regress/multiplex.sh] Use -d (detach stdin) flag to disassociate + nc from stdin, it's more portable + +commit 5b3879fd4b7a4e3d43bab8f40addda39bc1169d0 +Author: Damien Miller +Date: Fri Aug 1 12:28:31 2014 +1000 + + - (djm) [regress/multiplex.sh] Instruct nc not to quit as soon as stdin + is closed; avoid regress failures when stdin is /dev/null + +commit a9c46746d266f8a1b092a72b2150682d1af8ebfc +Author: Damien Miller +Date: Fri Aug 1 12:26:49 2014 +1000 + + - (djm) [regress/multiplex.sh] Skip test for non-OpenBSD netcat. We need + a better solution, but this will have to do for now. + +commit 426117b2e965e43f47015942b5be8dd88fe74b88 +Author: Damien Miller +Date: Wed Jul 30 12:33:20 2014 +1000 + + - schwarze@cvs.openbsd.org 2014/07/28 15:40:08 + [sftp-server.8 sshd_config.5] + some systems no longer need /dev/log; + issue noticed by jirib; + ok deraadt + +commit f497794b6962eaf802ab4ac2a7b22ae591cca1d5 +Author: Damien Miller +Date: Wed Jul 30 12:32:46 2014 +1000 + + - dtucker@cvs.openbsd.org 2014/07/25 21:22:03 + [ssh-agent.c] + Clear buffer used for handling messages. This prevents keys being + left in memory after they have been expired or deleted in some cases + (but note that ssh-agent is setgid so you would still need root to + access them). Pointed out by Kevin Burns, ok deraadt + +commit a8a0f65c57c8ecba94d65948e9090da54014dfef +Author: Damien Miller +Date: Wed Jul 30 12:32:28 2014 +1000 + + - OpenBSD CVS Sync + - millert@cvs.openbsd.org 2014/07/24 22:57:10 + [ssh.1] + Mention UNIX-domain socket forwarding too. OK jmc@ deraadt@ + +commit 56b840f2b81e14a2f95c203403633a72566736f8 +Author: Damien Miller +Date: Fri Jul 25 08:11:30 2014 +1000 + + - (djm) [regress/multiplex.sh] restore incorrectly deleted line; + pointed out by Christian Hesse + +commit dd417b60d5ca220565d1014e92b7f8f43dc081eb +Author: Darren Tucker +Date: Wed Jul 23 10:41:21 2014 +1000 + + - dtucker@cvs.openbsd.org 2014/07/22 23:35:38 + [regress/unittests/sshkey/testdata/*] + Regenerate test keys with certs signed with ed25519 instead of ecdsa. + These can be used in -portable on platforms that don't support ECDSA. + +commit 40e50211896369dba8f64f3b5e5fd58b76f5ac3f +Author: Darren Tucker +Date: Wed Jul 23 10:35:45 2014 +1000 + + - dtucker@cvs.openbsd.org 2014/07/22 23:57:40 + [regress/unittests/sshkey/mktestdata.sh] + Add $OpenBSD tag to make syncs easier + +commit 07e644251e809b1d4c062cf85bd1146a7e3f5a8a +Author: Darren Tucker +Date: Wed Jul 23 10:34:26 2014 +1000 + + - dtucker@cvs.openbsd.org 2014/07/22 23:23:22 + [regress/unittests/sshkey/mktestdata.sh] + Sign test certs with ed25519 instead of ecdsa so that they'll work in + -portable on platforms that don't have ECDSA in their OpenSSL. ok djm + +commit cea099a7c4eaecb01b001e5453bb4e5c25006c22 +Author: Darren Tucker +Date: Wed Jul 23 10:04:02 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/22 01:32:12 + [regress/multiplex.sh] + change the test for still-open Unix domain sockets to be robust against + nc implementations that produce error messages. from -portable + (Id sync only) + +commit 31eb78078d349b32ea41952ecc944b3ad6cb0d45 +Author: Darren Tucker +Date: Wed Jul 23 09:43:42 2014 +1000 + + - guenther@cvs.openbsd.org 2014/07/22 07:13:42 + [umac.c] + Convert from to the shiney new + ok dtucker@, who also confirmed that -portable handles this already + (ID sync only, includes.h pulls in endian.h if available.) + +commit 820763efef2d19d965602533036c2b4badc9d465 +Author: Darren Tucker +Date: Wed Jul 23 09:40:46 2014 +1000 + + - dtucker@cvs.openbsd.org 2014/07/22 01:18:50 + [key.c] + Prevent spam from key_load_private_pem during hostbased auth. ok djm@ + +commit c4ee219a66f3190fa96cbd45b4d11015685c6306 +Author: Darren Tucker +Date: Wed Jul 23 04:27:50 2014 +1000 + + - (dtucker) [regress/unittests/sshkey/test_{file,fuzz,sshkey}.c] Wrap ecdsa- + specific tests inside OPENSSL_HAS_ECC. + +commit 04f4824940ea3edd60835416ececbae16438968a +Author: Damien Miller +Date: Tue Jul 22 11:31:47 2014 +1000 + + - (djm) [regress/multiplex.sh] change the test for still-open Unix + domain sockets to be robust against nc implementations that produce + error messages. + +commit 5ea4fe00d55453aaa44007330bb4c3181bd9b796 +Author: Damien Miller +Date: Tue Jul 22 09:39:19 2014 +1000 + + - (djm) [regress/multiplex.sh] ssh mux master lost -N somehow; + put it back + +commit 948a1774a79a85f9deba6d74db95f402dee32c69 +Author: Darren Tucker +Date: Tue Jul 22 01:07:11 2014 +1000 + + - (dtucker) [sshkey.c] ifdef out unused variable when compiling without + OPENSSL_HAS_ECC. + +commit c8f610f6cc57ae129758052439d9baf13699097b +Author: Damien Miller +Date: Mon Jul 21 10:23:27 2014 +1000 + + - (djm) [regress/multiplex.sh] Not all netcat accept the -N option. + +commit 0e4e95566cd95c887f69272499b8f3880b3ec0f5 +Author: Damien Miller +Date: Mon Jul 21 09:52:54 2014 +1000 + + - millert@cvs.openbsd.org 2014/07/15 15:54:15 + [forwarding.sh multiplex.sh] + Add support for Unix domain socket forwarding. A remote TCP port + may be forwarded to a local Unix domain socket and vice versa or + both ends may be a Unix domain socket. This is a reimplementation + of the streamlocal patches by William Ahern from: + http://www.25thandclement.com/~william/projects/streamlocal.html + OK djm@ markus@ + +commit 93a87ab27ecdc709169fb24411133998f81e2761 +Author: Darren Tucker +Date: Mon Jul 21 06:30:25 2014 +1000 + + - (dtucker) [regress/unittests/sshkey/ + {common,test_file,test_fuzz,test_sshkey}.c] Wrap stdint.h includes in + ifdefs. + +commit 5573171352ea23df2dc6d2fe0324d023b7ba697c +Author: Darren Tucker +Date: Mon Jul 21 02:24:59 2014 +1000 + + - (dtucker) [cipher.c openbsd-compat/openssl-compat.h] Restore the bits + needed to build AES CTR mode against OpenSSL 0.9.8f and above. ok djm + +commit 74e28682711d005026c7c8f15f96aea9d3c8b5a3 +Author: Tim Rice +Date: Fri Jul 18 20:00:11 2014 -0700 + + - (tim) [openbsd-compat/port-uw.c] Include misc.h for fwd_opts, used + in servconf.h. + +commit d1a0421f8e5e933fee6fb58ee6b9a22c63c8a613 +Author: Darren Tucker +Date: Sat Jul 19 07:23:55 2014 +1000 + + - (dtucker) [key.c sshkey.c] Put new ecdsa bits inside ifdef OPENSSL_HAS_ECC. + +commit f0fe9ea1be62227c130b317769de3d1e736b6dc1 +Author: Darren Tucker +Date: Sat Jul 19 06:33:12 2014 +1000 + + - (dtucker) [Makefile.in] Add a t-exec target to run just the executable + tests. + +commit 450bc1180d4b061434a4b733c5c8814fa30b022b +Author: Darren Tucker +Date: Sat Jul 19 06:23:18 2014 +1000 + + - (dtucker) [auth2-gss.c gss-serv-krb5.c] Include misc.h for fwd_opts, used + in servconf.h. + +commit ab2ec586baad122ed169285c31927ccf58bc7b28 +Author: Damien Miller +Date: Fri Jul 18 15:04:47 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/18 02:46:01 + [ssh-agent.c] + restore umask around listener socket creation (dropped in streamlocal patch + merge) + +commit 357610d15946381ae90c271837dcdd0cdce7145f +Author: Damien Miller +Date: Fri Jul 18 15:04:10 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/17 07:22:19 + [mux.c ssh.c] + reflect stdio-forward ("ssh -W host:port ...") failures in exit status. + previously we were always returning 0. bz#2255 reported by Brendan + Germain; ok dtucker + +commit dad9a4a0b7c2b5d78605f8df28718f116524134e +Author: Damien Miller +Date: Fri Jul 18 15:03:49 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/17 00:12:03 + [key.c] + silence "incorrect passphrase" error spam; reported and ok dtucker@ + +commit f42f7684ecbeec6ce50e0310f80b3d6da2aaf533 +Author: Damien Miller +Date: Fri Jul 18 15:03:27 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/17 00:10:18 + [mux.c] + preserve errno across syscall + +commit 1b83320628cb0733e3688b85bfe4d388a7c51909 +Author: Damien Miller +Date: Fri Jul 18 15:03:02 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/17 00:10:56 + [sandbox-systrace.c] + ifdef SYS_sendsyslog so this will compile without patching on -stable + +commit 6d57656331bcd754d912950e4a18ad259d596e61 +Author: Damien Miller +Date: Fri Jul 18 15:02:06 2014 +1000 + + - jmc@cvs.openbsd.org 2014/07/16 14:48:57 + [ssh.1] + add the streamlocal* options to ssh's -o list; millert says they're + irrelevant for scp/sftp; + + ok markus millert + +commit 7acefbbcbeab725420ea07397ae35992f505f702 +Author: Damien Miller +Date: Fri Jul 18 14:11:24 2014 +1000 + + - millert@cvs.openbsd.org 2014/07/15 15:54:14 + [PROTOCOL auth-options.c auth-passwd.c auth-rh-rsa.c auth-rhosts.c] + [auth-rsa.c auth.c auth1.c auth2-hostbased.c auth2-kbdint.c auth2-none.c] + [auth2-passwd.c auth2-pubkey.c auth2.c canohost.c channels.c channels.h] + [clientloop.c misc.c misc.h monitor.c mux.c packet.c readconf.c] + [readconf.h servconf.c servconf.h serverloop.c session.c ssh-agent.c] + [ssh.c ssh_config.5 sshconnect.c sshconnect1.c sshconnect2.c sshd.c] + [sshd_config.5 sshlogin.c] + Add support for Unix domain socket forwarding. A remote TCP port + may be forwarded to a local Unix domain socket and vice versa or + both ends may be a Unix domain socket. This is a reimplementation + of the streamlocal patches by William Ahern from: + http://www.25thandclement.com/~william/projects/streamlocal.html + OK djm@ markus@ + +commit 6262d760e00714523633bd989d62e273a3dca99a +Author: Damien Miller +Date: Thu Jul 17 09:52:07 2014 +1000 + + - tedu@cvs.openbsd.org 2014/07/11 13:54:34 + [myproposal.h] + by popular demand, add back hamc-sha1 to server proposal for better compat + with many clients still in use. ok deraadt + +commit 9d69d937b46ecba17f16d923e538ceda7b705c7a +Author: Damien Miller +Date: Thu Jul 17 09:49:37 2014 +1000 + + - deraadt@cvs.openbsd.org 2014/07/11 08:09:54 + [sandbox-systrace.c] + Permit use of SYS_sendsyslog from inside the sandbox. Clock is ticking, + update your kernels and sshd soon.. libc will start using sendsyslog() + in about 4 days. + +commit f6293a0b4129826fc2e37e4062f96825df43c326 +Author: Damien Miller +Date: Thu Jul 17 09:01:25 2014 +1000 + + - (djm) [digest-openssl.c] Preserve array order when disabling digests. + Reported by Petr Lautrbach. + +commit 00f9cd230709c04399ef5ff80492d70a55230694 +Author: Damien Miller +Date: Tue Jul 15 10:41:38 2014 +1000 + + - (djm) [configure.ac] Delay checks for arc4random* until after libcrypto + has been located; fixes builds agains libressl-portable + +commit 1d0df3249c87019556b83306c28d4769375c2edc +Author: Damien Miller +Date: Fri Jul 11 09:19:04 2014 +1000 + + - OpenBSD CVS Sync + - benno@cvs.openbsd.org 2014/07/09 14:15:56 + [ssh-add.c] + fix ssh-add crash while loading more than one key + ok markus@ + +commit 7a57eb3d105aa4ced15fb47001092c58811e6d9d +Author: Damien Miller +Date: Wed Jul 9 13:22:31 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/07 08:15:26 + [multiplex.sh] + remove forced-fatal that I stuck in there to test the new cleanup + logic and forgot to remove... + +commit 612f965239a30fe536b11ece1834d9f470aeb029 +Author: Damien Miller +Date: Wed Jul 9 13:22:03 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/06 07:42:03 + [multiplex.sh test-exec.sh] + add a hook to the cleanup() function to kill $SSH_PID if it is set + + use it to kill the mux master started in multiplex.sh (it was being left + around on fatal failures) + +commit d0bb950485ba121e43a77caf434115ed6417b46f +Author: Damien Miller +Date: Wed Jul 9 13:07:28 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/09 03:02:15 + [key.c] + downgrade more error() to debug() to better match what old authfile.c + did; suppresses spurious errors with hostbased authentication enabled + +commit 0070776a038655c57f57e70cd05e4c38a5de9d84 +Author: Damien Miller +Date: Wed Jul 9 13:07:06 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/09 01:45:10 + [sftp.c] + more useful error message when GLOB_NOSPACE occurs; + bz#2254, patch from Orion Poplawski + +commit 079bac2a43c74ef7cf56850afbab3b1932534c50 +Author: Damien Miller +Date: Wed Jul 9 13:06:25 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/07 08:19:12 + [ssh_config.5] + mention that ProxyCommand is executed using shell "exec" to avoid + a lingering process; bz#1977 + +commit 3a48cc090096cf99b9de592deb5f90e444edebfb +Author: Damien Miller +Date: Sun Jul 6 09:32:49 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/05 23:11:48 + [channels.c] + fix remote-forward cancel regression; ok markus@ + +commit 48bae3a38cb578713e676708164f6e7151cc64fa +Author: Damien Miller +Date: Sun Jul 6 09:27:06 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 23:18:35 + [authfile.h] + remove leakmalloc droppings + +commit 72e6b5c9ed5e72ca3a6ccc3177941b7c487a0826 +Author: Damien Miller +Date: Fri Jul 4 09:00:04 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 22:40:43 + [servconf.c servconf.h session.c sshd.8 sshd_config.5] + Add a sshd_config PermitUserRC option to control whether ~/.ssh/rc is + executed, mirroring the no-user-rc authorized_keys option; + bz#2160; ok markus@ + +commit 602943d1179a08dfa70af94f62296ea5e3d6ebb8 +Author: Damien Miller +Date: Fri Jul 4 08:59:41 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 22:33:41 + [channels.c] + allow explicit ::1 and 127.0.0.1 forwarding bind addresses when + GatewayPorts=no; allows client to choose address family; + bz#2222 ok markus@ + +commit 6b37fbb7921d156b31e2c8f39d9e1b6746c34983 +Author: Damien Miller +Date: Fri Jul 4 08:59:24 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 22:23:46 + [sshconnect.c] + when rekeying, skip file/DNS lookup if it is the same as the key sent + during initial key exchange. bz#2154 patch from Iain Morgan; ok markus@ + +commit d2c3cd5f2e47ee24cf7093ce8e948c2e79dfc3fd +Author: Damien Miller +Date: Fri Jul 4 08:59:01 2014 +1000 + + - jsing@cvs.openbsd.org 2014/07/03 12:42:16 + [cipher-chachapoly.c] + Call chacha_ivsetup() immediately before chacha_encrypt_bytes() - this + makes it easier to verify that chacha_encrypt_bytes() is only called once + per chacha_ivsetup() call. + ok djm@ + +commit 686feb560ec43a06ba04da82b50f3c183c947309 +Author: Damien Miller +Date: Thu Jul 3 21:29:38 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 11:16:55 + [auth.c auth.h auth1.c auth2.c] + make the "Too many authentication failures" message include the + user, source address, port and protocol in a format similar to the + authentication success / failure messages; bz#2199, ok dtucker + +commit 0f12341402e18fd9996ec23189b9418d2722453f +Author: Damien Miller +Date: Thu Jul 3 21:28:09 2014 +1000 + + - jmc@cvs.openbsd.org 2014/07/03 07:45:27 + [ssh_config.5] + escape %C since groff thinks it part of an Rs/Re block; + +commit 9c38643c5cd47a19db2cc28279dcc28abadc22b3 +Author: Damien Miller +Date: Thu Jul 3 21:27:46 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 06:39:19 + [ssh.c ssh_config.5] + Add a %C escape sequence for LocalCommand and ControlPath that expands + to a unique identifer based on a has of the tuple of (local host, + remote user, hostname, port). + + Helps avoid exceeding sockaddr_un's miserly pathname limits for mux + control paths. + + bz#2220, based on patch from mancha1 AT zoho.com; ok markus@ + +commit 49d9bfe2b2f3e90cc158a215dffa7675e57e7830 +Author: Damien Miller +Date: Thu Jul 3 21:26:42 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 05:38:17 + [ssh.1] + document that -g will only work in the multiplexed case if applied to + the mux master + +commit ef9f13ba4c58057b2166d1f2e790535da402fbe5 +Author: Damien Miller +Date: Thu Jul 3 21:26:21 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 05:32:36 + [ssh_config.5] + mention '%%' escape sequence in HostName directives and how it may + be used to specify IPv6 link-local addresses + +commit e6a407789e5432dd2e53336fb73476cc69048c54 +Author: Damien Miller +Date: Thu Jul 3 21:25:03 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 04:36:45 + [digest.h] + forward-declare struct sshbuf so consumers don't need to include sshbuf.h + +commit 4a1d3d50f02d0a8a4ef95ea4749293cbfb89f919 +Author: Damien Miller +Date: Thu Jul 3 21:24:40 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 03:47:27 + [ssh-keygen.c] + When hashing or removing hosts using ssh-keygen, don't choke on + @revoked markers and don't remove @cert-authority markers; + bz#2241, reported by mlindgren AT runelind.net + +commit e5c0d52ceb575c3db8c313e0b1aa3845943d7ba8 +Author: Damien Miller +Date: Thu Jul 3 21:24:19 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 03:34:09 + [gss-serv.c session.c ssh-keygen.c] + standardise on NI_MAXHOST for gethostname() string lengths; about + 1/2 the cases were using it already. Fixes bz#2239 en passant + +commit c174a3b7c14e0d178c61219de2aa1110e209950c +Author: Damien Miller +Date: Thu Jul 3 21:23:24 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 03:26:43 + [digest-openssl.c] + use EVP_Digest() for one-shot hash instead of creating, updating, + finalising and destroying a context. + bz#2231, based on patch from Timo Teras + +commit d7ca2cd31ecc4d63a055e2dcc4bf35c13f2db4c5 +Author: Damien Miller +Date: Thu Jul 3 21:23:01 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 03:15:01 + [ssh-add.c] + make stdout line-buffered; saves partial output getting lost when + ssh-add fatal()s part-way through (e.g. when listing keys from an + agent that supports key types that ssh-add doesn't); + bz#2234, reported by Phil Pennock + +commit b1e967c8d7c7578dd0c172d85b3046cf54ea42ba +Author: Damien Miller +Date: Thu Jul 3 21:22:40 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 03:11:03 + [ssh-agent.c] + Only cleanup agent socket in the main agent process and not in any + subprocesses it may have started (e.g. forked askpass). Fixes + agent sockets being zapped when askpass processes fatal(); + bz#2236 patch from Dmitry V. Levin + +commit 61e28e55c3438d796b02ef878bcd28620d452670 +Author: Damien Miller +Date: Thu Jul 3 21:22:22 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 01:45:38 + [sshkey.c] + make Ed25519 keys' title fit properly in the randomart border; bz#2247 + based on patch from Christian Hesse + +commit 9eb4cd9a32c32d40d36450b68ed93badc6a94c68 +Author: Damien Miller +Date: Thu Jul 3 13:29:50 2014 +1000 + + - (djm) [monitor_fdpass.c] Use sys/poll.h if poll.h doesn't exist; + bz#2237 + +commit 8da0fa24934501909408327298097b1629b89eaa +Author: Damien Miller +Date: Thu Jul 3 11:54:19 2014 +1000 + + - (djm) [digest-openssl.c configure.ac] Disable RIPEMD160 if libcrypto + doesn't support it. + +commit 81309c857dd0dbc0a1245a16d621c490ad48cfbb +Author: Damien Miller +Date: Wed Jul 2 17:45:55 2014 +1000 + + - (djm) [regress/Makefile] fix execution of sshkey unit/fuzz test + +commit 82b2482ce68654815ee049b9bf021bb362a35ff2 +Author: Damien Miller +Date: Wed Jul 2 17:43:41 2014 +1000 + + - (djm) [sshkey.c] Conditionalise inclusion of util.h + +commit dd8b1dd7933eb6f5652641b0cdced34a387f2e80 +Author: Damien Miller +Date: Wed Jul 2 17:38:31 2014 +1000 + + - djm@cvs.openbsd.org 2014/06/24 01:14:17 + [Makefile.in regress/Makefile regress/unittests/Makefile] + [regress/unittests/sshkey/Makefile] + [regress/unittests/sshkey/common.c] + [regress/unittests/sshkey/common.h] + [regress/unittests/sshkey/mktestdata.sh] + [regress/unittests/sshkey/test_file.c] + [regress/unittests/sshkey/test_fuzz.c] + [regress/unittests/sshkey/test_sshkey.c] + [regress/unittests/sshkey/tests.c] + [regress/unittests/sshkey/testdata/dsa_1] + [regress/unittests/sshkey/testdata/dsa_1-cert.fp] + [regress/unittests/sshkey/testdata/dsa_1-cert.pub] + [regress/unittests/sshkey/testdata/dsa_1.fp] + [regress/unittests/sshkey/testdata/dsa_1.fp.bb] + [regress/unittests/sshkey/testdata/dsa_1.param.g] + [regress/unittests/sshkey/testdata/dsa_1.param.priv] + [regress/unittests/sshkey/testdata/dsa_1.param.pub] + [regress/unittests/sshkey/testdata/dsa_1.pub] + [regress/unittests/sshkey/testdata/dsa_1_pw] + [regress/unittests/sshkey/testdata/dsa_2] + [regress/unittests/sshkey/testdata/dsa_2.fp] + [regress/unittests/sshkey/testdata/dsa_2.fp.bb] + [regress/unittests/sshkey/testdata/dsa_2.pub] + [regress/unittests/sshkey/testdata/dsa_n] + [regress/unittests/sshkey/testdata/dsa_n_pw] + [regress/unittests/sshkey/testdata/ecdsa_1] + [regress/unittests/sshkey/testdata/ecdsa_1-cert.fp] + [regress/unittests/sshkey/testdata/ecdsa_1-cert.pub] + [regress/unittests/sshkey/testdata/ecdsa_1.fp] + [regress/unittests/sshkey/testdata/ecdsa_1.fp.bb] + [regress/unittests/sshkey/testdata/ecdsa_1.param.curve] + [regress/unittests/sshkey/testdata/ecdsa_1.param.priv] + [regress/unittests/sshkey/testdata/ecdsa_1.param.pub] + [regress/unittests/sshkey/testdata/ecdsa_1.pub] + [regress/unittests/sshkey/testdata/ecdsa_1_pw] + [regress/unittests/sshkey/testdata/ecdsa_2] + [regress/unittests/sshkey/testdata/ecdsa_2.fp] + [regress/unittests/sshkey/testdata/ecdsa_2.fp.bb] + [regress/unittests/sshkey/testdata/ecdsa_2.param.curve] + [regress/unittests/sshkey/testdata/ecdsa_2.param.priv] + [regress/unittests/sshkey/testdata/ecdsa_2.param.pub] + [regress/unittests/sshkey/testdata/ecdsa_2.pub] + [regress/unittests/sshkey/testdata/ecdsa_n] + [regress/unittests/sshkey/testdata/ecdsa_n_pw] + [regress/unittests/sshkey/testdata/ed25519_1] + [regress/unittests/sshkey/testdata/ed25519_1-cert.fp] + [regress/unittests/sshkey/testdata/ed25519_1-cert.pub] + [regress/unittests/sshkey/testdata/ed25519_1.fp] + [regress/unittests/sshkey/testdata/ed25519_1.fp.bb] + [regress/unittests/sshkey/testdata/ed25519_1.pub] + [regress/unittests/sshkey/testdata/ed25519_1_pw] + [regress/unittests/sshkey/testdata/ed25519_2] + [regress/unittests/sshkey/testdata/ed25519_2.fp] + [regress/unittests/sshkey/testdata/ed25519_2.fp.bb] + [regress/unittests/sshkey/testdata/ed25519_2.pub] + [regress/unittests/sshkey/testdata/pw] + [regress/unittests/sshkey/testdata/rsa1_1] + [regress/unittests/sshkey/testdata/rsa1_1.fp] + [regress/unittests/sshkey/testdata/rsa1_1.fp.bb] + [regress/unittests/sshkey/testdata/rsa1_1.param.n] + [regress/unittests/sshkey/testdata/rsa1_1.pub] + [regress/unittests/sshkey/testdata/rsa1_1_pw] + [regress/unittests/sshkey/testdata/rsa1_2] + [regress/unittests/sshkey/testdata/rsa1_2.fp] + [regress/unittests/sshkey/testdata/rsa1_2.fp.bb] + [regress/unittests/sshkey/testdata/rsa1_2.param.n] + [regress/unittests/sshkey/testdata/rsa1_2.pub] + [regress/unittests/sshkey/testdata/rsa_1] + [regress/unittests/sshkey/testdata/rsa_1-cert.fp] + [regress/unittests/sshkey/testdata/rsa_1-cert.pub] + [regress/unittests/sshkey/testdata/rsa_1.fp] + [regress/unittests/sshkey/testdata/rsa_1.fp.bb] + [regress/unittests/sshkey/testdata/rsa_1.param.n] + [regress/unittests/sshkey/testdata/rsa_1.param.p] + [regress/unittests/sshkey/testdata/rsa_1.param.q] + [regress/unittests/sshkey/testdata/rsa_1.pub] + [regress/unittests/sshkey/testdata/rsa_1_pw] + [regress/unittests/sshkey/testdata/rsa_2] + [regress/unittests/sshkey/testdata/rsa_2.fp] + [regress/unittests/sshkey/testdata/rsa_2.fp.bb] + [regress/unittests/sshkey/testdata/rsa_2.param.n] + [regress/unittests/sshkey/testdata/rsa_2.param.p] + [regress/unittests/sshkey/testdata/rsa_2.param.q] + [regress/unittests/sshkey/testdata/rsa_2.pub] + [regress/unittests/sshkey/testdata/rsa_n] + [regress/unittests/sshkey/testdata/rsa_n_pw] + unit and fuzz tests for new key API + +commit c1dc24b71f087f385b92652b9673f52af64e0428 +Author: Damien Miller +Date: Wed Jul 2 17:02:03 2014 +1000 + + - djm@cvs.openbsd.org 2014/06/24 01:04:43 + [regress/krl.sh] + regress test for broken consecutive revoked serial number ranges + +commit 43d3ed2dd3feca6d0326c7dc82588d2faa115e92 +Author: Damien Miller +Date: Wed Jul 2 17:01:08 2014 +1000 + + - djm@cvs.openbsd.org 2014/05/21 07:04:21 + [regress/integrity.sh] + when failing because of unexpected output, show the offending output + +commit 5a96707ffc8d227c2e7d94fa6b0317f8a152cf4e +Author: Damien Miller +Date: Wed Jul 2 15:38:05 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/30 05:32:00 + [regress/Makefile] + unit tests for new buffer API; including basic fuzz testing + NB. Id sync only. + +commit 3ff92ba756aee48e4ae3e0aeff7293517b3dd185 +Author: Damien Miller +Date: Wed Jul 2 15:33:09 2014 +1000 + + - djm@cvs.openbsd.org 2014/06/30 12:54:39 + [key.c] + suppress spurious error message when loading key with a passphrase; + reported by kettenis@ ok markus@ + - djm@cvs.openbsd.org 2014/07/02 04:59:06 + [cipher-3des1.c] + fix ssh protocol 1 on the server that regressed with the sshkey change + (sometimes fatal() after auth completed), make file return useful status + codes. + NB. Id sync only for these two. They were bundled into the sshkey merge + above, since it was easier to sync the entire file and then apply + portable-specific changed atop it. + +commit ec3d0e24a1e46873d80507f5cd8ee6d0d03ac5dc +Author: Damien Miller +Date: Wed Jul 2 15:30:00 2014 +1000 + + - markus@cvs.openbsd.org 2014/06/27 18:50:39 + [ssh-add.c] + fix loading of private keys + +commit 4b3ed647d5b328cf68e6a8ffbee490d8e0683e82 +Author: Damien Miller +Date: Wed Jul 2 15:29:40 2014 +1000 + + - markus@cvs.openbsd.org 2014/06/27 16:41:56 + [channels.c channels.h clientloop.c ssh.c] + fix remote fwding with same listen port but different listen address + with gerhard@, ok djm@ + +commit 9e01ff28664921ce9b6500681333e42fb133b4d0 +Author: Damien Miller +Date: Wed Jul 2 15:29:21 2014 +1000 + + - deraadt@cvs.openbsd.org 2014/06/25 14:16:09 + [sshbuf.c] + unblock SIGSEGV before raising it + ok djm + +commit 1845fe6bda0729e52f4c645137f4fc3070b5438a +Author: Damien Miller +Date: Wed Jul 2 15:29:01 2014 +1000 + + - djm@cvs.openbsd.org 2014/06/24 02:21:01 + [scp.c] + when copying local->remote fails during read, don't send uninitialised + heap to the remote end. Reported by Jann Horn + +commit 19439e9a2a0ac0b4b3b1210e89695418beb1c883 +Author: Damien Miller +Date: Wed Jul 2 15:28:40 2014 +1000 + + - djm@cvs.openbsd.org 2014/06/24 02:19:48 + [ssh.c] + don't fatal() when hostname canonicalisation fails with a + ProxyCommand in use; continue and allow the ProxyCommand to + connect anyway (e.g. to a host with a name outside the DNS + behind a bastion) + +commit 8668706d0f52654fe64c0ca41a96113aeab8d2b8 +Author: Damien Miller +Date: Wed Jul 2 15:28:02 2014 +1000 + + - djm@cvs.openbsd.org 2014/06/24 01:13:21 + [Makefile.in auth-bsdauth.c auth-chall.c auth-options.c auth-rsa.c + [auth2-none.c auth2-pubkey.c authfile.c authfile.h cipher-3des1.c + [cipher-chachapoly.c cipher-chachapoly.h cipher.c cipher.h + [digest-libc.c digest-openssl.c digest.h dns.c entropy.c hmac.h + [hostfile.c key.c key.h krl.c monitor.c packet.c rsa.c rsa.h + [ssh-add.c ssh-agent.c ssh-dss.c ssh-ecdsa.c ssh-ed25519.c + [ssh-keygen.c ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c + [ssh-rsa.c sshbuf-misc.c sshbuf.h sshconnect.c sshconnect1.c + [sshconnect2.c sshd.c sshkey.c sshkey.h + [openbsd-compat/openssl-compat.c openbsd-compat/openssl-compat.h] + New key API: refactor key-related functions to be more library-like, + existing API is offered as a set of wrappers. + + with and ok markus@ + + Thanks also to Ben Hawkes, David Tomaschik, Ivan Fratric, Matthew + Dempsky and Ron Bowes for a detailed review a few months ago. + + NB. This commit also removes portable OpenSSH support for OpenSSL + <0.9.8e. + +commit 2cd7929250cf9e9f658d70dcd452f529ba08c942 +Author: Damien Miller +Date: Wed Jul 2 12:48:30 2014 +1000 + + - djm@cvs.openbsd.org 2014/06/24 00:52:02 + [krl.c] + fix bug in KRL generation: multiple consecutive revoked certificate + serial number ranges could be serialised to an invalid format. + + Readers of a broken KRL caused by this bug will fail closed, so no + should-have-been-revoked key will be accepted. + +commit 99db840ee8dbbd2b3fbc6c45d0ee2f6a65e96898 +Author: Damien Miller +Date: Wed Jul 2 12:48:04 2014 +1000 + + - naddy@cvs.openbsd.org 2014/06/18 15:42:09 + [sshbuf-getput-crypto.c] + The ssh_get_bignum functions must accept the same range of bignums + the corresponding ssh_put_bignum functions create. This fixes the + use of 16384-bit RSA keys (bug reported by Eivind Evensen). + ok djm@ + +commit 84a89161a9629239b64171ef3e22ef6a3e462d51 +Author: Damien Miller +Date: Wed Jul 2 12:47:48 2014 +1000 + + - matthew@cvs.openbsd.org 2014/06/18 02:59:13 + [sandbox-systrace.c] + Now that we have a dedicated getentropy(2) system call for + arc4random(3), we can disallow __sysctl(2) in OpenSSH's systrace + sandbox. + + ok djm + +commit 51504ceec627c0ad57b9f75585c7b3d277f326be +Author: Damien Miller +Date: Wed Jul 2 12:47:25 2014 +1000 + + - deraadt@cvs.openbsd.org 2014/06/13 08:26:29 + [sandbox-systrace.c] + permit SYS_getentropy + from matthew + +commit a261b8df59117f7dc52abb3a34b35a40c2c9fa88 +Author: Tim Rice +Date: Wed Jun 18 16:17:28 2014 -0700 + + - (tim) [openssh/session.c] Work around to get chroot sftp working on UnixWare + +commit 316fac6f18f87262a315c79bcf68b9f92c9337e4 +Author: Darren Tucker +Date: Tue Jun 17 23:06:07 2014 +1000 + + - (dtucker) [entropy.c openbsd-compat/openssl-compat.{c,h} + openbsd-compat/regress/{.cvsignore,Makefile.in,opensslvertest.c}] + Move the OpenSSL header/library version test into its own function and add + tests for it. Fix it to allow fix version upgrades (but not downgrades). + Prompted by chl@ via OpenSMTPD (issue #462) and Debian (bug #748150). + ok djm@ chl@ + +commit af665bb7b092a59104db1e65577851cf35b86e32 +Author: Darren Tucker +Date: Mon Jun 16 22:50:55 2014 +1000 + + - (dtucker) [defines.h] Fix undef of _PATH_MAILDIR. From rak at debian via + OpenSMTPD and chl@ + +commit f9696566fb41320820f3b257ab564fa321bb3751 +Author: Darren Tucker +Date: Fri Jun 13 11:06:04 2014 +1000 + + - (dtucker) [configure.ac] Remove tcpwrappers support, support has already + been removed from sshd.c. + +commit 5e2b8894b0b24af4ad0a2f7aa33ebf255df7a8bc +Author: Tim Rice +Date: Wed Jun 11 18:31:10 2014 -0700 + + - (tim) [regress/unittests/test_helper/test_helper.h] Add includes.h for + u_intXX_t types. + +commit 985ee2cbc3e43bc65827c3c0d4df3faa99160c37 +Author: Darren Tucker +Date: Thu Jun 12 05:32:29 2014 +1000 + + - (dtucker) [regress/unittests/sshbuf/*.c regress/unittests/test_helper/*] + Wrap stdlib.h include an ifdef for platforms that don't have it. + +commit cf5392c2db2bb1dbef9818511d34056404436109 +Author: Darren Tucker +Date: Thu Jun 12 05:22:49 2014 +1000 + + - (dtucker) [defines.h] Add va_copy if we don't already have it, taken from + openbsd-compat/bsd-asprintf.c. + +commit 58538d795e0b662f2f4e5a7193f1204bbe992ddd +Author: Darren Tucker +Date: Wed Jun 11 13:39:24 2014 +1000 + + - (dtucker) [bufaux.c bufbn.c bufec.c buffer.c] Pull in includes.h for + compat stuff, specifically whether or not OpenSSL has ECC. + +commit eb012ac581fd0abc16ee86ee3a68cf07c8ce4d08 +Author: Darren Tucker +Date: Wed Jun 11 13:10:00 2014 +1000 + + - (dtucker) [openbsd-compat/arc4random.c] Use explicit_bzero instead of an + assigment that might get optimized out. ok djm@ + +commit b9609fd86c623d6d440e630f5f9a63295f7aea20 +Author: Darren Tucker +Date: Wed Jun 11 08:04:02 2014 +1000 + + - (dtucker) [sshbuf.h] Only declare ECC functions if building without + OpenSSL or if OpenSSL has ECC. + +commit a54a040f66944c6e8913df8635a01a2327219be9 +Author: Darren Tucker +Date: Wed Jun 11 07:58:35 2014 +1000 + + - dtucker@cvs.openbsd.org 2014/06/10 21:46:11 + [sshbuf.h] + Group ECC functions together to make things a little easier in -portable. + "doesn't bother me" deraadt@ + +commit 9f92c53bad04a89067756be8198d4ec2d8a08875 +Author: Darren Tucker +Date: Wed Jun 11 07:57:58 2014 +1000 + + - djm@cvs.openbsd.org 2014/06/05 22:17:50 + [sshconnect2.c] + fix inverted test that caused PKCS#11 keys that were explicitly listed + not to be preferred. Reported by Dirk-Willem van Gulik + +commit 15c254a25394f96643da2ad0f674acdc51e89856 +Author: Darren Tucker +Date: Wed Jun 11 07:38:49 2014 +1000 + + - (dtucker) [regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c] ifdef + ECC variable too. + +commit d7af0cc5bf273eeed0897a99420bc26841d07d8f +Author: Darren Tucker +Date: Wed Jun 11 07:37:25 2014 +1000 + + - (dtucker) [myprosal.h] Don't include curve25519-sha256@libssh.org in + the proposal if the version of OpenSSL we're using doesn't support ECC. + +commit 67508ac2563c33d582be181a3e777c65f549d22f +Author: Darren Tucker +Date: Wed Jun 11 06:27:16 2014 +1000 + + - (dtucker) [regress/unittests/sshbuf/test_sshbuf_getput_crypto.c + regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c] Only do NISTP256 + curve tests if OpenSSL has them. + +commit 6482d90a65459a88c18c925368525855832272b3 +Author: Damien Miller +Date: Tue May 27 14:34:42 2014 +1000 + + - (djm) [configure.ac openbsd-compat/bsd-cygwin_util.c] + [openbsd-compat/bsd-cygwin_util.h] On Cygwin, determine privilege + separation user at runtime, since it may need to be a domain account. + Patch from Corinna Vinschen. + +commit f9eb5e0734f7a7f6e975809eb54684d2a06a7ffc +Author: Damien Miller +Date: Tue May 27 14:31:58 2014 +1000 + + - (djm) [contrib/cygwin/ssh-host-config] Updated Cygwin ssh-host-config + from Corinna Vinschen, fixing a number of bugs and preparing for + Cygwin 1.7.30. + +commit eae88744662e6b149f43ef071657727f1a157d95 +Author: Damien Miller +Date: Tue May 27 14:27:02 2014 +1000 + + - (djm) [cipher.c] Fix merge botch. + +commit 564b5e253c1d95c26a00e8288f0089a2571661c3 +Author: Damien Miller +Date: Thu May 22 08:23:59 2014 +1000 + + - (djm) [Makefile.in] typo in path + +commit e84d10302aeaf7a1acb05c451f8718143656856a +Author: Damien Miller +Date: Wed May 21 17:13:36 2014 +1000 + + revert a diff I didn't mean to commit + +commit 795b86313f1f1aab9691666c4f2d5dae6e4acd50 +Author: Damien Miller +Date: Wed May 21 17:12:53 2014 +1000 + + - (djm) [misc.c] Use CLOCK_BOOTTIME in preference to CLOCK_MONOTONIC + when it is available. It takes into account time spent suspended, + thereby ensuring timeouts (e.g. for expiring agent keys) fire + correctly. bz#2228 reported by John Haxby + +commit 18912775cb97c0b1e75e838d3c7d4b56648137b5 +Author: Damien Miller +Date: Wed May 21 17:06:46 2014 +1000 + + - (djm) [commit configure.ac defines.h sshpty.c] don't attempt to use + vhangup on Linux. It doens't work for non-root users, and for them + it just messes up the tty settings. + +commit 7f1c264d3049cd95234e91970ccb5406e1d15b27 +Author: Damien Miller +Date: Thu May 15 18:01:52 2014 +1000 + + - (djm) [sshbuf.c] need __predict_false + +commit e7429f2be8643e1100380a8a7389d85cc286c8fe +Author: Damien Miller +Date: Thu May 15 18:01:01 2014 +1000 + + - (djm) [regress/Makefile Makefile.in] + [regress/unittests/sshbuf/test_sshbuf.c + [regress/unittests/sshbuf/test_sshbuf_fixed.c] + [regress/unittests/sshbuf/test_sshbuf_fuzz.c] + [regress/unittests/sshbuf/test_sshbuf_getput_basic.c] + [regress/unittests/sshbuf/test_sshbuf_getput_crypto.c] + [regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c] + [regress/unittests/sshbuf/test_sshbuf_misc.c] + [regress/unittests/sshbuf/tests.c] + [regress/unittests/test_helper/fuzz.c] + [regress/unittests/test_helper/test_helper.c] + Hook new unit tests into the build and "make tests" + +commit def1de086707b0e6b046fe7e115c60aca0227a99 +Author: Damien Miller +Date: Thu May 15 15:17:15 2014 +1000 + + - (djm) [regress/unittests/Makefile] + [regress/unittests/Makefile.inc] + [regress/unittests/sshbuf/Makefile] + [regress/unittests/sshbuf/test_sshbuf.c] + [regress/unittests/sshbuf/test_sshbuf_fixed.c] + [regress/unittests/sshbuf/test_sshbuf_fuzz.c] + [regress/unittests/sshbuf/test_sshbuf_getput_basic.c] + [regress/unittests/sshbuf/test_sshbuf_getput_crypto.c] + [regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c] + [regress/unittests/sshbuf/test_sshbuf_misc.c] + [regress/unittests/sshbuf/tests.c] + [regress/unittests/test_helper/Makefile] + [regress/unittests/test_helper/fuzz.c] + [regress/unittests/test_helper/test_helper.c] + [regress/unittests/test_helper/test_helper.h] + Import new unit tests from OpenBSD; not yet hooked up to build. + +commit 167685756fde8bc213a8df2c8e1848e312db0f46 +Author: Damien Miller +Date: Thu May 15 15:08:40 2014 +1000 + + - logan@cvs.openbsd.org 2014/05/04 10:40:59 + [connect-privsep.sh] + Remove the Z flag from the list of malloc options as it + was removed from malloc.c 10 days ago. + + OK from miod@ + +commit d0b69fe90466920d69c96069312e24b581771bd7 +Author: Damien Miller +Date: Thu May 15 15:08:19 2014 +1000 + + - dtucker@cvs.openbsd.org 2014/05/03 18:46:14 + [proxy-connect.sh] + Add tests for with and without compression, with and without privsep. + +commit edb1af50441d19fb2dd9ccb4d75bf14473fca584 +Author: Damien Miller +Date: Thu May 15 15:07:53 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/21 22:15:37 + [dhgex.sh integrity.sh kextype.sh rekey.sh try-ciphers.sh] + repair regress tests broken by server-side default cipher/kex/mac changes + by ensuring that the option under test is included in the server's + algorithm list + +commit 54343e95c70994695f8842fb22836321350198d3 +Author: Damien Miller +Date: Thu May 15 15:07:33 2014 +1000 + + - djm@cvs.openbsd.org 2014/03/13 20:44:49 + [login-timeout.sh] + this test is a sorry mess of race conditions; add another sleep + to avoid a failure on slow machines (at least until I find a + better way) + +commit e5b9f0f2ee6e133894307e44e862b66426990733 +Author: Damien Miller +Date: Thu May 15 14:58:07 2014 +1000 + + - (djm) [Makefile.in configure.ac sshbuf-getput-basic.c] + [sshbuf-getput-crypto.c sshbuf.c] compilation and portability fixes + +commit b9c566788a9ebd6a9d466f47a532124f111f0542 +Author: Damien Miller +Date: Thu May 15 14:43:37 2014 +1000 + + - (djm) [configure.ac] Unconditionally define WITH_OPENSSL until we write + portability glue to support building without libcrypto + +commit 3dc27178b42234b653a32f7a87292d7994045ee3 +Author: Damien Miller +Date: Thu May 15 14:37:59 2014 +1000 + + - logan@cvs.openbsd.org 2014/05/05 07:02:30 + [sftp.c] + Zap extra whitespace. + + OK from djm@ and dtucker@ + +commit c31a0cd5b31961f01c5b731f62a6cb9d4f767472 +Author: Damien Miller +Date: Thu May 15 14:37:39 2014 +1000 + + - markus@cvs.openbsd.org 2014/05/03 17:20:34 + [monitor.c packet.c packet.h] + unbreak compression, by re-init-ing the compression code in the + post-auth child. the new buffer code is more strict, and requires + buffer_init() while the old code was happy after a bzero(); + originally from djm@ + +commit 686c7d9ee6f44b2be4128d7860b6b37adaeba733 +Author: Damien Miller +Date: Thu May 15 14:37:03 2014 +1000 + + - djm@cvs.openbsd.org 2014/05/02 03:27:54 + [chacha.h cipher-chachapoly.h digest.h hmac.h kex.h kexc25519.c] + [misc.h poly1305.h ssh-pkcs11.c defines.h] + revert __bounded change; it causes way more problems for portable than + it solves; pointed out by dtucker@ + +commit 294c58a007cfb2f3bddc4fc3217e255857ffb9bf +Author: Damien Miller +Date: Thu May 15 14:35:03 2014 +1000 + + - naddy@cvs.openbsd.org 2014/04/30 19:07:48 + [mac.c myproposal.h umac.c] + UMAC can use our local fallback implementation of AES when OpenSSL isn't + available. Glue code straight from Ted Krovetz's original umac.c. + ok markus@ + +commit 05e82c3b963c33048128baf72a6f6b3a1c10b4c1 +Author: Damien Miller +Date: Thu May 15 14:33:43 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/30 05:29:56 + [bufaux.c bufbn.c bufec.c buffer.c buffer.h sshbuf-getput-basic.c] + [sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c sshbuf.h ssherr.c] + [ssherr.h] + New buffer API; the first installment of the conversion/replacement + of OpenSSH's internals to make them usable as a standalone library. + + This includes a set of wrappers to make it compatible with the + existing buffer API so replacement can occur incrementally. + + With and ok markus@ + + Thanks also to Ben Hawkes, David Tomaschik, Ivan Fratric, Matthew + Dempsky and Ron Bowes for a detailed review. + +commit 380948180f847a26f2d0c85b4dad3dca2ed2fd8b +Author: Damien Miller +Date: Thu May 15 14:25:18 2014 +1000 + + - dtucker@cvs.openbsd.org 2014/04/29 20:36:51 + [sftp.c] + Don't attempt to append a nul quote char to the filename. Should prevent + fatal'ing with "el_insertstr failed" when there's a single quote char + somewhere in the string. bz#2238, ok markus@ + +commit d7fd8bedd4619a2ec7fd02aae4c4e1db4431ad9f +Author: Damien Miller +Date: Thu May 15 14:24:59 2014 +1000 + + - dtucker@cvs.openbsd.org 2014/04/29 19:58:50 + [sftp.c] + Move nulling of variable next to where it's freed. ok markus@ + +commit 1f0311c7c7d10c94ff7f823de9c5b2ed79368b14 +Author: Damien Miller +Date: Thu May 15 14:24:09 2014 +1000 + + - markus@cvs.openbsd.org 2014/04/29 18:01:49 + [auth.c authfd.c authfile.c bufaux.c cipher.c cipher.h hostfile.c] + [kex.c key.c mac.c monitor.c monitor_wrap.c myproposal.h packet.c] + [roaming_client.c ssh-agent.c ssh-keygen.c ssh-keyscan.c ssh-keysign.c] + [ssh-pkcs11.h ssh.c sshconnect.c sshconnect2.c sshd.c] + make compiling against OpenSSL optional (make OPENSSL=no); + reduces algorithms to curve25519, aes-ctr, chacha, ed25519; + allows us to explore further options; with and ok djm + +commit c5893785564498cea73cb60d2cf199490483e080 +Author: Damien Miller +Date: Thu May 15 13:48:49 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/29 13:10:30 + [clientloop.c serverloop.c] + bz#1818 - don't send channel success/failre replies on channels that + have sent a close already; analysis and patch from Simon Tatham; + ok markus@ + +commit 633de33b192d808d87537834c316dc8b75fe1880 +Author: Damien Miller +Date: Thu May 15 13:48:26 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/28 03:09:18 + [authfile.c bufaux.c buffer.h channels.c krl.c mux.c packet.c packet.h] + [ssh-keygen.c] + buffer_get_string_ptr's return should be const to remind + callers that futzing with it will futz with the actual buffer + contents + +commit 15271907843e4ae50dcfc83b3594014cf5e9607b +Author: Damien Miller +Date: Thu May 15 13:47:56 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/23 12:42:34 + [readconf.c] + don't record duplicate IdentityFiles + +commit 798a02568b13a2e46efebd81f08c8f4bb33a6dc7 +Author: Damien Miller +Date: Thu May 15 13:47:37 2014 +1000 + + - jmc@cvs.openbsd.org 2014/04/22 14:16:30 + [sftp.1] + zap eol whitespace; + +commit d875ff78d2b8436807381051de112f0ebf9b9ae1 +Author: Damien Miller +Date: Thu May 15 13:47:15 2014 +1000 + + - logan@cvs.openbsd.org 2014/04/22 12:42:04 + [sftp.1] + Document sftp upload resume. + OK from djm@, with feedback from okan@. + +commit b15cd7bb097fd80dc99520f45290ef775da1ef19 +Author: Damien Miller +Date: Thu May 15 13:46:52 2014 +1000 + + - logan@cvs.openbsd.org 2014/04/22 10:07:12 + [sftp.c] + Sort the sftp command list. + OK from djm@ + +commit d8accc0aa72656ba63d50937165c5ae49db1dcd6 +Author: Damien Miller +Date: Thu May 15 13:46:25 2014 +1000 + + - logan@cvs.openbsd.org 2014/04/21 14:36:16 + [sftp-client.c sftp-client.h sftp.c] + Implement sftp upload resume support. + OK from djm@, with input from guenther@, mlarkin@ and + okan@ + +commit 16cd3928a87d20c77b13592a74b60b08621d3ce6 +Author: Damien Miller +Date: Thu May 15 13:45:58 2014 +1000 + + - logan@cvs.openbsd.org 2014/04/20 09:24:26 + [dns.c dns.h ssh-keygen.c] + Add support for SSHFP DNS records for ED25519 key types. + OK from djm@ + +commit ec0b67eb3b4e12f296ced1fafa01860c374f7eea +Author: Damien Miller +Date: Thu May 15 13:45:26 2014 +1000 + + - (djm) [rijndael.c rijndael.h] Sync with newly-ressurected versions ine + OpenBSD + +commit f028460d0b2e5a584355321015cde69bf6fd933e +Author: Darren Tucker +Date: Thu May 1 02:24:35 2014 +1000 + + - (dtucker) [defines.h] Define __GNUC_PREREQ__ macro if we don't already + have it. Only attempt to use __attribute__(__bounded__) for gcc. + +commit b628cc4c3e4a842bab5e4584d18c2bc5fa4d0edf +Author: Damien Miller +Date: Sun Apr 20 13:33:58 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/20 02:49:32 + [compat.c] + add a canonical 6.6 + curve25519 bignum fix fake version that I can + recommend people use ahead of the openssh-6.7 release + +commit 888566913933a802f3a329ace123ebcb7154cf78 +Author: Damien Miller +Date: Sun Apr 20 13:33:19 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/20 02:30:25 + [misc.c misc.h umac.c] + use get/put_u32 to load values rather than *((UINT32 *)p) that breaks on + strict-alignment architectures; reported by and ok stsp@ + +commit 16f85cbc7e5139950e6a38317e7c8b368beafa5d +Author: Damien Miller +Date: Sun Apr 20 13:29:28 2014 +1000 + + - tedu@cvs.openbsd.org 2014/04/19 18:42:19 + [ssh.1] + delete .xr to hosts.equiv. there's still an unfortunate amount of + documentation referring to rhosts equivalency in here. + +commit 69cb24b7356ec3f0fc5ff04a68f98f2c55c766f4 +Author: Damien Miller +Date: Sun Apr 20 13:29:06 2014 +1000 + + - tedu@cvs.openbsd.org 2014/04/19 18:15:16 + [sshd.8] + remove some really old rsh references + +commit 84c1e7bca8c4ceaccf4d5557e39a833585a3c77e +Author: Damien Miller +Date: Sun Apr 20 13:27:53 2014 +1000 + + - tedu@cvs.openbsd.org 2014/04/19 14:53:48 + [ssh-keysign.c sshd.c] + Delete futile calls to RAND_seed. ok djm + NB. Id sync only. This only applies to OpenBSD's libcrypto slashathon + +commit 0e6b67423b8662f9ca4c92750309e144fd637ef1 +Author: Damien Miller +Date: Sun Apr 20 13:27:01 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/19 05:54:59 + [compat.c] + missing wildcard; pointed out by naddy@ + +commit 9395b28223334826837c15e8c1bb4dfb3b0d2ca5 +Author: Damien Miller +Date: Sun Apr 20 13:25:30 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/18 23:52:25 + [compat.c compat.h sshconnect2.c sshd.c version.h] + OpenSSH 6.5 and 6.6 have a bug that causes ~0.2% of connections + using the curve25519-sha256@libssh.org KEX exchange method to fail + when connecting with something that implements the spec properly. + + Disable this KEX method when speaking to one of the affected + versions. + + reported by Aris Adamantiadis; ok markus@ + +commit 8c492da58f8ceb85cf5f7066f23e26fb813a963d +Author: Damien Miller +Date: Sun Apr 20 13:25:09 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/16 23:28:12 + [ssh-agent.1] + remove the identity files from this manpage - ssh-agent doesn't deal + with them at all and the same information is duplicated in ssh-add.1 + (which does deal with them); prodded by deraadt@ + +commit adbfdbbdccc70c9bd70d81ae096db115445c6e26 +Author: Damien Miller +Date: Sun Apr 20 13:24:49 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/16 23:22:45 + [bufaux.c] + skip leading zero bytes in buffer_put_bignum2_from_string(); + reported by jan AT mojzis.com; ok markus@ + +commit 75c62728dc87af6805696eeb520b9748faa136c8 +Author: Damien Miller +Date: Sun Apr 20 13:24:31 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/12 04:55:53 + [sshd.c] + avoid crash at exit: check that pmonitor!=NULL before dereferencing; + bz#2225, patch from kavi AT juniper.net + +commit 2a328437fb1b0976f2f4522d8645803d5a5d0967 +Author: Damien Miller +Date: Sun Apr 20 13:24:01 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/01 05:32:57 + [packet.c] + demote a debug3 to PACKET_DEBUG; ok markus@ + +commit 7d6a9fb660c808882d064e152d6070ffc3844c3f +Author: Damien Miller +Date: Sun Apr 20 13:23:43 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/01 03:34:10 + [sshconnect.c] + When using VerifyHostKeyDNS with a DNSSEC resolver, down-convert any + certificate keys to plain keys and attempt SSHFP resolution. + + Prevents a server from skipping SSHFP lookup and forcing a new-hostkey + dialog by offering only certificate keys. + + Reported by mcv21 AT cam.ac.uk + +commit fcd62c0b66b8415405ed0af29c236329eb88cc0f +Author: Damien Miller +Date: Sun Apr 20 13:23:21 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/01 02:05:27 + [ssh-keysign.c] + include fingerprint of key not found + use arc4random_buf() instead of loop+arc4random() + +commit 43b156cf72f900f88065b0a1c1ebd09ab733ca46 +Author: Damien Miller +Date: Sun Apr 20 13:23:03 2014 +1000 + + - jmc@cvs.openbsd.org 2014/03/31 13:39:34 + [ssh-keygen.1] + the text for the -K option was inserted in the wrong place in -r1.108; + fix From: Matthew Clarke + +commit c1621c84f2dc1279065ab9fde2aa9327af418900 +Author: Damien Miller +Date: Sun Apr 20 13:22:46 2014 +1000 + + - naddy@cvs.openbsd.org 2014/03/28 05:17:11 + [ssh_config.5 sshd_config.5] + sync available and default algorithms, improve algorithm list formatting + help from jmc@ and schwarze@, ok deraadt@ + +commit f2719b7c2b8a3b14d778d8a6d8dc729b5174b054 +Author: Damien Miller +Date: Sun Apr 20 13:22:18 2014 +1000 + + - tedu@cvs.openbsd.org 2014/03/26 19:58:37 + [sshd.8 sshd.c] + remove libwrap support. ok deraadt djm mfriedl + +commit 4f40209aa4060b9c066a2f0d9332ace7b8dfb391 +Author: Damien Miller +Date: Sun Apr 20 13:21:22 2014 +1000 + + - djm@cvs.openbsd.org 2014/03/26 04:55:35 + [chacha.h cipher-chachapoly.h digest.h hmac.h kex.h kexc25519.c + [misc.h poly1305.h ssh-pkcs11.c] + use __bounded(...) attribute recently added to sys/cdefs.h instead of + longform __attribute__(__bounded(...)); + + for brevity and a warning free compilation with llvm/clang + +commit 9235a030ad1b16903fb495d81544e0f7c7449523 +Author: Damien Miller +Date: Sun Apr 20 13:17:20 2014 +1000 + + Three commits in one (since they touch the same heavily-diverged file + repeatedly): + + - markus@cvs.openbsd.org 2014/03/25 09:40:03 + [myproposal.h] + trimm default proposals. + + This commit removes the weaker pre-SHA2 hashes, the broken ciphers + (arcfour), and the broken modes (CBC) from the default configuration + (the patch only changes the default, all the modes are still available + for the config files). + + ok djm@, reminded by tedu@ & naddy@ and discussed with many + - deraadt@cvs.openbsd.org 2014/03/26 17:16:26 + [myproposal.h] + The current sharing of myproposal[] between both client and server code + makes the previous diff highly unpallatable. We want to go in that + direction for the server, but not for the client. Sigh. + Brought up by naddy. + - markus@cvs.openbsd.org 2014/03/27 23:01:27 + [myproposal.h ssh-keyscan.c sshconnect2.c sshd.c] + disable weak proposals in sshd, but keep them in ssh; ok djm@ + +commit 6e1777f592f15f4559728c78204617537b1ac076 +Author: Damien Miller +Date: Sun Apr 20 13:02:58 2014 +1000 + + - tedu@cvs.openbsd.org 2014/03/19 14:42:44 + [scp.1] + there is no need for rcp anymore + ok deraadt millert + +commit eb1b7c514d2a7b1802ccee8cd50e565a4d419887 +Author: Damien Miller +Date: Sun Apr 20 13:02:26 2014 +1000 + + - tedu@cvs.openbsd.org 2014/03/17 19:44:10 + [ssh.1] + old descriptions of des and blowfish are old. maybe ok deraadt + +commit f0858de6e1324ec730752387074b111b8551081e +Author: Damien Miller +Date: Sun Apr 20 13:01:30 2014 +1000 + + - deraadt@cvs.openbsd.org 2014/03/15 17:28:26 + [ssh-agent.c ssh-keygen.1 ssh-keygen.c] + Improve usage() and documentation towards the standard form. + In particular, this line saves a lot of man page reading time. + usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa | rsa1] + [-N new_passphrase] [-C comment] [-f output_keyfile] + ok schwarze jmc + +commit 94bfe0fbd6e91a56b5b0ab94ac955d2a67d101aa +Author: Damien Miller +Date: Sun Apr 20 13:00:51 2014 +1000 + + - naddy@cvs.openbsd.org 2014/03/12 13:06:59 + [ssh-keyscan.1] + scan for Ed25519 keys by default too + +commit 3819519288b2b3928c6882f5883b0f55148f4fc0 +Author: Damien Miller +Date: Sun Apr 20 13:00:28 2014 +1000 + + - djm@cvs.openbsd.org 2014/03/12 04:51:12 + [authfile.c] + correct test that kdf name is not "none" or "bcrypt" + +commit 8f9cd709c7cf0655d414306a0ed28306b33802be +Author: Damien Miller +Date: Sun Apr 20 13:00:11 2014 +1000 + + - djm@cvs.openbsd.org 2014/03/12 04:50:32 + [auth-bsdauth.c ssh-keygen.c] + don't count on things that accept arguments by reference to clear + things for us on error; most things do, but it's unsafe form. + +commit 1c7ef4be83f6dec84509a312518b9df00ab491d9 +Author: Damien Miller +Date: Sun Apr 20 12:59:46 2014 +1000 + + - djm@cvs.openbsd.org 2014/03/12 04:44:58 + [ssh-keyscan.c] + scan for Ed25519 keys by default too + +commit c10bf4d051c97939b30a1616c0499310057d07da +Author: Damien Miller +Date: Sun Apr 20 12:58:04 2014 +1000 + + - djm@cvs.openbsd.org 2014/03/03 22:22:30 + [session.c] + ignore enviornment variables with embedded '=' or '\0' characters; + spotted by Jann Horn; ok deraadt@ + Id sync only - portable already has this. + +commit c2e49062faccbcd7135c40d1c78c5c329c58fc2e +Author: Damien Miller +Date: Tue Apr 1 14:42:46 2014 +1100 + + - (djm) Use full release (e.g. 6.5p1) in debug output rather than just + version. From des@des.no + +commit 14928b7492abec82afa4c2b778fc03f78cd419b6 +Author: Damien Miller +Date: Tue Apr 1 14:38:07 2014 +1100 + + - (djm) On platforms that support it, use prctl() to prevent sftp-server + from accessing /proc/self/{mem,maps}; patch from jann AT thejh.net + +commit 48abc47e60048461fe9117e108a7e99ea1ac2bb8 +Author: Damien Miller +Date: Mon Mar 17 14:45:56 2014 +1100 + + - (djm) [sandbox-seccomp-filter.c] Soft-fail stat() syscalls. Add XXX to + remind myself to add sandbox violation logging via the log socket. + +commit 9c36698ca2f554ec221dc7ef29c7a89e97c88705 +Author: Tim Rice +Date: Fri Mar 14 12:45:01 2014 -0700 + + 20140314 + - (tim) [opensshd.init.in] Add support for ed25519 + +commit 19158b2447e35838d69b2b735fb640d1e86061ea +Author: Damien Miller +Date: Thu Mar 13 13:14:21 2014 +1100 + + - (djm) Release OpenSSH 6.6 + +commit 8569eba5d7f7348ce3955eeeb399f66f25c52ece +Author: Damien Miller +Date: Tue Mar 4 09:35:17 2014 +1100 + + - djm@cvs.openbsd.org 2014/03/03 22:22:30 + [session.c] + ignore enviornment variables with embedded '=' or '\0' characters; + spotted by Jann Horn; ok deraadt@ + +commit 2476c31b96e89aec7d4e73cb6fbfb9a4290de3a7 +Author: Damien Miller +Date: Sun Mar 2 04:01:00 2014 +1100 + + - (djm) [regress/Makefile] Disable dhgex regress test; it breaks when + no moduli file exists at the expected location. + +commit c83fdf30e9db865575b2521b1fe46315cf4c70ae +Author: Damien Miller +Date: Fri Feb 28 10:34:03 2014 +1100 + + - (djm) [regress/host-expand.sh] Add RCS Id + +commit 834aeac3555e53f7d29a6fcf3db010dfb99681c7 +Author: Damien Miller +Date: Fri Feb 28 10:25:16 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/27 21:21:25 + [agent-ptrace.sh agent.sh] + keep return values that are printed in error messages; + from portable + (Id sync only) + +commit 4f7f1a9a0de24410c30952c7e16d433240422182 +Author: Damien Miller +Date: Fri Feb 28 10:24:11 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/27 20:04:16 + [login-timeout.sh] + remove any existing LoginGraceTime from sshd_config before adding + a specific one for the test back in + +commit d705d987c27f68080c8798eeb5262adbdd6b4ffd +Author: Damien Miller +Date: Fri Feb 28 10:23:26 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/26 10:49:17 + [scp-ssh-wrapper.sh scp.sh] + make sure $SCP is tested on the remote end rather than whichever one + happens to be in $PATH; from portable + (Id sync only) + +commit 624a3ca376e3955a4b9d936c9e899e241b65d357 +Author: Damien Miller +Date: Fri Feb 28 10:22:37 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/26 10:22:10 + [regress/cert-hostkey.sh] + automatically generate revoked keys from listed keys rather than + manually specifying each type; from portable + (Id sync only) + +commit b84392328425e4b9a71f8bde5fe6a4a4c48d3ec4 +Author: Damien Miller +Date: Fri Feb 28 10:21:26 2014 +1100 + + - dtucker@cvs.openbsd.org 2014/01/25 04:35:32 + [regress/Makefile regress/dhgex.sh] + Add a test for DH GEX sizes + +commit 1e2aa3d90472293ea19008f02336d6d68aa05793 +Author: Damien Miller +Date: Fri Feb 28 10:19:51 2014 +1100 + + - dtucker@cvs.openbsd.org 2014/01/20 00:00:30 + [sftp-chroot.sh] + append to rather than truncating the log file + +commit f483cc16fe7314e24a37aa3a4422b03c013c3213 +Author: Damien Miller +Date: Fri Feb 28 10:19:11 2014 +1100 + + - dtucker@cvs.openbsd.org 2014/01/19 23:43:02 + [regress/sftp-chroot.sh] + Don't use -q on sftp as it suppresses logging, instead redirect the + output to the regress logfile. + +commit 6486f16f1c0ebd6f39286f6ab5e08286d90a994a +Author: Damien Miller +Date: Fri Feb 28 10:03:52 2014 +1100 + + - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] Crank version numbers + +commit 92cf5adea194140380e6af6ec32751f9ad540794 +Author: Damien Miller +Date: Fri Feb 28 10:01:53 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/27 22:57:40 + [version.h] + openssh-6.6 + +commit fc5d6759aba71eb205b296b5f148010ffc828583 +Author: Damien Miller +Date: Fri Feb 28 10:01:28 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/27 22:47:07 + [sshd_config.5] + bz#2184 clarify behaviour of a keyword that appears in multiple + matching Match blocks; ok dtucker@ + +commit 172ec7e0af1a5f1d682f6a2dca335c6c186153d5 +Author: Damien Miller +Date: Fri Feb 28 10:00:57 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/27 08:25:09 + [bufbn.c] + off by one in range check + +commit f9a9aaba437c2787e40cf7cc928281950e161678 +Author: Damien Miller +Date: Fri Feb 28 10:00:27 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/27 00:41:49 + [bufbn.c] + fix unsigned overflow that could lead to reading a short ssh protocol + 1 bignum value; found by Ben Hawkes; ok deraadt@ + +commit fb3423b612713d9cde67c8a75f6f51188d6a3de3 +Author: Damien Miller +Date: Thu Feb 27 10:20:07 2014 +1100 + + - markus@cvs.openbsd.org 2014/02/26 21:53:37 + [sshd.c] + ssh_gssapi_prepare_supported_oids needs GSSAPI + +commit 1348129a34f0f7728c34d86c100a32dcc8d1f922 +Author: Damien Miller +Date: Thu Feb 27 10:18:32 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/26 20:29:29 + [channels.c] + don't assume that the socks4 username is \0 terminated; + spotted by Ben Hawkes; ok markus@ + +commit e6a74aeeacd01d885262ff8e50eb28faee8c8039 +Author: Damien Miller +Date: Thu Feb 27 10:17:49 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/26 20:28:44 + [auth2-gss.c gss-serv.c ssh-gss.h sshd.c] + bz#2107 - cache OIDs of supported GSSAPI mechanisms before privsep + sandboxing, as running this code in the sandbox can cause violations; + ok markus@ + +commit 08b57c67f3609340ff703fe2782d7058acf2529e +Author: Damien Miller +Date: Thu Feb 27 10:17:13 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/26 20:18:37 + [ssh.c] + bz#2205: avoid early hostname lookups unless canonicalisation is enabled; + ok dtucker@ markus@ + +commit 13f97b2286142fd0b8eab94e4ce84fe124eeb752 +Author: Damien Miller +Date: Mon Feb 24 15:57:55 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/23 20:11:36 + [readconf.c readconf.h ssh.c ssh_config.5] + reparse ssh_config and ~/.ssh/config if hostname canonicalisation changes + the hostname. This allows users to write configurations that always + refer to canonical hostnames, e.g. + + CanonicalizeHostname yes + CanonicalDomains int.example.org example.org + CanonicalizeFallbackLocal no + + Host *.int.example.org + Compression off + Host *.example.org + User djm + + ok markus@ + +commit bee3a234f3d1ad4244952bcff1b4b7c525330dc2 +Author: Damien Miller +Date: Mon Feb 24 15:57:22 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/23 20:03:42 + [ssh-ed25519.c] + check for unsigned overflow; not reachable in OpenSSH but others might + copy our code... + +commit 0628780abe61e7e50cba48cdafb1837f49ff23b2 +Author: Damien Miller +Date: Mon Feb 24 15:56:45 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/22 01:32:19 + [readconf.c] + when processing Match blocks, skip 'exec' clauses if previous predicates + failed to match; ok markus@ + +commit 0890dc8191bb201eb01c3429feec0300a9d3a930 +Author: Damien Miller +Date: Mon Feb 24 15:56:07 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/15 23:05:36 + [channels.c] + avoid spurious "getsockname failed: Bad file descriptor" errors in ssh -W; + bz#2200, debian#738692 via Colin Watson; ok dtucker@ + +commit d3cf67e1117c25d151d0f86396e77ee3a827045a +Author: Damien Miller +Date: Mon Feb 24 15:55:36 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/07 06:55:54 + [cipher.c mac.c] + remove some logging that makes ssh debugging output very verbose; + ok markus + +commit 03ae081aeaa118361c81ece76eb7cc1aaa2b40c5 +Author: Tim Rice +Date: Fri Feb 21 09:09:34 2014 -0800 + + 20140221 + - (tim) [configure.ac] Fix cut-and-paste error. Patch from Bryan Drewery. + +commit 4a20959d2e3c90e9d66897c0b4032c785672d815 +Author: Darren Tucker +Date: Thu Feb 13 16:38:32 2014 +1100 + + - (dtucker) [configure.ac openbsd-compat/openssl-compat.{c,h}] Add compat + code for older OpenSSL versions that don't have EVP_MD_CTX_copy_ex. + +commit d1a7a9c0fd1ac2e3314cceb2891959fd2cd9eabb +Author: Damien Miller +Date: Fri Feb 7 09:24:33 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/06 22:21:01 + [sshconnect.c] + in ssh_create_socket(), only do the getaddrinfo for BindAddress when + BindAddress is actually specified. Fixes regression in 6.5 for + UsePrivilegedPort=yes; patch from Corinna Vinschen + +commit 6ce35b6cc4ead1bf98abec34cb2e2d6ca0abb15e +Author: Damien Miller +Date: Fri Feb 7 09:24:14 2014 +1100 + + - naddy@cvs.openbsd.org 2014/02/05 20:13:25 + [ssh-keygen.1 ssh-keygen.c] + tweak synopsis: calling ssh-keygen without any arguments is fine; ok jmc@ + while here, fix ordering in usage(); requested by jmc@ + +commit 6434cb2cfbbf0a46375d2d22f2ff9927feb5e478 +Author: Damien Miller +Date: Thu Feb 6 11:17:50 2014 +1100 + + - (djm) [sandbox-seccomp-filter.c] Not all Linux architectures define + __NR_shutdown; some go via the socketcall(2) multiplexer. + +commit 8d36f9ac71eff2e9f5770c0518b73d875f270647 +Author: Darren Tucker +Date: Thu Feb 6 10:44:13 2014 +1100 + + - (dtucker) [openbsd-compat/bsd-poll.c] Don't bother checking for non-NULL + before freeing since free(NULL) is a no-op. ok djm. + +commit a0959da3680b4ce8cf911caf3293a6d90f88eeb7 +Author: Damien Miller +Date: Wed Feb 5 10:33:45 2014 +1100 + + - (djm) [sandbox-capsicum.c] Don't fatal if Capsicum is offered by + headers/libc but not supported by the kernel. Patch from Loganaden + Velvindron @ AfriNIC + +commit 9c449bc183b256c84d8f740727b0bc54d247b15e +Author: Damien Miller +Date: Tue Feb 4 11:38:28 2014 +1100 + + - (djm) [regress/setuid-allowed.c] Missing string.h for strerror() + +commit bf7e0f03be661b6f5b3bfe325135ce19391f9c4d +Author: Damien Miller +Date: Tue Feb 4 11:37:50 2014 +1100 + + - (djm) [openbsd-compat/Makefile.in] Add missing explicit_bzero.o + +commit eb6d870a0ea8661299bb2ea8f013d3ace04e2024 +Author: Damien Miller +Date: Tue Feb 4 11:26:34 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/04 00:24:29 + [ssh.c] + delay lowercasing of hostname until right before hostname + canonicalisation to unbreak case-sensitive matching of ssh_config; + reported by Ike Devolder; ok markus@ + +commit d56b44d2dfa093883a5c4e91be3f72d99946b170 +Author: Damien Miller +Date: Tue Feb 4 11:26:04 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/04 00:24:29 + [ssh.c] + delay lowercasing of hostname until right before hostname + canonicalisation to unbreak case-sensitive matching of ssh_config; + reported by Ike Devolder; ok markus@ + +commit db3c595ea74ea9ccd5aa644d7e1f8dc675710731 +Author: Damien Miller +Date: Tue Feb 4 11:25:45 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/02 03:44:31 + [digest-libc.c digest-openssl.c] + convert memset of potentially-private data to explicit_bzero() + +commit aae07e2e2000dd318418fd7fd4597760904cae32 +Author: Damien Miller +Date: Tue Feb 4 11:20:40 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/03 23:28:00 + [ssh-ecdsa.c] + fix memory leak; ECDSA_SIG_new() allocates 'r' and 's' for us, unlike + DSA_SIG_new. Reported by Batz Spear; ok markus@ + +commit a5103f413bde6f31bff85d6e1fd29799c647d765 +Author: Damien Miller +Date: Tue Feb 4 11:20:14 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/02 03:44:32 + [auth1.c auth2-chall.c auth2-passwd.c authfile.c bufaux.c bufbn.c] + [buffer.c cipher-3des1.c cipher.c clientloop.c gss-serv.c kex.c] + [kexdhc.c kexdhs.c kexecdhc.c kexgexc.c kexecdhs.c kexgexs.c key.c] + [monitor.c monitor_wrap.c packet.c readpass.c rsa.c serverloop.c] + [ssh-add.c ssh-agent.c ssh-dss.c ssh-ecdsa.c ssh-ed25519.c] + [ssh-keygen.c ssh-rsa.c sshconnect.c sshconnect1.c sshconnect2.c] + [sshd.c] + convert memset of potentially-private data to explicit_bzero() + +commit 1d2c4564265ee827147af246a16f3777741411ed +Author: Damien Miller +Date: Tue Feb 4 11:18:20 2014 +1100 + + - tedu@cvs.openbsd.org 2014/01/31 16:39:19 + [auth2-chall.c authfd.c authfile.c bufaux.c bufec.c canohost.c] + [channels.c cipher-chachapoly.c clientloop.c configure.ac hostfile.c] + [kexc25519.c krl.c monitor.c sandbox-systrace.c session.c] + [sftp-client.c ssh-keygen.c ssh.c sshconnect2.c sshd.c sshlogin.c] + [openbsd-compat/explicit_bzero.c openbsd-compat/openbsd-compat.h] + replace most bzero with explicit_bzero, except a few that cna be memset + ok djm dtucker + +commit 3928de067c286683a95fbdbdb5fdb3c78a0e5efd +Author: Damien Miller +Date: Tue Feb 4 11:13:54 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/30 22:26:14 + [sandbox-systrace.c] + allow shutdown(2) syscall in sandbox - it may be called by packet_close() + from portable + (Id sync only; change is already in portable) + +commit e1e480aee8a9af6cfbe7188667b7b940d6b57f9f +Author: Damien Miller +Date: Tue Feb 4 11:13:17 2014 +1100 + + - jmc@cvs.openbsd.org 2014/01/29 14:04:51 + [sshd_config.5] + document kbdinteractiveauthentication; + requested From: Ross L Richardson + + dtucker/markus helped explain its workings; + +commit 7cc194f70d4a5ec9a82d19422eaf18db4a6624c6 +Author: Damien Miller +Date: Tue Feb 4 11:12:56 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/29 06:18:35 + [Makefile.in auth.h auth2-jpake.c auth2.c jpake.c jpake.h monitor.c] + [monitor.h monitor_wrap.c monitor_wrap.h readconf.c readconf.h] + [schnorr.c schnorr.h servconf.c servconf.h ssh2.h sshconnect2.c] + remove experimental, never-enabled JPAKE code; ok markus@ + +commit b0f26544cf6f4feeb1a4f6db09fca834f5c9867d +Author: Damien Miller +Date: Tue Feb 4 11:10:01 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/29 00:19:26 + [sshd.c] + use kill(0, ...) instead of killpg(0, ...); on most operating systems + they are equivalent, but SUSv2 describes the latter as having undefined + behaviour; from portable; ok dtucker + (Id sync only; change is already in portable) + +commit f8f35bc471500348bb262039fb1fc43175d251b0 +Author: Damien Miller +Date: Tue Feb 4 11:09:12 2014 +1100 + + - jmc@cvs.openbsd.org 2014/01/28 14:13:39 + [ssh-keyscan.1] + kill some bad Pa; + From: Jan Stary + +commit 0ba85d696ae9daf66002c2e4ab0d6bb111e1a787 +Author: Damien Miller +Date: Tue Feb 4 11:08:38 2014 +1100 + + ignore a few more regress droppings + +commit ec93d15170b7a6ddf63fd654bd0f6a752acc19dd +Author: Damien Miller +Date: Tue Feb 4 11:07:13 2014 +1100 + + - markus@cvs.openbsd.org 2014/01/27 20:13:46 + [digest.c digest-openssl.c digest-libc.c Makefile.in] + rename digest.c to digest-openssl.c and add libc variant; ok djm@ + +commit 4a1c7aa640fb97d3472d51b215b6a0ec0fd025c7 +Author: Damien Miller +Date: Tue Feb 4 11:03:36 2014 +1100 + + - markus@cvs.openbsd.org 2014/01/27 19:18:54 + [auth-rsa.c cipher.c ssh-agent.c sshconnect1.c sshd.c] + replace openssl MD5 with our ssh_digest_*; ok djm@ + +commit 4e8d937af79ce4e253f77ec93489d098b25becc3 +Author: Damien Miller +Date: Tue Feb 4 11:02:42 2014 +1100 + + - markus@cvs.openbsd.org 2014/01/27 18:58:14 + [Makefile.in digest.c digest.h hostfile.c kex.h mac.c hmac.c hmac.h] + replace openssl HMAC with an implementation based on our ssh_digest_* + ok and feedback djm@ + +commit 69d0d09f76bab5aec86fbf78489169f63bd16475 +Author: Tim Rice +Date: Fri Jan 31 14:25:18 2014 -0800 + + - (tim) [Makefile.in] build regress/setuid-allow. + +commit 0eeafcd76b972a3d159f3118227c149a4d7817fe +Author: Darren Tucker +Date: Fri Jan 31 14:18:51 2014 +1100 + + - (dtucker) [readconf.c] Include for the hton macros. Fixes + build with HP-UX's compiler. Patch from Kevin Brott. + +commit 7e5cec6070673e9f9785ffc749837ada22fbe99f +Author: Damien Miller +Date: Fri Jan 31 09:25:34 2014 +1100 + + - (djm) [sandbox-seccomp-filter.c sandbox-systrace.c] Allow shutdown(2) + syscall from sandboxes; it may be called by packet_close. + +commit cdb6c90811caa5df2df856be9b0b16db020fe31d +Author: Damien Miller +Date: Thu Jan 30 12:50:17 2014 +1100 + + - (djm) Release openssh-6.5p1 + +commit 996ea80b1884b676a901439f1f2681eb6ff68501 +Author: Damien Miller +Date: Thu Jan 30 12:49:55 2014 +1100 + + trim entries prior to openssh-6.0p1 + +commit f5bbd3b657b6340551c8a95f74a70857ff8fac79 +Author: Damien Miller +Date: Thu Jan 30 11:26:46 2014 +1100 + + - (djm) [configure.ac atomicio.c] Kludge around NetBSD offering + different symbols for 'read' when various compiler flags are + in use, causing atomicio.c comparisons against it to break and + read/write operations to hang; ok dtucker + +commit c2868192ddc4e1420a50389e18c05db20b0b1f32 +Author: Damien Miller +Date: Thu Jan 30 10:21:19 2014 +1100 + + - (djm) [configure.ac] Only check for width-specified integer types + in headers that actually exist. patch from Tom G. Christensen; + ok dtucker@ + +commit c161fc90fc86e2035710570238a9e1ca7a68d2a5 +Author: Damien Miller +Date: Wed Jan 29 21:01:33 2014 +1100 + + - (djm) [configure.ac] Fix broken shell test '==' vs '='; patch from + Tom G. Christensen + +commit 6f917ad376481995ab7d29fb53b08ec8d507eb9e +Author: Tim Rice +Date: Tue Jan 28 10:26:25 2014 -0800 + + - (tim) [regress/agent.sh regress/agent-ptrace.sh] Assign $? to a variable + when used as an error message inside an if statement so we display the + correct into. agent.sh patch from Petr Lautrbach. + +commit ab16ef4152914d44ce6f76e48167d26d22f66a06 +Author: Damien Miller +Date: Tue Jan 28 15:08:12 2014 +1100 + + - (djm) [sshd.c] Use kill(0, ...) instead of killpg(0, ...); the + latter being specified to have undefined behaviour in SUSv3; + ok dtucker + +commit ab0394905884dc6e58c3721211c6b38fb8fc2ca8 +Author: Damien Miller +Date: Tue Jan 28 15:07:10 2014 +1100 + + - (djm) [configure.ac] Search for inet_ntop in libnsl and libresovl; + ok dtucker + +commit 4ab20a82d4d4168d62318923f62382f6ef242fcd +Author: Darren Tucker +Date: Mon Jan 27 17:35:04 2014 +1100 + + - (dtucker) [Makefile.in] Remove trailing backslash which some make + implementations (eg older Solaris) do not cope with. + +commit e7e8b3cfe9f8665faaf0e68b33df5bbb431bd129 +Author: Darren Tucker +Date: Mon Jan 27 17:32:50 2014 +1100 + + Welcome to 2014 + +commit 5b447c0aac0dd444251e276f6bb3bbbe1c05331c +Author: Damien Miller +Date: Sun Jan 26 09:46:53 2014 +1100 + + - (djm) [configure.ac] correct AC_DEFINE for previous. + +commit 2035b2236d3b1f76c749c642a43e03c85eae76e6 +Author: Damien Miller +Date: Sun Jan 26 09:39:53 2014 +1100 + + - (djm) [configure.ac sandbox-capsicum.c sandbox-rlimit.c] Disable + RLIMIT_NOFILE pseudo-sandbox on FreeBSD. In some configurations, + libc will attempt to open additional file descriptors for crypto + offload and crash if they cannot be opened. + +commit a92ac7410475fbb00383c7402aa954dc0a75ae19 +Author: Damien Miller +Date: Sun Jan 26 09:38:03 2014 +1100 + + - markus@cvs.openbsd.org 2014/01/25 20:35:37 + [kex.c] + dh_need needs to be set to max(seclen, blocksize, ivlen, mac_len) + ok dtucker@, noted by mancha + +commit 76eea4ab4e658670ca6e76dd1e6d17f262208b57 +Author: Damien Miller +Date: Sun Jan 26 09:37:25 2014 +1100 + + - dtucker@cvs.openbsd.org 2014/01/25 10:12:50 + [cipher.c cipher.h kex.c kex.h kexgexc.c] + Add a special case for the DH group size for 3des-cbc, which has an + effective strength much lower than the key size. This causes problems + with some cryptlib implementations, which don't support group sizes larger + than 4k but also don't use the largest group size it does support as + specified in the RFC. Based on a patch from Petr Lautrbach at Redhat, + reduced by me with input from Markus. ok djm@ markus@ + +commit 603b8f47f1cd9ed95a2017447db8e60ca6704594 +Author: Damien Miller +Date: Sat Jan 25 13:16:59 2014 +1100 + + - (djm) [configure.ac] autoconf sets finds to 'yes' not '1', so test + against the correct thing. + +commit c96d85376d779b6ac61525b5440010d344d2f23f +Author: Damien Miller +Date: Sat Jan 25 13:12:28 2014 +1100 + + - (djm) [configure.ac] Do not attempt to use capsicum sandbox unless + sys/capability.h exists and cap_rights_limit is in libc. Fixes + build on FreeBSD9x which provides the header but not the libc + support. + +commit f62ecef9939cb3dbeb10602fd705d4db3976d822 +Author: Damien Miller +Date: Sat Jan 25 12:34:38 2014 +1100 + + - (djm) [configure.ac] Fix detection of capsicum sandbox on FreeBSD + +commit b0e0f760b861676a3fe5c40133b270713d5321a9 +Author: Damien Miller +Date: Fri Jan 24 14:27:04 2014 +1100 + + - (djm) [Makefile.in regress/scp-ssh-wrapper.sh regress/scp.sh] Make + the scp regress test actually test the built scp rather than the one + in $PATH. ok dtucker@ + +commit 42a092530159637da9cb7f9e1b5f4679e34a85e6 +Author: Darren Tucker +Date: Thu Jan 23 23:14:39 2014 +1100 + + - (dtucker) [configure.ac] NetBSD's (and FreeBSD's) strnvis is gratuitously + incompatible with OpenBSD's despite post-dating it by more than a decade. + Declare it as broken, and document FreeBSD's as the same. ok djm@ + +commit 617da33c20cb59f9ea6c99c881d92493371ef7b8 +Author: Tim Rice +Date: Wed Jan 22 19:16:10 2014 -0800 + + - (tim) [session.c] Improve error reporting on set_id(). + +commit 5c2ff5e31f57d303ebb414d84a934c02728fa568 +Author: Damien Miller +Date: Wed Jan 22 21:30:12 2014 +1100 + + - (djm) [configure.ac aclocal.m4] More tests to detect fallout from + platform hardening options: include some long long int arithmatic + to detect missing support functions for -ftrapv in libgcc and + equivalents, actually test linking when -ftrapv is supplied and + set either both -pie/-fPIE or neither. feedback and ok dtucker@ + +commit 852472a54b8a0dc3e53786b313baaa86850a4273 +Author: Damien Miller +Date: Wed Jan 22 16:31:18 2014 +1100 + + - (djm) [configure.ac] Unless specifically requested, only attempt + to build Position Independent Executables on gcc >= 4.x; ok dtucker + +commit ee87838786cef0194db36ae0675b3e7c4e8ec661 +Author: Damien Miller +Date: Wed Jan 22 16:30:15 2014 +1100 + + - (djm) [openbsd-compat/setproctitle.c] Don't fail to compile if a + platform that is expected to use the reuse-argv style setproctitle + hack surprises us by providing a setproctitle in libc; ok dtucker + +commit 5c96a154c7940fa67b1f11c421e390dbbc159f27 +Author: Damien Miller +Date: Tue Jan 21 13:10:26 2014 +1100 + + - (djm) [aclocal.m4] Flesh out the code run in the OSSH_CHECK_CFLAG_COMPILE + and OSSH_CHECK_LDFLAG_LINK tests to give them a better chance of + detecting toolchain-related problems; ok dtucker + +commit 9464ba6fb34bb42eb3501ec3c5143662e75674bf +Author: Tim Rice +Date: Mon Jan 20 17:59:28 2014 -0800 + + - (tim) [platform.c session.c] Fix bug affecting SVR5 platforms introduced + with sftp chroot support. Move set_id call after chroot. + +commit a6d573caa14d490e6c42fb991bcb5c6860ec704b +Author: Darren Tucker +Date: Tue Jan 21 12:50:46 2014 +1100 + + - (dtucker) [aclocal.m4] Differentiate between compile-time and link-time + tests in the configure output. ok djm. + +commit 096118dc73ab14810b3c12785c0b5acb01ad6123 +Author: Darren Tucker +Date: Tue Jan 21 12:48:51 2014 +1100 + + - (dtucker) [configure.ac] Make PIE a configure-time option which defaults + to on platforms where it's known to be reliably detected and off elsewhere. + Works around platforms such as FreeBSD 9.1 where it does not interop with + -ftrapv (it seems to work but fails when trying to link ssh). ok djm@ + +commit f9df7f6f477792254eab33cdef71a6d66488cb88 +Author: Damien Miller +Date: Mon Jan 20 20:07:15 2014 +1100 + + - (djm) [regress/cert-hostkey.sh] Fix regress failure on platforms that + skip one or more key types (e.g. RHEL/CentOS 6.5); ok dtucker@ + +commit c74e70eb52ccc0082bd5a70b5798bb01c114d138 +Author: Darren Tucker +Date: Mon Jan 20 13:18:09 2014 +1100 + + - (dtucker) [gss-serv-krb5.c] Fall back to krb5_cc_gen_new if the Kerberos + implementation does not have krb5_cc_new_unique, similar to what we do + in auth-krb5.c. + +commit 3510979e83b6a18ec8773c64c3fa04aa08b2e783 +Author: Damien Miller +Date: Mon Jan 20 12:41:53 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/20 00:08:48 + [digest.c] + memleak; found by Loganaden Velvindron @ AfriNIC; ok markus@ + +commit 7eee358d7a6580479bee5cd7e52810ebfd03e5b2 +Author: Darren Tucker +Date: Sun Jan 19 22:37:02 2014 +1100 + + - dtucker@cvs.openbsd.org 2014/01/19 11:21:51 + [addrmatch.c] + Cast the sizeof to socklen_t so it'll work even if the supplied len is + negative. Suggested by and ok djm, ok deraadt. + +commit b7e01c09b56ab26e8fac56bbce0fd25e36d12bb0 +Author: Darren Tucker +Date: Sun Jan 19 22:36:13 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/19 04:48:08 + [ssh_config.5] + fix inverted meaning of 'no' and 'yes' for CanonicalizeFallbackLocal + +commit 7b1ded04adce42efa25ada7c3a39818d3109b724 +Author: Darren Tucker +Date: Sun Jan 19 15:30:02 2014 +1100 + + - dtucker@cvs.openbsd.org 2014/01/19 04:17:29 + [canohost.c addrmatch.c] + Cast socklen_t when comparing to size_t and use socklen_t to iterate over + the ip options, both to prevent signed/unsigned comparison warnings. + Patch from vinschen at redhat via portable openssh, begrudging ok deraadt. + +commit 293ee3c9f0796d99ebb033735f0e315f2e0180bf +Author: Darren Tucker +Date: Sun Jan 19 15:28:01 2014 +1100 + + - dtucker@cvs.openbsd.org 2014/01/18 09:36:26 + [session.c] + explicitly define USE_PIPES to 1 to prevent redefinition warnings in + portable on platforms that use pipes for everything. From redhat @ + redhat. + +commit 2aca159d05f9e7880d1d8f1ce49a218840057f53 +Author: Darren Tucker +Date: Sun Jan 19 15:25:34 2014 +1100 + + - dtucker@cvs.openbsd.org 2014/01/17 06:23:24 + [sftp-server.c] + fix log message statvfs. ok djm + +commit 841f7da89ae8b367bb502d61c5c41916c6e7ae4c +Author: Darren Tucker +Date: Sat Jan 18 22:12:15 2014 +1100 + + - (dtucker) [sandbox-capsicum.c] Correct some error messages and make the + return value check for cap_enter() consistent with the other uses in + FreeBSD. From by Loganaden Velvindron @ AfriNIC via bz#2140. + +commit fdce3731660699b2429e93e822f2ccbaccd163ae +Author: Darren Tucker +Date: Sat Jan 18 21:12:42 2014 +1100 + + - (dtucker) [configure.ac] On Cygwin the getopt variables (like optargs, + optind) are defined in getopt.h already. Unfortunately they are defined as + "declspec(dllimport)" for historical reasons, because the GNU linker didn't + allow auto-import on PE/COFF targets way back when. The problem is the + dllexport attributes collide with the definitions in the various source + files in OpenSSH, which obviousy define the variables without + declspec(dllimport). The least intrusive way to get rid of these warnings + is to disable warnings for GCC compiler attributes when building on Cygwin. + Patch from vinschen at redhat.com. + +commit 1411c9263f46e1ee49d0d302bf7258ebe69ce827 +Author: Darren Tucker +Date: Sat Jan 18 21:03:59 2014 +1100 + + - (dtucker) [openbsd-compat/bsd-cygwin_util.h] Add missing function + declarations that stopped being included when we stopped including + from openbsd-compat/bsd-cygwin_util.h. Patch from vinschen at + redhat.com. + +commit 89c532d843c95a085777c66365067d64d1937eb9 +Author: Darren Tucker +Date: Sat Jan 18 20:43:49 2014 +1100 + + - (dtucker) [uidswap.c] Prevent unused variable warnings on Cygwin. Patch + from vinschen at redhat.com + +commit 355f861022be7b23d3009fae8f3c9f6f7fc685f7 +Author: Darren Tucker +Date: Sat Jan 18 00:12:38 2014 +1100 + + - (dtucker) [defines.h] Move our definitions of uintXX_t types down to after + they're defined if we have to define them ourselves. Fixes builds on old + AIX. + +commit a3357661ee1d5d553294f36e4940e8285c7f1332 +Author: Darren Tucker +Date: Sat Jan 18 00:03:57 2014 +1100 + + - (dtucker) [readconf.c] Wrap paths.h inside an ifdef. Allows building on + Solaris. + +commit 9edcbff46ff01c8d5dee9c1aa843f09e9ad8a80e +Author: Darren Tucker +Date: Fri Jan 17 21:54:32 2014 +1100 + + - (dtucker) [configure.ac] Have --without-toolchain-hardening not turn off + stack-protector since that has a separate flag that's been around a while. + +commit 6d725687c490d4ba957a1bbc0ba0a2956c09fa69 +Author: Darren Tucker +Date: Fri Jan 17 19:17:34 2014 +1100 + + - (dtucker) [configure.ac] Also look in inttypes.h for uintXX_t types. + +commit 5055699c7f7c7ef21703a443ec73117da392f6ae +Author: Darren Tucker +Date: Fri Jan 17 18:48:22 2014 +1100 + + - (dtucker) [openbsd-compat/bsd-statvfs.h] Only start including headers if we + need them to cut down on the name collisions. + +commit a5cf1e220def07290260e4125e74f41ac75cf88d +Author: Darren Tucker +Date: Fri Jan 17 18:10:58 2014 +1100 + + - (dtucker) [configure.ac openbsd-compat/bsd-statvfs.c + openbsd-compat/bsd-statvfs.h] Implement enough of statvfs on top of statfs + to be useful (and for the regression tests to pass) on platforms that + have statfs and fstatfs. ok djm@ + +commit 1357d71d7b6d269969520aaa3e84d312ec971d5b +Author: Darren Tucker +Date: Fri Jan 17 18:00:40 2014 +1100 + + - (dtucker) Fix typo in #ifndef. + +commit d23a91ffb289d3553a58b7a60cec39fba9f0f506 +Author: Darren Tucker +Date: Fri Jan 17 17:32:30 2014 +1100 + + - (dtucker) [configure.ac digest.c openbsd-compat/openssl-compat.c + openbsd-compat/openssl-compat.h] Add compatibility layer for older + openssl versions. ok djm@ + +commit 868ea1ea1c1bfdbee5dbad78f81999c5983ecf31 +Author: Damien Miller +Date: Fri Jan 17 16:47:04 2014 +1100 + + - (djm) [Makefile.in configure.ac sandbox-capsicum.c sandbox-darwin.c] + [sandbox-null.c sandbox-rlimit.c sandbox-seccomp-filter.c] + [sandbox-systrace.c ssh-sandbox.h sshd.c] Support preauth sandboxing + using the Capsicum API introduced in FreeBSD 10. Patch by Dag-Erling + Smorgrav, updated by Loganaden Velvindron @ AfriNIC; ok dtucker@ + +commit a9d186a8b50d18869a10e9203abf71c83ddb1f79 +Author: Darren Tucker +Date: Fri Jan 17 16:30:49 2014 +1100 + + - dtucker@cvs.openbsd.org 2014/01/17 05:26:41 + [digest.c] + remove unused includes. ok djm@ + +commit 5f1c57a7a7eb39c0e4fee3367712337dbcaef024 +Author: Darren Tucker +Date: Fri Jan 17 16:29:45 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/17 00:21:06 + [sftp-client.c] + signed/unsigned comparison warning fix; from portable (Id sync only) + +commit c548722361d89fb12c108528f96b306a26477b18 +Author: Darren Tucker +Date: Fri Jan 17 15:12:16 2014 +1100 + + - (dtucker) [configure.ac] Split AC_CHECK_FUNCS for OpenSSL functions into + separate lines and alphabetize for easier diffing of changes. + +commit acad351a5b1c37de9130c9c1710445cc45a7f6b9 +Author: Darren Tucker +Date: Fri Jan 17 14:20:05 2014 +1100 + + - (dtucker) [defines.h] Add typedefs for uintXX_t types for platforms that + don't have them. + +commit c3ed065ce8417aaa46490836648c173a5010f226 +Author: Darren Tucker +Date: Fri Jan 17 14:18:45 2014 +1100 + + - (dtucker) [openbsd-compat/bcrypt_pbkdf.c] Wrap stdlib.h include inside + #ifdef HAVE_STDINT_H. + +commit f45f78ae437062c7d9506c5f475b7215f486be44 +Author: Darren Tucker +Date: Fri Jan 17 12:43:43 2014 +1100 + + - (dtucker) [blocks.c fe25519.c ge25519.c hash.c sc25519.c verify.c] Include + includes.h to pull in all of the compatibility stuff. + +commit 99df369d0340caac145d57f700d830147ff18b87 +Author: Darren Tucker +Date: Fri Jan 17 12:42:17 2014 +1100 + + - (dtucker) [poly1305.c] Wrap stdlib.h include inside #ifdef HAVE_STDINT_H. + +commit ac413b62ea1957e80c711acbe0c11b908273fc01 +Author: Darren Tucker +Date: Fri Jan 17 12:31:33 2014 +1100 + + - (dtucker) [crypto_api.h] Wrap stdlib.h include inside #ifdef HAVE_STDINT_H. + +commit 1c4a011e9c939e74815346a560843e1862c300b8 +Author: Darren Tucker +Date: Fri Jan 17 12:23:23 2014 +1100 + + - (dtucker) [loginrec.c] Cast to the types specfied in the format + specification to prevent warnings. + +commit c3d483f9a8275be1113535a1e0d0e384f605f3c4 +Author: Damien Miller +Date: Fri Jan 17 11:20:26 2014 +1100 + + - (djm) [sftp-client.c] signed/unsigned comparison fix + +commit fd994379dd972417d0491767f7cd9b5bf23f4975 +Author: Darren Tucker +Date: Fri Jan 17 09:53:24 2014 +1100 + + - (dtucker) [aclocal.m4 configure.ac] Add some additional compiler/toolchain + hardening flags including -fstack-protector-strong. These default to on + if the toolchain supports them, but there is a configure-time knob + (--without-hardening) to disable them if necessary. ok djm@ + +commit 366224d21768ee8ec28cfbcc5fbade1b32582d58 +Author: Damien Miller +Date: Thu Jan 16 18:51:44 2014 +1100 + + - (djm) [README] update release notes URL. + +commit 2ae77e64f8fa82cbf25c9755e8e847709b978b40 +Author: Damien Miller +Date: Thu Jan 16 18:51:07 2014 +1100 + + - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] Crank RPM spec version numbers. + +commit 0fa29e6d777c73a1b4ddd3b996b06ee20022ae8a +Author: Damien Miller +Date: Thu Jan 16 18:42:31 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/16 07:32:00 + [version.h] + openssh-6.5 + +commit 52c371cd6d2598cc73d4e633811b3012119c47e2 +Author: Damien Miller +Date: Thu Jan 16 18:42:10 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/16 07:31:09 + [sftp-client.c] + needless and incorrect cast to size_t can break resumption of + large download; patch from tobias@ + +commit 91b580e4bec55118bf96ab3cdbe5a50839e75d0a +Author: Damien Miller +Date: Sun Jan 12 19:21:22 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/12 08:13:13 + [bufaux.c buffer.h kex.c kex.h kexc25519.c kexc25519c.c kexc25519s.c] + [kexdhc.c kexdhs.c kexecdhc.c kexecdhs.c kexgexc.c kexgexs.c] + avoid use of OpenSSL BIGNUM type and functions for KEX with + Curve25519 by adding a buffer_put_bignum2_from_string() that stores + a string using the bignum encoding rules. Will make it easier to + build a reduced-feature OpenSSH without OpenSSL in the future; + ok markus@ + +commit af5d4481f4c7c8c3c746e68b961bb85ef907800e +Author: Damien Miller +Date: Sun Jan 12 19:20:47 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/10 05:59:19 + [sshd_config] + the /etc/ssh/ssh_host_ed25519_key is loaded by default too + +commit 58cd63bc63038acddfb4051ed14e11179d8f4941 +Author: Damien Miller +Date: Fri Jan 10 10:59:24 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/09 23:26:48 + [sshconnect.c sshd.c] + ban clients/servers that suffer from SSH_BUG_DERIVEKEY, they are ancient, + deranged and might make some attacks on KEX easier; ok markus@ + +commit b3051d01e505c9c2dc00faab472a0d06fa6b0e65 +Author: Damien Miller +Date: Fri Jan 10 10:58:53 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/09 23:20:00 + [digest.c digest.h hostfile.c kex.c kex.h kexc25519.c kexc25519c.c] + [kexc25519s.c kexdh.c kexecdh.c kexecdhc.c kexecdhs.c kexgex.c kexgexc.c] + [kexgexs.c key.c key.h roaming_client.c roaming_common.c schnorr.c] + [schnorr.h ssh-dss.c ssh-ecdsa.c ssh-rsa.c sshconnect2.c] + Introduce digest API and use it to perform all hashing operations + rather than calling OpenSSL EVP_Digest* directly. Will make it easier + to build a reduced-feature OpenSSH without OpenSSL in future; + feedback, ok markus@ + +commit e00e413dd16eb747fb2c15a099971d91c13cf70f +Author: Damien Miller +Date: Fri Jan 10 10:40:45 2014 +1100 + + - guenther@cvs.openbsd.org 2014/01/09 03:26:00 + [sftp-common.c] + When formating the time for "ls -l"-style output, show dates in the future + with the year, and rearrange a comparison to avoid a potentional signed + arithmetic overflow that would give the wrong result. + + ok djm@ + +commit 3e49853650448883685cfa32fa382d0ba6d51d48 +Author: Damien Miller +Date: Fri Jan 10 10:37:05 2014 +1100 + + - tedu@cvs.openbsd.org 2014/01/04 17:50:55 + [mac.c monitor_mm.c monitor_mm.h xmalloc.c] + use standard types and formats for size_t like variables. ok dtucker + +commit a9c1e500ef609795cbc662848edb1a1dca279c81 +Author: Damien Miller +Date: Wed Jan 8 16:13:12 2014 +1100 + + - (djm) [regress/.cvsignore] Ignore regress test droppings; ok dtucker@ + +commit 324541e5264e1489ca0babfaf2b39612eb80dfb3 +Author: Damien Miller +Date: Tue Dec 31 12:25:40 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/30 23:52:28 + [auth2-hostbased.c auth2-pubkey.c compat.c compat.h ssh-rsa.c] + [sshconnect.c sshconnect2.c sshd.c] + refuse RSA keys from old proprietary clients/servers that use the + obsolete RSA+MD5 signature scheme. it will still be possible to connect + with these clients/servers but only DSA keys will be accepted, and we'll + deprecate them entirely in a future release. ok markus@ + +commit 9f4c8e797ea002a883307ca906f1f1f815010e78 +Author: Damien Miller +Date: Sun Dec 29 17:57:46 2013 +1100 + + - (djm) [regress/Makefile] Add some generated files for cleaning + +commit 106bf1ca3c7a5fdc34f9fd7a1fe651ca53085bc5 +Author: Damien Miller +Date: Sun Dec 29 17:54:03 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/29 05:57:02 + [sshconnect.c] + when showing other hostkeys, don't forget Ed25519 keys + +commit 0fa47cfb32c239117632cab41e4db7d3e6de5e91 +Author: Damien Miller +Date: Sun Dec 29 17:53:39 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/29 05:42:16 + [ssh.c] + don't forget to load Ed25519 certs too + +commit b9a95490daa04cc307589897f95bfaff324ad2c9 +Author: Damien Miller +Date: Sun Dec 29 17:50:15 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/29 04:35:50 + [authfile.c] + don't refuse to load Ed25519 certificates + +commit f72cdde6e6fabc51d2a62f4e75b8b926d9d7ee89 +Author: Damien Miller +Date: Sun Dec 29 17:49:55 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/29 04:29:25 + [authfd.c] + allow deletion of ed25519 keys from the agent + +commit 29ace1cb68cc378a464c72c0fd67aa5f9acd6b5b +Author: Damien Miller +Date: Sun Dec 29 17:49:31 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/29 04:20:04 + [key.c] + to make sure we don't omit any key types as valid CA keys again, + factor the valid key type check into a key_type_is_valid_ca() + function + +commit 9de4fcdc5a9cff48d49a3e2f6194d3fb2d7ae34d +Author: Damien Miller +Date: Sun Dec 29 17:49:13 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/29 02:49:52 + [key.c] + correct comment for key_drop_cert() + +commit 5baeacf8a80f054af40731c6f92435f9164b8e02 +Author: Damien Miller +Date: Sun Dec 29 17:48:55 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/29 02:37:04 + [key.c] + correct comment for key_to_certified() + +commit 83f2fe26cb19330712c952eddbd3c0b621674adc +Author: Damien Miller +Date: Sun Dec 29 17:48:38 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/29 02:28:10 + [key.c] + allow ed25519 keys to appear as certificate authorities + +commit 06122e9a74bb488b0fe0a8f64e1135de870f9cc0 +Author: Damien Miller +Date: Sun Dec 29 17:48:15 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/27 22:37:18 + [ssh-rsa.c] + correct comment + +commit 3e19295c3a253c8dc8660cf45baad7f45fccb969 +Author: Damien Miller +Date: Sun Dec 29 17:47:50 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/27 22:30:17 + [ssh-dss.c ssh-ecdsa.c ssh-rsa.c] + make the original RSA and DSA signing/verification code look more like + the ECDSA/Ed25519 ones: use key_type_plain() when checking the key type + rather than tediously listing all variants, use __func__ for debug/ + error messages + +commit 137977180be6254639e2c90245763e6965f8d815 +Author: Damien Miller +Date: Sun Dec 29 17:47:14 2013 +1100 + + - tedu@cvs.openbsd.org 2013/12/21 07:10:47 + [ssh-keygen.1] + small typo + +commit 339a48fe7ffb3186d22bbaa9efbbc3a053e602fd +Author: Damien Miller +Date: Sun Dec 29 17:46:49 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/19 22:57:13 + [poly1305.c poly1305.h] + use full name for author, with his permission + +commit 0b36c83148976c7c8268f4f41497359e2fb26251 +Author: Damien Miller +Date: Sun Dec 29 17:45:51 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/19 01:19:41 + [ssh-agent.c] + bz#2186: don't crash (NULL deref) when deleting PKCS#11 keys from an agent + that has a mix of normal and PKCS#11 keys; fix from jay AT slushpupie.com; + ok dtucker + +commit 4def184e9b6c36be6d965a9705632fc4c0c2a8af +Author: Damien Miller +Date: Sun Dec 29 17:45:26 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/19 01:04:36 + [channels.c] + bz#2147: fix multiple remote forwardings with dynamically assigned + listen ports. In the s->c message to open the channel we were sending + zero (the magic number to request a dynamic port) instead of the actual + listen port. The client therefore had no way of discriminating between + them. + + Diagnosis and fix by ronf AT timeheart.net + +commit bf25d114e23a803f8feca8926281b1aaedb6191b +Author: Damien Miller +Date: Sun Dec 29 17:44:56 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/19 00:27:57 + [auth-options.c] + simplify freeing of source-address certificate restriction + +commit bb3dafe7024a5b4e851252e65ee35d45b965e4a8 +Author: Damien Miller +Date: Sun Dec 29 17:44:29 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/12/19 00:19:12 + [serverloop.c] + Cast client_alive_interval to u_int64_t before assinging to + max_time_milliseconds to avoid potential integer overflow in the timeout. + bz#2170, patch from Loganaden Velvindron, ok djm@ + +commit ef275ead3dcadde4db1efe7a0aa02b5e618ed40c +Author: Damien Miller +Date: Sun Dec 29 17:44:07 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/19 00:10:30 + [ssh-add.c] + skip requesting smartcard PIN when removing keys from agent; bz#2187 + patch from jay AT slushpupie.com; ok dtucker + +commit 7d97fd9a1cae778c3eacf16e09f5da3689d616c6 +Author: Damien Miller +Date: Sun Dec 29 17:40:18 2013 +1100 + + - (djm) [loginrec.c] Check for username truncation when looking up lastlog + entries + +commit 77244afe3b6d013b485e0952eaab89b9db83380f +Author: Darren Tucker +Date: Sat Dec 21 17:02:39 2013 +1100 + + 20131221 + - (dtucker) [regress/keytype.sh] Actually test ecdsa key types. + +commit 53f8e784dc431a82d31c9b0e95b144507f9330e9 +Author: Darren Tucker +Date: Thu Dec 19 11:31:44 2013 +1100 + + - (dtucker) [auth-pam.c] bz#2163: check return value from pam_get_item(). + Patch from Loganaden Velvindron. + +commit 1fcec9d4f265e38af248c4c845986ca8c174bd68 +Author: Darren Tucker +Date: Thu Dec 19 11:00:12 2013 +1100 + + - (dtucker) [configure.ac] bz#2178: Don't try to use BSM on Solaris versions + greater than 11 either rather than just 11. Patch from Tomas Kuthan. + +commit 6674eb9683afd1ea4eb35670b5e66815543a759e +Author: Damien Miller +Date: Wed Dec 18 17:50:39 2013 +1100 + + - markus@cvs.openbsd.org 2013/12/17 10:36:38 + [crypto_api.h] + I've assempled the header file by cut&pasting from generated headers + and the source files. + +commit d58a5964426ee014384d67d775d16712e93057f3 +Author: Damien Miller +Date: Wed Dec 18 17:50:13 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/15 21:42:35 + [cipher-chachapoly.c] + add some comments and constify a constant + +commit 059321d19af24d87420de3193f79dfab23556078 +Author: Damien Miller +Date: Wed Dec 18 17:49:48 2013 +1100 + + - pascal@cvs.openbsd.org 2013/12/15 18:17:26 + [ssh-add.c] + Make ssh-add also add .ssh/id_ed25519; fixes lie in manual page. + ok markus@ + +commit 155b5a5bf158767f989215479ded2a57f331e1c6 +Author: Damien Miller +Date: Wed Dec 18 17:48:32 2013 +1100 + + - markus@cvs.openbsd.org 2013/12/09 11:08:17 + [crypto_api.h] + remove unused defines + +commit 8a56dc2b6b48b05590810e7f4c3567508410000c +Author: Damien Miller +Date: Wed Dec 18 17:48:11 2013 +1100 + + - markus@cvs.openbsd.org 2013/12/09 11:03:45 + [blocks.c ed25519.c fe25519.c fe25519.h ge25519.c ge25519.h] + [ge25519_base.data hash.c sc25519.c sc25519.h verify.c] + Add Authors for the public domain ed25519/nacl code. + see also http://nacl.cr.yp.to/features.html + All of the NaCl software is in the public domain. + and http://ed25519.cr.yp.to/software.html + The Ed25519 software is in the public domain. + +commit 6575c3acf31fca117352f31f37b16ae46e664837 +Author: Damien Miller +Date: Wed Dec 18 17:47:02 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/12/08 09:53:27 + [sshd_config.5] + Use a literal for the default value of KEXAlgorithms. ok deraadt jmc + +commit 8ba0ead6985ea14999265136b14ffd5aeec516f9 +Author: Damien Miller +Date: Wed Dec 18 17:46:27 2013 +1100 + + - naddy@cvs.openbsd.org 2013/12/07 11:58:46 + [ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh-keysign.8 ssh.1] + [ssh_config.5 sshd.8 sshd_config.5] + add missing mentions of ed25519; ok djm@ + +commit 4f752cf71cf44bf4bc777541156c2bf56daf9ce9 +Author: Damien Miller +Date: Wed Dec 18 17:45:35 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/07 08:08:26 + [ssh-keygen.1] + document -a and -o wrt new key format + +commit 6d6fcd14e23a9053198342bb379815b15e504084 +Author: Damien Miller +Date: Sun Dec 8 15:53:28 2013 +1100 + + - (djm) [Makefile.in regress/Makefile regress/agent-ptrace.sh] + [regress/setuid-allowed.c] Check that ssh-agent is not on a no-setuid + filesystem before running agent-ptrace.sh; ok dtucker + +commit 7e6e42fb532c7dafd7078ef5e9e2d3e47fcf6752 +Author: Damien Miller +Date: Sun Dec 8 08:23:08 2013 +1100 + + - (djm) [openbsd-compat/bsd-setres_id.c] Missing header; from Corinna + Vinschen + +commit da3ca351b49d52ae85db2e3998265dc3c6617068 +Author: Damien Miller +Date: Sat Dec 7 21:43:46 2013 +1100 + + - (djm) [Makefile.in] PATHSUBS and keygen bits for Ed25519; from + Loganaden Velvindron @ AfriNIC in bz#2179 + +commit eb401585bb8336cbf81fe4fc58eb9f7cac3ab874 +Author: Damien Miller +Date: Sat Dec 7 17:07:15 2013 +1100 + + - (djm) [regress/cert-hostkey.sh] Fix merge botch + +commit f54542af3ad07532188b10136ae302314ec69ed6 +Author: Damien Miller +Date: Sat Dec 7 16:32:44 2013 +1100 + + - markus@cvs.openbsd.org 2013/12/06 13:52:46 + [regress/Makefile regress/agent.sh regress/cert-hostkey.sh] + [regress/cert-userkey.sh regress/keytype.sh] + test ed25519 support; from djm@ + +commit f104da263de995f66b6861b4f3368264ee483d7f +Author: Damien Miller +Date: Sat Dec 7 12:37:53 2013 +1100 + + - (djm) [ed25519.c ssh-ed25519.c openbsd-compat/Makefile.in] + [openbsd-compat/bcrypt_pbkdf.c] Make ed25519/new key format compile on + Linux + +commit 1ff130dac9b7aea0628f4ad30683431fe35e0020 +Author: Damien Miller +Date: Sat Dec 7 11:51:51 2013 +1100 + + - [configure.ac openbsd-compat/Makefile.in openbsd-compat/bcrypt_pbkdf.c] + [openbsd-compat/blf.h openbsd-compat/blowfish.c] + [openbsd-compat/openbsd-compat.h] Start at supporting bcrypt_pbkdf in + portable. + +commit 4260828a2958ebe8c96f66d8301dac53f4cde556 +Author: Damien Miller +Date: Sat Dec 7 11:38:03 2013 +1100 + + - [authfile.c] Conditionalise inclusion of util.h + +commit a913442bac8a26fd296a3add51293f8f6f9b3b4c +Author: Damien Miller +Date: Sat Dec 7 11:35:36 2013 +1100 + + - [Makefile.in] Add ed25519 sources + +commit ca570a519cb846da61d002c7f46fa92e39c83e45 +Author: Damien Miller +Date: Sat Dec 7 11:29:09 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/07 00:19:15 + [key.c] + set k->cert = NULL after freeing it + +commit 3cccc0e155229a2f2d86b6df40bd4559b4f960ff +Author: Damien Miller +Date: Sat Dec 7 11:27:47 2013 +1100 + + - [blocks.c ed25519.c fe25519.c fe25519.h ge25519.c ge25519.h] + [ge25519_base.data hash.c sc25519.c sc25519.h verify.c] Fix RCS idents + +commit a7827c11b3f0380b7e593664bd62013ff9c131db +Author: Damien Miller +Date: Sat Dec 7 11:24:30 2013 +1100 + + - jmc@cvs.openbsd.org 2013/12/06 15:29:07 + [sshd.8] + missing comma; + +commit 5be9d9e3cbd9c66f24745d25bf2e809c1d158ee0 +Author: Damien Miller +Date: Sat Dec 7 11:24:01 2013 +1100 + + - markus@cvs.openbsd.org 2013/12/06 13:39:49 + [authfd.c authfile.c key.c key.h myproposal.h pathnames.h readconf.c] + [servconf.c ssh-agent.c ssh-keygen.c ssh-keyscan.1 ssh-keyscan.c] + [ssh-keysign.c ssh.c ssh_config.5 sshd.8 sshd.c verify.c ssh-ed25519.c] + [sc25519.h sc25519.c hash.c ge25519_base.data ge25519.h ge25519.c] + [fe25519.h fe25519.c ed25519.c crypto_api.h blocks.c] + support ed25519 keys (hostkeys and user identities) using the public + domain ed25519 reference code from SUPERCOP, see + http://ed25519.cr.yp.to/software.html + feedback, help & ok djm@ + +commit bcd00abd8451f36142ae2ee10cc657202149201e +Author: Damien Miller +Date: Sat Dec 7 10:41:55 2013 +1100 + + - markus@cvs.openbsd.org 2013/12/06 13:34:54 + [authfile.c authfile.h cipher.c cipher.h key.c packet.c ssh-agent.c] + [ssh-keygen.c PROTOCOL.key] new private key format, bcrypt as KDF by + default; details in PROTOCOL.key; feedback and lots help from djm; + ok djm@ + +commit f0e9060d236c0e38bec2fa1c6579fb0a2ea6458d +Author: Damien Miller +Date: Sat Dec 7 10:40:26 2013 +1100 + + - markus@cvs.openbsd.org 2013/12/06 13:30:08 + [authfd.c key.c key.h ssh-agent.c] + move private key (de)serialization to key.c; ok djm + +commit 0f8536da23a6ef26e6495177c0d8a4242b710289 +Author: Damien Miller +Date: Sat Dec 7 10:31:37 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/06 03:40:51 + [ssh-keygen.c] + remove duplicated character ('g') in getopt() string; + document the (few) remaining option characters so we don't have to + rummage next time. + +commit 393920745fd328d3fe07f739a3cf7e1e6db45b60 +Author: Damien Miller +Date: Sat Dec 7 10:31:08 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/05 22:59:45 + [sftp-client.c] + fix memory leak in error path in do_readdir(); pointed out by + Loganaden Velvindron @ AfriNIC in bz#2163 + +commit 534b2ccadea5e5e9a8b27226e6faac3ed5552e97 +Author: Damien Miller +Date: Thu Dec 5 14:07:27 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/05 01:16:41 + [servconf.c servconf.h] + bz#2161 - fix AuthorizedKeysCommand inside a Match block and + rearrange things so the same error is harder to make next time; + with and ok dtucker@ + +commit 8369c8e61a3408ec6bb75755fad4ffce29b5fdbe +Author: Darren Tucker +Date: Thu Dec 5 11:00:16 2013 +1100 + + - (dtucker) [configure.ac] bz#2173: use pkg-config --libs to include correct + -L location for libedit. Patch from Serge van den Boom. + +commit 9275df3e0a2a3bc3897f7d664ea86a425c8a092d +Author: Damien Miller +Date: Thu Dec 5 10:26:32 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/04 04:20:01 + [sftp-client.c] + bz#2171: don't leak local_fd on error; from Loganaden Velvindron @ + AfriNIC + +commit 960f6a2b5254e4da082d8aa3700302ed12dc769a +Author: Damien Miller +Date: Thu Dec 5 10:26:14 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/02 03:13:14 + [cipher.c] + correct bzero of chacha20+poly1305 key context. bz#2177 from + Loganaden Velvindron @ AfriNIC + + Also make it a memset for consistency with the rest of cipher.c + +commit f7e8a8796d661c9d6692ab837e1effd4f5ada1c2 +Author: Damien Miller +Date: Thu Dec 5 10:25:51 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/02 03:09:22 + [key.c] + make key_to_blob() return a NULL blob on failure; part of + bz#2175 from Loganaden Velvindron @ AfriNIC + +commit f1e44ea9d9a6d4c1a95a0024132e603bd1778c9c +Author: Damien Miller +Date: Thu Dec 5 10:23:21 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/02 02:56:17 + [ssh-pkcs11-helper.c] + use-after-free; bz#2175 patch from Loganaden Velvindron @ AfriNIC + +commit 114e540b15d57618f9ebf624264298f80bbd8c77 +Author: Damien Miller +Date: Thu Dec 5 10:22:57 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/02 02:50:27 + [PROTOCOL.chacha20poly1305] + typo; from Jon Cave + +commit e4870c090629e32f2cb649dc16d575eeb693f4a8 +Author: Damien Miller +Date: Thu Dec 5 10:22:39 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/01 23:19:05 + [PROTOCOL] + mention curve25519-sha256@libssh.org key exchange algorithm + +commit 1d2f8804a6d33a4e908b876b2e1266b8260ec76b +Author: Damien Miller +Date: Thu Dec 5 10:22:03 2013 +1100 + + - deraadt@cvs.openbsd.org 2013/11/26 19:15:09 + [pkcs11.h] + cleanup 1 << 31 idioms. Resurrection of this issue pointed out by + Eitan Adler ok markus for ssh, implies same change in kerberosV + +commit bdb352a54f82df94a548e3874b22f2d6ae90328d +Author: Damien Miller +Date: Thu Dec 5 10:20:52 2013 +1100 + + - jmc@cvs.openbsd.org 2013/11/26 12:14:54 + [ssh.1 ssh.c] + - put -Q in the right place + - Ar was a poor choice for the arguments to -Q. i've chosen an + admittedly equally poor Cm, at least consistent with the rest + of the docs. also no need for multiple instances + - zap a now redundant Nm + - usage() sync + +commit d937dc084a087090f1cf5395822c3ac958d33759 +Author: Damien Miller +Date: Thu Dec 5 10:19:54 2013 +1100 + + - deraadt@cvs.openbsd.org 2013/11/25 18:04:21 + [ssh.1 ssh.c] + improve -Q usage and such. One usage change is that the option is now + case-sensitive + ok dtucker markus djm + +commit dec0393f7ee8aabc7d9d0fc2c5fddb4bc649112e +Author: Damien Miller +Date: Thu Dec 5 10:18:43 2013 +1100 + + - jmc@cvs.openbsd.org 2013/11/21 08:05:09 + [ssh_config.5 sshd_config.5] + no need for .Pp before displays; + +commit 8a073cf57940aabf85e49799f89f5d5e9b072c1b +Author: Damien Miller +Date: Thu Nov 21 14:26:18 2013 +1100 + + - djm@cvs.openbsd.org 2013/11/21 03:18:51 + [regress/cipher-speed.sh regress/integrity.sh regress/rekey.sh] + [regress/try-ciphers.sh] + use new "ssh -Q cipher-auth" query to obtain lists of authenticated + encryption ciphers instead of specifying them manually; ensures that + the new chacha20poly1305@openssh.com mode is tested; + + ok markus@ and naddy@ as part of the diff to add + chacha20poly1305@openssh.com + +commit ea61b2179f63d48968dd2c9617621002bb658bfe +Author: Damien Miller +Date: Thu Nov 21 14:25:15 2013 +1100 + + - djm@cvs.openbsd.org 2013/11/21 03:16:47 + [regress/modpipe.c] + use unsigned long long instead of u_int64_t here to avoid warnings + on some systems portable OpenSSH is built on. + +commit 36aba25b0409d2db6afc84d54bc47a2532d38424 +Author: Damien Miller +Date: Thu Nov 21 14:24:42 2013 +1100 + + - djm@cvs.openbsd.org 2013/11/21 03:15:46 + [regress/krl.sh] + add some reminders for additional tests that I'd like to implement + +commit fa7a20bc289f09b334808d988746bc260a2f60c9 +Author: Damien Miller +Date: Thu Nov 21 14:24:08 2013 +1100 + + - naddy@cvs.openbsd.org 2013/11/18 05:09:32 + [regress/forward-control.sh] + bump timeout to 10 seconds to allow slow machines (e.g. Alpha PC164) + to successfully run this; ok djm@ + (ID sync only; our timeouts are already longer) + +commit 0fde8acdad78a4d20cadae974376cc0165f645ee +Author: Damien Miller +Date: Thu Nov 21 14:12:23 2013 +1100 + + - djm@cvs.openbsd.org 2013/11/21 00:45:44 + [Makefile.in PROTOCOL PROTOCOL.chacha20poly1305 authfile.c chacha.c] + [chacha.h cipher-chachapoly.c cipher-chachapoly.h cipher.c cipher.h] + [dh.c myproposal.h packet.c poly1305.c poly1305.h servconf.c ssh.1] + [ssh.c ssh_config.5 sshd_config.5] Add a new protocol 2 transport + cipher "chacha20-poly1305@openssh.com" that combines Daniel + Bernstein's ChaCha20 stream cipher and Poly1305 MAC to build an + authenticated encryption mode. + + Inspired by and similar to Adam Langley's proposal for TLS: + http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03 + but differs in layout used for the MAC calculation and the use of a + second ChaCha20 instance to separately encrypt packet lengths. + Details are in the PROTOCOL.chacha20poly1305 file. + + Feedback markus@, naddy@; manpage bits Loganden Velvindron @ AfriNIC + ok markus@ naddy@ + +commit fdb2306acdc3eb2bc46b6dfdaaf6005c650af22a +Author: Damien Miller +Date: Thu Nov 21 13:57:15 2013 +1100 + + - deraadt@cvs.openbsd.org 2013/11/20 20:54:10 + [canohost.c clientloop.c match.c readconf.c sftp.c] + unsigned casts for ctype macros where neccessary + ok guenther millert markus + +commit e00167307e4d3692695441e9bd712f25950cb894 +Author: Damien Miller +Date: Thu Nov 21 13:56:49 2013 +1100 + + - deraadt@cvs.openbsd.org 2013/11/20 20:53:10 + [scp.c] + unsigned casts for ctype macros where neccessary + ok guenther millert markus + +commit 23e00aa6ba9eee0e0c218f2026bf405ad4625832 +Author: Damien Miller +Date: Thu Nov 21 13:56:28 2013 +1100 + + - djm@cvs.openbsd.org 2013/11/20 02:19:01 + [sshd.c] + delay closure of in/out fds until after "Bad protocol version + identification..." message, as get_remote_ipaddr/get_remote_port + require them open. + +commit 867e6934be6521f87f04a5ab86702e2d1b314245 +Author: Damien Miller +Date: Thu Nov 21 13:56:06 2013 +1100 + + - markus@cvs.openbsd.org 2013/11/13 13:48:20 + [ssh-pkcs11.c] + add missing braces found by pedro + +commit 0600c7020f4fe68a780bd7cf21ff541a8d4b568a +Author: Damien Miller +Date: Thu Nov 21 13:55:43 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/11/08 11:15:19 + [bufaux.c bufbn.c buffer.c sftp-client.c sftp-common.c sftp-glob.c] + [uidswap.c] Include stdlib.h for free() as per the man page. + +commit b6a75b0b93b8faa6f79c3a395ab6c71f3f880b80 +Author: Darren Tucker +Date: Sun Nov 10 20:25:22 2013 +1100 + + - (dtucker) [regress/keytype.sh] Populate ECDSA key types to be tested by + querying the ones that are compiled in. + +commit 2c89430119367eb1bc96ea5ee55de83357e4c926 +Author: Darren Tucker +Date: Sun Nov 10 12:38:42 2013 +1100 + + - (dtucker) [key.c] Check for the correct defines for NID_secp521r1. + +commit dd5264db5f641dbd03186f9e5e83e4b14b3d0003 +Author: Darren Tucker +Date: Sat Nov 9 22:32:51 2013 +1100 + + - (dtucker) [configure.ac] Add missing "test". + +commit 95cb2d4eb08117be061f3ff076adef3e9a5372c3 +Author: Darren Tucker +Date: Sat Nov 9 22:02:31 2013 +1100 + + - (dtucker) [configure.ac] Fix brackets in NID_secp521r1 test. + +commit 37bcef51b3d9d496caecea6394814d2f49a1357f +Author: Darren Tucker +Date: Sat Nov 9 18:39:25 2013 +1100 + + - (dtucker) [configure.ac kex.c key.c myproposal.h] Test for the presence of + NID_X9_62_prime256v1, NID_secp384r1 and NID_secp521r1 and test that the + latter actually works before using it. Fedora (at least) has NID_secp521r1 + that doesn't work (see https://bugzilla.redhat.com/show_bug.cgi?id=1021897). + +commit 6e2fe81f926d995bae4be4a6b5b3c88c1c525187 +Author: Darren Tucker +Date: Sat Nov 9 16:55:03 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/11/09 05:41:34 + [regress/test-exec.sh regress/rekey.sh] + Use smaller test data files to speed up tests. Grow test datafiles + where necessary for a specific test. + +commit aff7ef1bb8b7c1eeb1f4812129091c5adbf51848 +Author: Darren Tucker +Date: Sat Nov 9 00:19:22 2013 +1100 + + - (dtucker) [contrib/cygwin/ssh-host-config] Simplify host key generation: + rather than testing and generating each key, call ssh-keygen -A. + Patch from vinschen at redhat.com. + +commit 882abfd3fb3c98cfe70b4fc79224770468b570a5 +Author: Darren Tucker +Date: Sat Nov 9 00:17:41 2013 +1100 + + - (dtucker) [Makefile.in configure.ac] Set MALLOC_OPTIONS per platform + and pass in TEST_ENV. Unknown options cause stderr to get polluted + and the stderr-data test to fail. + +commit 8c333ec23bdf7da917aa20ac6803a2cdd79182c5 +Author: Darren Tucker +Date: Fri Nov 8 21:12:58 2013 +1100 + + - (dtucker) [openbsd-compat/bsd-poll.c] Add headers to prevent compile + warnings. + +commit d94240b2f6b376b6e9de187e4a0cd4b89dfc48cb +Author: Darren Tucker +Date: Fri Nov 8 21:10:04 2013 +1100 + + - (dtucker) [myproposal.h] Conditionally enable CURVE25519_SHA256. + +commit 1c8ce34909886288a3932dce770deec5449f7bb5 +Author: Darren Tucker +Date: Fri Nov 8 19:50:32 2013 +1100 + + - (dtucker) [kex.c] Only enable CURVE25519_SHA256 if we actually have + EVP_sha256. + +commit ccdb9bec46bcc88549b26a94aa0bae2b9f51031c +Author: Darren Tucker +Date: Fri Nov 8 18:54:38 2013 +1100 + + - (dtucker) [openbsd-compat/openbsd-compat.h] Add null implementation of + arc4random_stir for platforms that have arc4random but don't have + arc4random_stir (right now this is only OpenBSD -current). + +commit 3420a50169b52cc8d2775d51316f9f866c73398f +Author: Damien Miller +Date: Fri Nov 8 16:48:13 2013 +1100 + + - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] Update version numbers following release. + +commit 3ac4a234df842fd8c94d9cb0ad198e1fe84b895b +Author: Damien Miller +Date: Fri Nov 8 12:39:49 2013 +1100 + + - djm@cvs.openbsd.org 2013/11/08 01:38:11 + [version.h] + openssh-6.4 + +commit 6c81fee693038de7d4a5559043350391db2a2761 +Author: Damien Miller +Date: Fri Nov 8 12:19:55 2013 +1100 + + - djm@cvs.openbsd.org 2013/11/08 00:39:15 + [auth-options.c auth2-chall.c authfd.c channels.c cipher-3des1.c] + [clientloop.c gss-genr.c monitor_mm.c packet.c schnorr.c umac.c] + [sftp-client.c sftp-glob.c] + use calloc for all structure allocations; from markus@ + +commit 690d989008e18af3603a5e03f1276c9bad090370 +Author: Damien Miller +Date: Fri Nov 8 12:16:49 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/11/07 11:58:27 + [cipher.c cipher.h kex.c kex.h mac.c mac.h servconf.c ssh.c] + Output the effective values of Ciphers, MACs and KexAlgorithms when + the default has not been overridden. ok markus@ + +commit 08998c5fb9c7c1d248caa73b76e02ca0482e6d85 +Author: Darren Tucker +Date: Fri Nov 8 12:11:46 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/11/08 01:06:14 + [regress/rekey.sh] + Rekey less frequently during tests to speed them up + +commit 4bf7e50e533aa956366df7402c132f202e841a48 +Author: Darren Tucker +Date: Thu Nov 7 22:33:48 2013 +1100 + + - (dtucker) [Makefile.in configure.ac] Remove TEST_SSH_SHA256 environment + variable. It's no longer used now that we get the supported MACs from + ssh -Q. + +commit 6e9d6f411288374d1dee4b7debbfa90bc7e73035 +Author: Darren Tucker +Date: Thu Nov 7 15:32:37 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/11/07 04:26:56 + [regress/kextype.sh] + trailing space + +commit 74cbc22529f3e5de756e1b7677b7624efb28f62c +Author: Darren Tucker +Date: Thu Nov 7 15:26:12 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/11/07 03:55:41 + [regress/kextype.sh] + Use ssh -Q to get kex types instead of a static list. + +commit a955041c930e63405159ff7d25ef14272f36eab3 +Author: Darren Tucker +Date: Thu Nov 7 15:21:19 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/11/07 02:48:38 + [regress/integrity.sh regress/cipher-speed.sh regress/try-ciphers.sh] + Use ssh -Q instead of hardcoding lists of ciphers or MACs. + +commit 06595d639577577bc15d359e037a31eb83563269 +Author: Darren Tucker +Date: Thu Nov 7 15:08:02 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/11/07 01:12:51 + [regress/rekey.sh] + Factor out the data transfer rekey tests + +commit 651dc8b2592202dac6b16ee3b82ce5b331be7da3 +Author: Darren Tucker +Date: Thu Nov 7 15:04:44 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/11/07 00:12:05 + [regress/rekey.sh] + Test rekeying for every Cipher, MAC and KEX, plus test every KEX with + the GCM ciphers. + +commit 234557762ba1096a867ca6ebdec07efebddb5153 +Author: Darren Tucker +Date: Thu Nov 7 15:00:51 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/11/04 12:27:42 + [regress/rekey.sh] + Test rekeying with all KexAlgorithms. + +commit bbfb9b0f386aab0c3e19d11f136199ef1b9ad0ef +Author: Darren Tucker +Date: Thu Nov 7 14:56:43 2013 +1100 + + - markus@cvs.openbsd.org 2013/11/02 22:39:53 + [regress/kextype.sh] + add curve25519-sha256@libssh.org + +commit aa19548a98c0f89283ebd7354abd746ca6bc4fdf +Author: Darren Tucker +Date: Thu Nov 7 14:50:09 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/09 23:44:14 + [regress/Makefile] (ID sync only) + regression test for sftp request white/blacklisting and readonly mode. + +commit c8908aabff252f5da772d4e679479c2b7d18cac1 +Author: Damien Miller +Date: Thu Nov 7 13:38:35 2013 +1100 + + - djm@cvs.openbsd.org 2013/11/06 23:05:59 + [ssh-pkcs11.c] + from portable: s/true/true_val/ to avoid name collisions on dump platforms + RCSID sync only + +commit 49c145c5e89b9d7d48e84328d6347d5ad640b567 +Author: Damien Miller +Date: Thu Nov 7 13:35:39 2013 +1100 + + - markus@cvs.openbsd.org 2013/11/06 16:52:11 + [monitor_wrap.c] + fix rekeying for AES-GCM modes; ok deraadt + +commit 67a8800f290b39fd60e379988c700656ae3f2539 +Author: Damien Miller +Date: Thu Nov 7 13:32:51 2013 +1100 + + - markus@cvs.openbsd.org 2013/11/04 11:51:16 + [monitor.c] + fix rekeying for KEX_C25519_SHA256; noted by dtucker@ + RCSID sync only; I thought this was a merge botch and fixed it already + +commit df8b030b15fcec7baf38ec7944f309f9ca8cc9a7 +Author: Damien Miller +Date: Thu Nov 7 13:28:16 2013 +1100 + + - (djm) [configure.ac defines.h] Skip arc4random_stir() calls on platforms + that lack it but have arc4random_uniform() + +commit a6fd1d3c38a562709374a70fa76423859160aa90 +Author: Damien Miller +Date: Thu Nov 7 12:03:26 2013 +1100 + + - (djm) [regress/modpipe.c regress/rekey.sh] Never intended to commit these + +commit c98319750b0bbdd0d1794420ec97d65dd9244613 +Author: Damien Miller +Date: Thu Nov 7 12:00:23 2013 +1100 + + - (djm) [Makefile.in monitor.c] Missed chunks of curve25519 KEX diff + +commit 61c5c2319e84a58210810d39b062c8b8e3321160 +Author: Damien Miller +Date: Thu Nov 7 11:34:14 2013 +1100 + + - (djm) [ssh-pkcs11.c] Bring back "non-constant initialiser" fix (rev 1.5) + that got lost in recent merge. + +commit 094003f5454a9f5a607674b2739824a7e91835f4 +Author: Damien Miller +Date: Mon Nov 4 22:59:27 2013 +1100 + + - (djm) [kexc25519.c kexc25519c.c kexc25519s.c] Import missed files from + KEX/curve25519 change + +commit ca67a7eaf8766499ba67801d0be8cdaa550b9a50 +Author: Damien Miller +Date: Mon Nov 4 09:05:17 2013 +1100 + + - djm@cvs.openbsd.org 2013/11/03 10:37:19 + [roaming_common.c] + fix a couple of function definitions foo() -> foo(void) + (-Wold-style-definition) + +commit 0bd8f1519d51af8d4229be81e8f2f4903a1d440b +Author: Damien Miller +Date: Mon Nov 4 08:55:43 2013 +1100 + + - markus@cvs.openbsd.org 2013/11/02 22:39:19 + [ssh_config.5 sshd_config.5] + the default kex is now curve25519-sha256@libssh.org + +commit 4c3ba0767fbe4a8a2a748df4035aaf86651f6b30 +Author: Damien Miller +Date: Mon Nov 4 08:40:13 2013 +1100 + + - markus@cvs.openbsd.org 2013/11/02 22:34:01 + [auth-options.c] + no need to include monitor_wrap.h and ssh-gss.h + +commit 660621b2106b987b874c2f120218bec249d0f6ba +Author: Damien Miller +Date: Mon Nov 4 08:37:51 2013 +1100 + + - markus@cvs.openbsd.org 2013/11/02 22:24:24 + [kexdhs.c kexecdhs.c] + no need to include ssh-gss.h + +commit abdca986decfbbc008c895195b85e879ed460ada +Author: Damien Miller +Date: Mon Nov 4 08:30:05 2013 +1100 + + - markus@cvs.openbsd.org 2013/11/02 22:10:15 + [kexdhs.c kexecdhs.c] + no need to include monitor_wrap.h + +commit 1e1242604eb0fd510fe93f81245c529237ffc513 +Author: Damien Miller +Date: Mon Nov 4 08:26:52 2013 +1100 + + - markus@cvs.openbsd.org 2013/11/02 21:59:15 + [kex.c kex.h myproposal.h ssh-keyscan.c sshconnect2.c sshd.c] + use curve25519 for default key exchange (curve25519-sha256@libssh.org); + initial patch from Aris Adamantiadis; ok djm@ + +commit d2252c79191d069372ed6effce7c7a2de93448cd +Author: Damien Miller +Date: Mon Nov 4 07:41:48 2013 +1100 + + - markus@cvs.openbsd.org 2013/11/02 20:03:54 + [ssh-pkcs11.c] + support pkcs#11 tokes that only provide x509 zerts instead of raw pubkeys; + fixes bz#1908; based on patch from Laurent Barbe; ok djm + +commit 007e3b357e880caa974d5adf9669298ba0751c78 +Author: Darren Tucker +Date: Sun Nov 3 18:43:55 2013 +1100 + + - (dtucker) [configure.ac defines.h] Add typedefs for intmax_t and uintmax_t + for platforms that don't have them. + +commit 710f3747352fb93a63e5b69b12379da37f5b3fa9 +Author: Darren Tucker +Date: Sun Nov 3 17:20:34 2013 +1100 + + - (dtucker) [openbsd-compat/setproctitle.c] Handle error case form the 2nd + vsnprintf. From eric at openbsd via chl@. + +commit d52770452308e5c2e99f4da6edaaa77ef078b610 +Author: Darren Tucker +Date: Sun Nov 3 16:30:46 2013 +1100 + + - (dtucker) [openbsd-compat/bsd-misc.c] Include time.h for nanosleep. + From OpenSMTPD where it prevents "implicit declaration" warnings (it's + a no-op in OpenSSH). From chl at openbsd. + +commit 63857c9340d3482746a5622ffdacc756751f6448 +Author: Damien Miller +Date: Wed Oct 30 22:31:06 2013 +1100 + + - jmc@cvs.openbsd.org 2013/10/29 18:49:32 + [sshd_config.5] + pty(4), not pty(7); + +commit 5ff30c6b68adeee767dd29bf2369763c6a13c0b3 +Author: Damien Miller +Date: Wed Oct 30 22:21:50 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/29 09:48:02 + [servconf.c servconf.h session.c sshd_config sshd_config.5] + shd_config PermitTTY to disallow TTY allocation, mirroring the + longstanding no-pty authorized_keys option; + bz#2070, patch from Teran McKinney; ok markus@ + +commit 4a3a9d4bbf8048473f5cc202cd8db7164d5e6b8d +Author: Damien Miller +Date: Wed Oct 30 22:19:47 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/29 09:42:11 + [key.c key.h] + fix potential stack exhaustion caused by nested certificates; + report by Mateusz Kocielski; ok dtucker@ markus@ + +commit 28631ceaa7acd9bc500f924614431542893c6a21 +Author: Damien Miller +Date: Sat Oct 26 10:07:56 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/25 23:04:51 + [ssh.c] + fix crash when using ProxyCommand caused by previous commit - was calling + freeaddrinfo(NULL); spotted by sthen@ and Tim Ruehsen, patch by sthen@ + +commit 26506ad29350c5681815745cc90b3952a84cf118 +Author: Damien Miller +Date: Sat Oct 26 10:05:46 2013 +1100 + + - (djm) [ssh-keygen.c ssh-keysign.c sshconnect1.c sshd.c] Remove + unnecessary arc4random_stir() calls. The only ones left are to ensure + that the PRNG gets a different state after fork() for platforms that + have broken the API. + +commit bd43e8872325e9bbb3319c89da593614709f317c +Author: Tim Rice +Date: Thu Oct 24 12:22:49 2013 -0700 + + - (tim) [regress/sftp-perm.sh] We need a shell that understands "! somecmd" + +commit a90c0338083ee0e4064c4bdf61f497293a699be0 +Author: Damien Miller +Date: Thu Oct 24 21:03:17 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/24 08:19:36 + [ssh.c] + fix bug introduced in hostname canonicalisation commit: don't try to + resolve hostnames when a ProxyCommand is set unless the user has forced + canonicalisation; spotted by Iain Morgan + +commit cf31f3863425453ffcda540fbefa9df80088c8d1 +Author: Damien Miller +Date: Thu Oct 24 21:02:56 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/10/24 00:51:48 + [readconf.c servconf.c ssh_config.5 sshd_config.5] + Disallow empty Match statements and add "Match all" which matches + everything. ok djm, man page help jmc@ + +commit 4bedd4032a09ce87322ae5ea80f193f109e5c607 +Author: Damien Miller +Date: Thu Oct 24 21:02:26 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/10/24 00:49:49 + [moduli.c] + Periodically print progress and, if possible, expected time to completion + when screening moduli for DH groups. ok deraadt djm + +commit 5ecb41629860687b145be63b8877fabb6bae5eda +Author: Damien Miller +Date: Thu Oct 24 21:02:02 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/23 23:35:32 + [sshd.c] + include local address and port in "Connection from ..." message (only + shown at loglevel>=verbose) + +commit 03bf2e61ad6ac59a362a1f11b105586cb755c147 +Author: Damien Miller +Date: Thu Oct 24 21:01:26 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/10/23 05:40:58 + [servconf.c] + fix comment + +commit 8f1873191478847773906af961c8984d02a49dd6 +Author: Damien Miller +Date: Thu Oct 24 10:53:02 2013 +1100 + + - (djm) [auth-krb5.c] bz#2032 - use local username in krb5_kuserok check + rather than full client name which may be of form user@REALM; + patch from Miguel Sanders; ok dtucker@ + +commit 5b01b0dcb417eb615df77e7ce1b59319bf04342c +Author: Damien Miller +Date: Wed Oct 23 16:31:31 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/23 04:16:22 + [ssh-keygen.c] + Make code match documentation: relative-specified certificate expiry time + should be relative to current time and not the validity start time. + Reported by Petr Lautrbach; ok deraadt@ + +commit eff5cada589f25793dbe63a76aba9da39837a148 +Author: Damien Miller +Date: Wed Oct 23 16:31:10 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/23 03:05:19 + [readconf.c ssh.c] + comment + +commit 084bcd24e9fe874020e4df4e073e7408e1b17fb7 +Author: Damien Miller +Date: Wed Oct 23 16:30:51 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/23 03:03:07 + [readconf.c] + Hostname may have %h sequences that should be expanded prior to Match + evaluation; spotted by Iain Morgan + +commit 8e5a67f46916def40b2758bb7755350dd2eee843 +Author: Damien Miller +Date: Wed Oct 23 16:30:25 2013 +1100 + + - jmc@cvs.openbsd.org 2013/10/20 18:00:13 + [ssh_config.5] + tweak the "exec" description, as worded by djm; + +commit c0049bd0bca02890cd792babc594771c563f91f2 +Author: Damien Miller +Date: Wed Oct 23 16:29:59 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/20 09:51:26 + [scp.1 sftp.1] + add canonicalisation options to -o lists + +commit 8a04be795fc28514a09e55a54b2e67968f2e1b3a +Author: Damien Miller +Date: Wed Oct 23 16:29:40 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/20 06:19:28 + [readconf.c ssh_config.5] + rename "command" subclause of the recently-added "Match" keyword to + "exec"; it's shorter, clearer in intent and we might want to add the + ability to match against the command being executed at the remote end in + the future. + +commit 5c86ebdf83b636b6741db4b03569ef4a53b89a58 +Author: Damien Miller +Date: Wed Oct 23 16:29:12 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/20 04:39:28 + [ssh_config.5] + document % expansions performed by "Match command ..." + +commit 4502f88774edc56194707167443f94026d3c7cfa +Author: Damien Miller +Date: Fri Oct 18 10:17:36 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/17 22:08:04 + [sshd.c] + include remote port in bad banner message; bz#2162 + +commit 1edcbf65ebd2febeaf10a836468f35e519eed7ca +Author: Damien Miller +Date: Fri Oct 18 10:17:17 2013 +1100 + + - jmc@cvs.openbsd.org 2013/10/17 07:35:48 + [sftp.1 sftp.c] + tweak previous; + +commit a176e1823013dd8533a20235b3a5131f0626f46b +Author: Damien Miller +Date: Fri Oct 18 09:05:41 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/09 23:44:14 + [regress/Makefile regress/sftp-perm.sh] + regression test for sftp request white/blacklisting and readonly mode. + +commit e3ea09494dcfe7ba76536e95765c8328ecfc18fb +Author: Damien Miller +Date: Thu Oct 17 11:57:23 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/17 00:46:49 + [ssh.c] + rearrange check to reduce diff against -portable + (Id sync only) + +commit f29238e67471a7f1088a99c3c3dbafce76b790cf +Author: Damien Miller +Date: Thu Oct 17 11:48:52 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/17 00:30:13 + [PROTOCOL sftp-client.c sftp-client.h sftp-server.c sftp.1 sftp.c] + fsync@openssh.com protocol extension for sftp-server + client support to allow calling fsync() faster successful transfer + patch mostly by imorgan AT nas.nasa.gov; bz#1798 + "fine" markus@ "grumble OK" deraadt@ "doesn't sound bad to me" millert@ + +commit 51682faa599550a69d8120e5e2bdbdc0625ef4be +Author: Damien Miller +Date: Thu Oct 17 11:48:31 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/16 22:58:01 + [ssh.c ssh_config.5] + one I missed in previous: s/isation/ization/ + +commit 3850559be93f1a442ae9ed370e8c389889dd5f72 +Author: Damien Miller +Date: Thu Oct 17 11:48:13 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/16 22:49:39 + [readconf.c readconf.h ssh.1 ssh.c ssh_config.5] + s/canonicalise/canonicalize/ for consistency with existing spelling, + e.g. authorized_keys; pointed out by naddy@ + +commit 607af3434b75acc7199a5d99d5a9c11068c01f27 +Author: Damien Miller +Date: Thu Oct 17 11:47:51 2013 +1100 + + - jmc@cvs.openbsd.org 2013/10/16 06:42:25 + [ssh_config.5] + tweak previous; + +commit 0faf747e2f77f0f7083bcd59cbed30c4b5448444 +Author: Damien Miller +Date: Thu Oct 17 11:47:23 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/16 02:31:47 + [readconf.c readconf.h roaming_client.c ssh.1 ssh.c ssh_config.5] + [sshconnect.c sshconnect.h] + Implement client-side hostname canonicalisation to allow an explicit + search path of domain suffixes to use to convert unqualified host names + to fully-qualified ones for host key matching. + This is particularly useful for host certificates, which would otherwise + need to list unqualified names alongside fully-qualified ones (and this + causes a number of problems). + "looks fine" markus@ + +commit d77b81f856e078714ec6b0f86f61c20249b7ead4 +Author: Damien Miller +Date: Thu Oct 17 11:39:00 2013 +1100 + + - jmc@cvs.openbsd.org 2013/10/15 14:10:25 + [ssh.1 ssh_config.5] + tweak previous; + +commit dcd39f29ce3308dc74a0ff27a9056205a932ce05 +Author: Damien Miller +Date: Thu Oct 17 11:31:40 2013 +1100 + + - [ssh.c] g/c unused variable. + +commit 5359a628ce3763408da25d83271a8eddec597a0c +Author: Damien Miller +Date: Tue Oct 15 12:20:37 2013 +1100 + + - [ssh.c] g/c unused variable. + +commit 386feab0c4736b054585ee8ee372865d5cde8d69 +Author: Damien Miller +Date: Tue Oct 15 12:14:49 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/14 23:31:01 + [ssh.c] + whitespace at EOL; pointed out by markus@ + +commit e9fc72edd6c313b670558cd5219601c38a949b67 +Author: Damien Miller +Date: Tue Oct 15 12:14:12 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/14 23:28:23 + [canohost.c misc.c misc.h readconf.c sftp-server.c ssh.c] + refactor client config code a little: + add multistate option partsing to readconf.c, similar to servconf.c's + existing code. + move checking of options that accept "none" as an argument to readconf.c + add a lowercase() function and use it instead of explicit tolower() in + loops + part of a larger diff that was ok markus@ + +commit 194fd904d8597a274b93e075b2047afdf5a175d4 +Author: Damien Miller +Date: Tue Oct 15 12:13:05 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/14 22:22:05 + [readconf.c readconf.h ssh-keysign.c ssh.c ssh_config.5] + add a "Match" keyword to ssh_config that allows matching on hostname, + user and result of arbitrary commands. "nice work" markus@ + +commit 71df752de2a04f423b1cd18d961a79f4fbccbcee +Author: Damien Miller +Date: Tue Oct 15 12:12:02 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/14 21:20:52 + [session.c session.h] + Add logging of session starts in a useful format; ok markus@ feedback and + ok dtucker@ + +commit 6efab27109b82820e8d32a5d811adb7bfc354f65 +Author: Damien Miller +Date: Tue Oct 15 12:07:05 2013 +1100 + + - jmc@cvs.openbsd.org 2013/10/14 14:18:56 + [sftp-server.8 sftp-server.c] + tweak previous; + ok djm + +commit 61c7de8a94156f6d7e9718ded9be8c65bb902b66 +Author: Damien Miller +Date: Tue Oct 15 12:06:45 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/11 02:53:45 + [sftp-client.h] + obsolete comment + +commit 2f93d0556e4892208c9b072624caa8cc5ddd839d +Author: Damien Miller +Date: Tue Oct 15 12:06:27 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/11 02:52:23 + [sftp-client.c] + missed one arg reorder + +commit bda5c8445713ae592d969a5105ed1a65da22bc96 +Author: Damien Miller +Date: Tue Oct 15 12:05:58 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/11 02:45:36 + [sftp-client.c] + rename flag arguments to be more clear and consistent. + reorder some internal function arguments to make adding additional flags + easier. + no functional change + +commit 61ee4d68ca0fcc793a826fc7ec70f3b8ffd12ab6 +Author: Damien Miller +Date: Tue Oct 15 11:56:47 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/10 01:43:03 + [sshd.c] + bz#2139: fix re-exec fallback by ensuring that startup_pipe is correctly + updated; ok dtucker@ + +commit 73600e51af9ee734a19767e0c084bbbc5eb5b8da +Author: Damien Miller +Date: Tue Oct 15 11:56:25 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/10 00:53:25 + [sftp-server.c] + add -Q, -P and -p to usage() before jmc@ catches me + +commit 6eaeebf27d92f39a38c772aa3f20c2250af2dd29 +Author: Damien Miller +Date: Tue Oct 15 11:55:57 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/09 23:42:17 + [sftp-server.8 sftp-server.c] + Add ability to whitelist and/or blacklist sftp protocol requests by name. + Refactor dispatch loop and consolidate read-only mode checks. + Make global variables static, since sftp-server is linked into sshd(8). + ok dtucker@ + +commit df62d71e64d29d1054e7a53d1a801075ef70335f +Author: Darren Tucker +Date: Thu Oct 10 10:32:39 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/10/08 11:42:13 + [dh.c dh.h] + Increase the size of the Diffie-Hellman groups requested for a each + symmetric key size. New values from NIST Special Publication 800-57 with + the upper limit specified by RFC4419. Pointed out by Peter Backes, ok + djm@. + +commit e6e52f8c5dc89a6767702e65bb595aaf7bc8991c +Author: Darren Tucker +Date: Thu Oct 10 10:28:07 2013 +1100 + + - djm@cvs.openbsd.org 2013/09/19 01:26:29 + [sshconnect.c] + bz#1211: make BindAddress work with UsePrivilegedPort=yes; patch from + swp AT swp.pp.ru; ok dtucker@ + +commit 71152bc9911bc34a98810b2398dac20df3fe8de3 +Author: Darren Tucker +Date: Thu Oct 10 10:27:21 2013 +1100 + + - djm@cvs.openbsd.org 2013/09/19 01:24:46 + [channels.c] + bz#1297 - tell the client (via packet_send_debug) when their preferred + listen address has been overridden by the server's GatewayPorts; + ok dtucker@ + +commit b59aaf3c4f3f449a4b86d8528668bd979be9aa5f +Author: Darren Tucker +Date: Thu Oct 10 10:26:21 2013 +1100 + + - djm@cvs.openbsd.org 2013/09/19 00:49:12 + [sftp-client.c] + fix swapped pflag and printflag in sftp upload_dir; from Iain Morgan + +commit 5d80e4522d6238bdefe9d0c634f0e6d35a241e41 +Author: Darren Tucker +Date: Thu Oct 10 10:25:09 2013 +1100 + + - djm@cvs.openbsd.org 2013/09/19 00:24:52 + [progressmeter.c] + store the initial file offset so the progress meter doesn't freak out + when resuming sftp transfers. bz#2137; patch from Iain Morgan; ok dtucker@ + +commit ad92df7e5ed26fea85adfb3f95352d6cd8e86344 +Author: Darren Tucker +Date: Thu Oct 10 10:24:11 2013 +1100 + + - sthen@cvs.openbsd.org 2013/09/16 11:35:43 + [ssh_config] + Remove gssapi config parts from ssh_config, as was already done for + sshd_config. Req by/ok ajacoutot@ + ID SYNC ONLY for portable; kerberos/gssapi is still pretty popular + +commit 720711960b130d36dfdd3d50eb25ef482bdd000e +Author: Damien Miller +Date: Wed Oct 9 10:44:47 2013 +1100 + + - (djm) [openbsd-compat/Makefile.in openbsd-compat/arc4random.c] + [openbsd-compat/bsd-arc4random.c] Replace old RC4-based arc4random + implementation with recent OpenBSD's ChaCha-based PRNG. ok dtucker@, + tested tim@ + +commit 9159310087a218e28940a592896808b8eb76a039 +Author: Damien Miller +Date: Wed Oct 9 10:42:32 2013 +1100 + + - (djm) [openbsd-compat/arc4random.c openbsd-compat/chacha_private.h] Pull + in OpenBSD implementation of arc4random, shortly to replace the existing + bsd-arc4random.c + +commit 67f1d557a68d6fa8966a327d7b6dee3408cf0e72 +Author: Damien Miller +Date: Wed Oct 9 09:33:08 2013 +1100 + + correct incorrect years in datestamps; from des + +commit f2bf36c3eb4d969f85ec8aa342e9aecb61cc8bb1 +Author: Darren Tucker +Date: Sun Sep 22 19:02:40 2013 +1000 + + - (dtucker) [platform.c platform.h sshd.c] bz#2156: restore Linux oom_adj + setting when handling SIGHUP to maintain behaviour over retart. Patch + from Matthew Ife. + +commit e90a06ae570fd259a2f5ced873c7f17390f535a5 +Author: Darren Tucker +Date: Wed Sep 18 15:09:38 2013 +1000 + + - (dtucker) [sshd_config] Trailing whitespace; from jstjohn at purdue edu. + +commit 13840e0103946982cee2a05c40697be7e57dca41 +Author: Damien Miller +Date: Sat Sep 14 09:49:43 2013 +1000 + + - djm@cvs.openbsd.org 2013/09/13 06:54:34 + [channels.c] + avoid unaligned access in code that reused a buffer to send a + struct in_addr in a reply; simpler just use use buffer_put_int(); + from portable; spotted by and ok dtucker@ + +commit 70182522a47d283513a010338cd028cb80dac2ab +Author: Damien Miller +Date: Sat Sep 14 09:49:19 2013 +1000 + + - djm@cvs.openbsd.org 2013/09/12 01:41:12 + [clientloop.c] + fix connection crash when sending break (~B) on ControlPersist'd session; + ok dtucker@ + +commit ff9d6c2a4171ee32e8fe28fc3b86eb33bd5c845b +Author: Damien Miller +Date: Sat Sep 14 09:48:55 2013 +1000 + + - sthen@cvs.openbsd.org 2013/09/07 13:53:11 + [sshd_config] + Remove commented-out kerberos/gssapi config options from sample config, + kerberos support is currently not enabled in ssh in OpenBSD. Discussed with + various people; ok deraadt@ + ID SYNC ONLY for portable; kerberos/gssapi is still pretty popular + +commit 8bab5e7b5ff6721d926b5ebf05a3a24489889c58 +Author: Damien Miller +Date: Sat Sep 14 09:47:00 2013 +1000 + + - deraadt@cvs.openbsd.org 2013/09/02 22:00:34 + [ssh-keygen.c sshconnect1.c sshd.c] + All the instances of arc4random_stir() are bogus, since arc4random() + does this itself, inside itself, and has for a very long time.. Actually, + this was probably reducing the entropy available. + ok djm + ID SYNC ONLY for portable; we don't trust other arc4random implementations + to do this right. + +commit 61353b3208d548fab863e0e0ac5d2400ee5bb340 +Author: Damien Miller +Date: Sat Sep 14 09:45:32 2013 +1000 + + - djm@cvs.openbsd.org 2013/08/31 00:13:54 + [sftp.c] + make ^w match ksh behaviour (delete previous word instead of entire line) + +commit 660854859cad31d234edb9353fb7ca2780df8128 +Author: Damien Miller +Date: Sat Sep 14 09:45:03 2013 +1000 + + - mikeb@cvs.openbsd.org 2013/08/28 12:34:27 + [ssh-keygen.c] + improve batch processing a bit by making use of the quite flag a bit + more often and exit with a non zero code if asked to find a hostname + in a known_hosts file and it wasn't there; + originally from reyk@, ok djm + +commit 045bda5cb8acf0eb9d71c275ee1247e3154fc9e5 +Author: Damien Miller +Date: Sat Sep 14 09:44:37 2013 +1000 + + - djm@cvs.openbsd.org 2013/08/22 19:02:21 + [sshd.c] + Stir PRNG after post-accept fork. The child gets a different PRNG state + anyway via rexec and explicit privsep reseeds, but it's good to be sure. + ok markus@ + +commit ed4af412da60a084891b20412433a27966613fb8 +Author: Damien Miller +Date: Sat Sep 14 09:40:51 2013 +1000 + + add marker for 6.3p1 release at the point of the last included change + +commit 43968a8e66a0aa1afefb11665bf96f86b113f5d9 +Author: Damien Miller +Date: Wed Aug 28 14:00:54 2013 +1000 + + - (djm) [openbsd-compat/bsd-snprintf.c] #ifdef noytet for intmax_t bits + until we have configure support. + +commit 04be8b9e53f8388c94b531ebc5d1bd6e10e930d1 +Author: Damien Miller +Date: Wed Aug 28 12:49:43 2013 +1000 + + - (djm) [openbsd-compat/bsd-snprintf.c] teach our local snprintf code the + 'j' (intmax_t/uintmax_t) and 'z' (size_t/ssize_t) conversions in case we + start to use them in the future. diff --git a/crypto/external/bsd/openssh/dist/INSTALL b/crypto/external/bsd/openssh/dist/INSTALL new file mode 100644 index 000000000..cbbb2df59 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/INSTALL @@ -0,0 +1,262 @@ +1. Prerequisites +---------------- + +You will need working installations of Zlib and libcrypto (LibreSSL / +OpenSSL) + +Zlib 1.1.4 or 1.2.1.2 or greater (ealier 1.2.x versions have problems): +http://www.gzip.org/zlib/ + +libcrypto (LibreSSL or OpenSSL >= 0.9.8f) +LibreSSL http://www.libressl.org/ ; or +OpenSSL http://www.openssl.org/ + +LibreSSL/OpenSSL should be compiled as a position-independent library +(i.e. with -fPIC) otherwise OpenSSH will not be able to link with it. +If you must use a non-position-independent libcrypto, then you may need +to configure OpenSSH --without-pie. + +The remaining items are optional. + +NB. If you operating system supports /dev/random, you should configure +libcrypto (LibreSSL/OpenSSL) to use it. OpenSSH relies on libcrypto's +direct support of /dev/random, or failing that, either prngd or egd + +PRNGD: + +If your system lacks kernel-based random collection, the use of Lutz +Jaenicke's PRNGd is recommended. + +http://prngd.sourceforge.net/ + +EGD: + +If the kernel lacks /dev/random the Entropy Gathering Daemon (EGD) is +supported only if libcrypto supports it. + +http://egd.sourceforge.net/ + +PAM: + +OpenSSH can utilise Pluggable Authentication Modules (PAM) if your +system supports it. PAM is standard most Linux distributions, Solaris, +HP-UX 11, AIX >= 5.2, FreeBSD and NetBSD. + +Information about the various PAM implementations are available: + +Solaris PAM: http://www.sun.com/software/solaris/pam/ +Linux PAM: http://www.kernel.org/pub/linux/libs/pam/ +OpenPAM: http://www.openpam.org/ + +If you wish to build the GNOME passphrase requester, you will need the GNOME +libraries and headers. + +GNOME: +http://www.gnome.org/ + +Alternatively, Jim Knoble has written an excellent X11 +passphrase requester. This is maintained separately at: + +http://www.jmknoble.net/software/x11-ssh-askpass/ + +S/Key Libraries: + +If you wish to use --with-skey then you will need the library below +installed. No other S/Key library is currently known to be supported. + +http://www.sparc.spb.su/solaris/skey/ + +LibEdit: + +sftp supports command-line editing via NetBSD's libedit. If your platform +has it available natively you can use that, alternatively you might try +these multi-platform ports: + +http://www.thrysoee.dk/editline/ +http://sourceforge.net/projects/libedit/ + +LDNS: + +LDNS is a DNS BSD-licensed resolver library which supports DNSSEC. + +http://nlnetlabs.nl/projects/ldns/ + +Autoconf: + +If you modify configure.ac or configure doesn't exist (eg if you checked +the code out of CVS yourself) then you will need autoconf-2.68 to rebuild +the automatically generated files by running "autoreconf". Earlier +versions may also work but this is not guaranteed. + +http://www.gnu.org/software/autoconf/ + +Basic Security Module (BSM): + +Native BSM support is know to exist in Solaris from at least 2.5.1, +FreeBSD 6.1 and OS X. Alternatively, you may use the OpenBSM +implementation (http://www.openbsm.org). + + +2. Building / Installation +-------------------------- + +To install OpenSSH with default options: + +./configure +make +make install + +This will install the OpenSSH binaries in /usr/local/bin, configuration files +in /usr/local/etc, the server in /usr/local/sbin, etc. To specify a different +installation prefix, use the --prefix option to configure: + +./configure --prefix=/opt +make +make install + +Will install OpenSSH in /opt/{bin,etc,lib,sbin}. You can also override +specific paths, for example: + +./configure --prefix=/opt --sysconfdir=/etc/ssh +make +make install + +This will install the binaries in /opt/{bin,lib,sbin}, but will place the +configuration files in /etc/ssh. + +If you are using Privilege Separation (which is enabled by default) +then you will also need to create the user, group and directory used by +sshd for privilege separation. See README.privsep for details. + +If you are using PAM, you may need to manually install a PAM control +file as "/etc/pam.d/sshd" (or wherever your system prefers to keep +them). Note that the service name used to start PAM is __progname, +which is the basename of the path of your sshd (e.g., the service name +for /usr/sbin/osshd will be osshd). If you have renamed your sshd +executable, your PAM configuration may need to be modified. + +A generic PAM configuration is included as "contrib/sshd.pam.generic", +you may need to edit it before using it on your system. If you are +using a recent version of Red Hat Linux, the config file in +contrib/redhat/sshd.pam should be more useful. Failure to install a +valid PAM file may result in an inability to use password +authentication. On HP-UX 11 and Solaris, the standard /etc/pam.conf +configuration will work with sshd (sshd will match the other service +name). + +There are a few other options to the configure script: + +--with-audit=[module] enable additional auditing via the specified module. +Currently, drivers for "debug" (additional info via syslog) and "bsm" +(Sun's Basic Security Module) are supported. + +--with-pam enables PAM support. If PAM support is compiled in, it must +also be enabled in sshd_config (refer to the UsePAM directive). + +--with-prngd-socket=/some/file allows you to enable EGD or PRNGD +support and to specify a PRNGd socket. Use this if your Unix lacks +/dev/random and you don't want to use OpenSSH's builtin entropy +collection support. + +--with-prngd-port=portnum allows you to enable EGD or PRNGD support +and to specify a EGD localhost TCP port. Use this if your Unix lacks +/dev/random and you don't want to use OpenSSH's builtin entropy +collection support. + +--with-lastlog=FILE will specify the location of the lastlog file. +./configure searches a few locations for lastlog, but may not find +it if lastlog is installed in a different place. + +--without-lastlog will disable lastlog support entirely. + +--with-osfsia, --without-osfsia will enable or disable OSF1's Security +Integration Architecture. The default for OSF1 machines is enable. + +--with-skey=PATH will enable S/Key one time password support. You will +need the S/Key libraries and header files installed for this to work. + +--with-md5-passwords will enable the use of MD5 passwords. Enable this +if your operating system uses MD5 passwords and the system crypt() does +not support them directly (see the crypt(3/3c) man page). If enabled, the +resulting binary will support both MD5 and traditional crypt passwords. + +--with-utmpx enables utmpx support. utmpx support is automatic for +some platforms. + +--without-shadow disables shadow password support. + +--with-ipaddr-display forces the use of a numeric IP address in the +$DISPLAY environment variable. Some broken systems need this. + +--with-default-path=PATH allows you to specify a default $PATH for sessions +started by sshd. This replaces the standard path entirely. + +--with-pid-dir=PATH specifies the directory in which the sshd.pid file is +created. + +--with-xauth=PATH specifies the location of the xauth binary + +--with-ssl-dir=DIR allows you to specify where your Libre/OpenSSL +libraries +are installed. + +--with-ssl-engine enables Libre/OpenSSL's (hardware) ENGINE support + +--with-4in6 Check for IPv4 in IPv6 mapped addresses and convert them to +real (AF_INET) IPv4 addresses. Works around some quirks on Linux. + +If you need to pass special options to the compiler or linker, you +can specify these as environment variables before running ./configure. +For example: + +CFLAGS="-O -m486" LDFLAGS="-s" LIBS="-lrubbish" LD="/usr/foo/ld" ./configure + +3. Configuration +---------------- + +The runtime configuration files are installed by in ${prefix}/etc or +whatever you specified as your --sysconfdir (/usr/local/etc by default). + +The default configuration should be instantly usable, though you should +review it to ensure that it matches your security requirements. + +To generate a host key, run "make host-key". Alternately you can do so +manually using the following commands: + + ssh-keygen -t rsa1 -f /etc/ssh/ssh_host_key -N "" + ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" + ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N "" + +Replacing /etc/ssh with the correct path to the configuration directory. +(${prefix}/etc or whatever you specified with --sysconfdir during +configuration) + +If you have configured OpenSSH with EGD support, ensure that EGD is +running and has collected some Entropy. + +For more information on configuration, please refer to the manual pages +for sshd, ssh and ssh-agent. + +4. (Optional) Send survey +------------------------- + +$ make survey +[check the contents of the file "survey" to ensure there's no information +that you consider sensitive] +$ make send-survey + +This will send configuration information for the currently configured +host to a survey address. This will help determine which configurations +are actually in use, and what valid combinations of configure options +exist. The raw data is available only to the OpenSSH developers, however +summary data may be published. + +5. Problems? +------------ + +If you experience problems compiling, installing or running OpenSSH. +Please refer to the "reporting bugs" section of the webpage at +http://www.openssh.com/ + + +$Id: INSTALL,v 1.91 2014/09/09 02:23:11 dtucker Exp $ diff --git a/crypto/external/bsd/openssh/dist/README.dns b/crypto/external/bsd/openssh/dist/README.dns new file mode 100644 index 000000000..97879183e --- /dev/null +++ b/crypto/external/bsd/openssh/dist/README.dns @@ -0,0 +1,47 @@ +How to verify host keys using OpenSSH and DNS +--------------------------------------------- + +OpenSSH contains support for verifying host keys using DNS as described in +draft-ietf-secsh-dns-05.txt. The document contains very brief instructions +on how to use this feature. Configuring DNS is out of the scope of this +document. + + +(1) Server: Generate and publish the DNS RR + +To create a DNS resource record (RR) containing a fingerprint of the +public host key, use the following command: + + ssh-keygen -r hostname -f keyfile -g + +where "hostname" is your fully qualified hostname and "keyfile" is the +file containing the public host key file. If you have multiple keys, +you should generate one RR for each key. + +In the example above, ssh-keygen will print the fingerprint in a +generic DNS RR format parsable by most modern name server +implementations. If your nameserver has support for the SSHFP RR +you can omit the -g flag and ssh-keygen will print a standard SSHFP RR. + +To publish the fingerprint using the DNS you must add the generated RR +to your DNS zone file and sign your zone. + + +(2) Client: Enable ssh to verify host keys using DNS + +To enable the ssh client to verify host keys using DNS, you have to +add the following option to the ssh configuration file +($HOME/.ssh/config or /etc/ssh/ssh_config): + + VerifyHostKeyDNS yes + +Upon connection the client will try to look up the fingerprint RR +using DNS. If the fingerprint received from the DNS server matches +the remote host key, the user will be notified. + + + Jakob Schlyter + Wesley Griffin + + +$OpenBSD: README.dns,v 1.2 2003/10/14 19:43:23 jakob Exp $ diff --git a/crypto/external/bsd/openssh/dist/README.platform b/crypto/external/bsd/openssh/dist/README.platform new file mode 100644 index 000000000..d1982321e --- /dev/null +++ b/crypto/external/bsd/openssh/dist/README.platform @@ -0,0 +1,96 @@ +This file contains notes about OpenSSH on specific platforms. + +AIX +--- +As of OpenSSH 3.8p1, sshd will now honour an accounts password expiry +settings, where previously it did not. Because of this, it's possible for +sites that have used OpenSSH's sshd exclusively to have accounts which +have passwords expired longer than the inactive time (ie the "Weeks between +password EXPIRATION and LOCKOUT" setting in SMIT or the maxexpired +chuser attribute). + +Accounts in this state must have their passwords reset manually by the +administrator. As a precaution, it is recommended that the administrative +passwords be reset before upgrading from OpenSSH <3.8. + +As of OpenSSH 4.0, configure will attempt to detect if your version +and maintenance level of AIX has a working getaddrinfo, and will use it +if found. This will enable IPv6 support. If for some reason configure +gets it wrong, or if you want to build binaries to work on earlier MLs +than the build host then you can add "-DBROKEN_GETADDRINFO" to CFLAGS +to force the previous IPv4-only behaviour. + +IPv6 known to work: 5.1ML7 5.2ML2 5.2ML5 +IPv6 known broken: 4.3.3ML11 5.1ML4 + +If you wish to use dynamic libraries that aren't in the normal system +locations (eg IBM's OpenSSL and zlib packages) then you will need to +define the environment variable blibpath before running configure, eg + +blibpath=/lib:/usr/lib:/opt/freeware/lib ./configure \ + --with-ssl-dir=/opt/freeware --with-zlib=/opt/freeware + +If sshd is built with the WITH_AIXAUTHENTICATE option (which is enabled +by default) then sshd checks that users are permitted via the +loginrestrictions() function, in particular that the user has the +"rlogin" attribute set. This check is not done for the root account, +instead the PermitRootLogin setting in sshd_config is used. + + +Cygwin +------ +To build on Cygwin, OpenSSH requires the following packages: +gcc, gcc-mingw-core, mingw-runtime, binutils, make, openssl, +openssl-devel, zlib, minres, minires-devel. + + +Darwin and MacOS X +------------------ +Darwin does not provide a tun(4) driver required for OpenSSH-based +virtual private networks. The BSD manpage still exists, but the driver +has been removed in recent releases of Darwin and MacOS X. + +Nevertheless, tunnel support is known to work with Darwin 8 and +MacOS X 10.4 in Point-to-Point (Layer 3) and Ethernet (Layer 2) mode +using a third party driver. More information is available at: + http://www-user.rhrk.uni-kl.de/~nissler/tuntap/ + + +Linux +----- + +Some Linux distributions (including Red Hat/Fedora/CentOS) include +headers and library links in the -devel RPMs rather than the main +binary RPMs. If you get an error about headers, or complaining about a +missing prerequisite then you may need to install the equivalent +development packages. On Redhat based distros these may be openssl-devel, +zlib-devel and pam-devel, on Debian based distros these may be +libssl-dev, libz-dev and libpam-dev. + + +Solaris +------- +If you enable BSM auditing on Solaris, you need to update audit_event(4) +for praudit(1m) to give sensible output. The following line needs to be +added to /etc/security/audit_event: + + 32800:AUE_openssh:OpenSSH login:lo + +The BSM audit event range available for third party TCB applications is +32768 - 65535. Event number 32800 has been choosen for AUE_openssh. +There is no official registry of 3rd party event numbers, so if this +number is already in use on your system, you may change it at build time +by configure'ing --with-cflags=-DAUE_openssh=32801 then rebuilding. + + +Platforms using PAM +------------------- +As of OpenSSH 4.3p1, sshd will no longer check /etc/nologin itself when +PAM is enabled. To maintain existing behaviour, pam_nologin should be +added to sshd's session stack which will prevent users from starting shell +sessions. Alternatively, pam_nologin can be added to either the auth or +account stacks which will prevent authentication entirely, but will still +return the output from pam_nologin to the client. + + +$Id: README.platform,v 1.10 2009/08/28 23:14:48 dtucker Exp $ diff --git a/crypto/external/bsd/openssh/dist/README.privsep b/crypto/external/bsd/openssh/dist/README.privsep new file mode 100644 index 000000000..f565e72da --- /dev/null +++ b/crypto/external/bsd/openssh/dist/README.privsep @@ -0,0 +1,63 @@ +Privilege separation, or privsep, is method in OpenSSH by which +operations that require root privilege are performed by a separate +privileged monitor process. Its purpose is to prevent privilege +escalation by containing corruption to an unprivileged process. +More information is available at: + http://www.citi.umich.edu/u/provos/ssh/privsep.html + +Privilege separation is now enabled by default; see the +UsePrivilegeSeparation option in sshd_config(5). + +On systems which lack mmap or anonymous (MAP_ANON) memory mapping, +compression must be disabled in order for privilege separation to +function. + +When privsep is enabled, during the pre-authentication phase sshd will +chroot(2) to "/var/empty" and change its privileges to the "sshd" user +and its primary group. sshd is a pseudo-account that should not be +used by other daemons, and must be locked and should contain a +"nologin" or invalid shell. + +You should do something like the following to prepare the privsep +preauth environment: + + # mkdir /var/empty + # chown root:sys /var/empty + # chmod 755 /var/empty + # groupadd sshd + # useradd -g sshd -c 'sshd privsep' -d /var/empty -s /bin/false sshd + +/var/empty should not contain any files. + +configure supports the following options to change the default +privsep user and chroot directory: + + --with-privsep-path=xxx Path for privilege separation chroot + --with-privsep-user=user Specify non-privileged user for privilege separation + +Privsep requires operating system support for file descriptor passing. +Compression will be disabled on systems without a working mmap MAP_ANON. + +PAM-enabled OpenSSH is known to function with privsep on AIX, FreeBSD, +HP-UX (including Trusted Mode), Linux, NetBSD and Solaris. + +On Cygwin, Tru64 Unix, OpenServer, and Unicos only the pre-authentication +part of privsep is supported. Post-authentication privsep is disabled +automatically (so you won't see the additional process mentioned below). + +Note that for a normal interactive login with a shell, enabling privsep +will require 1 additional process per login session. + +Given the following process listing (from HP-UX): + + UID PID PPID C STIME TTY TIME COMMAND + root 1005 1 0 10:45:17 ? 0:08 /opt/openssh/sbin/sshd -u0 + root 6917 1005 0 15:19:16 ? 0:00 sshd: stevesk [priv] + stevesk 6919 6917 0 15:19:17 ? 0:03 sshd: stevesk@2 + stevesk 6921 6919 0 15:19:17 pts/2 0:00 -bash + +process 1005 is the sshd process listening for new connections. +process 6917 is the privileged monitor process, 6919 is the user owned +sshd process and 6921 is the shell process. + +$Id: README.privsep,v 1.16 2005/06/04 23:21:41 djm Exp $ diff --git a/crypto/external/bsd/openssh/dist/README.tun b/crypto/external/bsd/openssh/dist/README.tun new file mode 100644 index 000000000..5e1cb074c --- /dev/null +++ b/crypto/external/bsd/openssh/dist/README.tun @@ -0,0 +1,132 @@ +How to use OpenSSH-based virtual private networks +------------------------------------------------- + +OpenSSH contains support for VPN tunneling using the tun(4) network +tunnel pseudo-device which is available on most platforms, either for +layer 2 or 3 traffic. + +The following brief instructions on how to use this feature use +a network configuration specific to the OpenBSD operating system. + +(1) Server: Enable support for SSH tunneling + +To enable the ssh server to accept tunnel requests from the client, you +have to add the following option to the ssh server configuration file +(/etc/ssh/sshd_config): + + PermitTunnel yes + +Restart the server or send the hangup signal (SIGHUP) to let the server +reread it's configuration. + +(2) Server: Restrict client access and assign the tunnel + +The OpenSSH server simply uses the file /root/.ssh/authorized_keys to +restrict the client to connect to a specified tunnel and to +automatically start the related interface configuration command. These +settings are optional but recommended: + + tunnel="1",command="sh /etc/netstart tun1" ssh-rsa ... reyk@openbsd.org + +(3) Client: Configure the local network tunnel interface + +Use the hostname.if(5) interface-specific configuration file to set up +the network tunnel configuration with OpenBSD. For example, use the +following configuration in /etc/hostname.tun0 to set up the layer 3 +tunnel on the client: + + inet 192.168.5.1 255.255.255.252 192.168.5.2 + +OpenBSD also supports layer 2 tunneling over the tun device by adding +the link0 flag: + + inet 192.168.1.78 255.255.255.0 192.168.1.255 link0 + +Layer 2 tunnels can be used in combination with an Ethernet bridge(4) +interface, like the following example for /etc/bridgename.bridge0: + + add tun0 + add sis0 + up + +(4) Client: Configure the OpenSSH client + +To establish tunnel forwarding for connections to a specified +remote host by default, use the following ssh client configuration for +the privileged user (in /root/.ssh/config): + + Host sshgateway + Tunnel yes + TunnelDevice 0:any + PermitLocalCommand yes + LocalCommand sh /etc/netstart tun0 + +A more complicated configuration is possible to establish a tunnel to +a remote host which is not directly accessible by the client. +The following example describes a client configuration to connect to +the remote host over two ssh hops in between. It uses the OpenSSH +ProxyCommand in combination with the nc(1) program to forward the final +ssh tunnel destination over multiple ssh sessions. + + Host access.somewhere.net + User puffy + Host dmzgw + User puffy + ProxyCommand ssh access.somewhere.net nc dmzgw 22 + Host sshgateway + Tunnel Ethernet + TunnelDevice 0:any + PermitLocalCommand yes + LocalCommand sh /etc/netstart tun0 + ProxyCommand ssh dmzgw nc sshgateway 22 + +The following network plan illustrates the previous configuration in +combination with layer 2 tunneling and Ethernet bridging. + ++--------+ ( ) +----------------------+ +| Client |------( Internet )-----| access.somewhere.net | ++--------+ ( ) +----------------------+ + : 192.168.1.78 | + :............................. +-------+ + Forwarded ssh connection : | dmzgw | + Layer 2 tunnel : +-------+ + : | + : | + : +------------+ + :......| sshgateway | + | +------------+ +--- real connection Bridge -> | +----------+ +... "virtual connection" [ X ]--------| somehost | +[X] switch +----------+ + 192.168.1.25 + +(5) Client: Connect to the server and establish the tunnel + +Finally connect to the OpenSSH server to establish the tunnel by using +the following command: + + ssh sshgateway + +It is also possible to tell the client to fork into the background after +the connection has been successfully established: + + ssh -f sshgateway true + +Without the ssh configuration done in step (4), it is also possible +to use the following command lines: + + ssh -fw 0:1 sshgateway true + ifconfig tun0 192.168.5.1 192.168.5.2 netmask 255.255.255.252 + +Using OpenSSH tunnel forwarding is a simple way to establish secure +and ad hoc virtual private networks. Possible fields of application +could be wireless networks or administrative VPN tunnels. + +Nevertheless, ssh tunneling requires some packet header overhead and +runs on top of TCP. It is still suggested to use the IP Security +Protocol (IPSec) for robust and permanent VPN connections and to +interconnect corporate networks. + + Reyk Floeter + +$OpenBSD: README.tun,v 1.4 2006/03/28 00:12:31 deraadt Exp $ diff --git a/crypto/external/bsd/openssh/dist/TODO b/crypto/external/bsd/openssh/dist/TODO new file mode 100644 index 000000000..e8aaa4b96 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/TODO @@ -0,0 +1,86 @@ +Documentation: + +- Update the docs + - Update README + - Update INSTALL + - Merge INSTALL & README.privsep + +- Install FAQ? + +- General FAQ on S/Key, TIS, RSA, RSA2, DSA, etc and suggestions on when it + would be best to use them. + +- Create a Documentation/ directory? + +Programming: + +- Grep for 'XXX' comments and fix + +- Link order is incorrect for some systems using Kerberos 4 and AFS. Result + is multiple inclusion of DES symbols. Holger Trapp + reports that changing the configure + generated link order from: + -lresolv -lkrb -lz -lnsl -lutil -lkafs -lkrb -ldes -lcrypto + to: + -lresolv -lkrb -lz -lnsl -lutil -lcrypto -lkafs -lkrb -ldes + fixing the problem. + +- Write a test program that calls stat() to search for EGD/PRNGd socket + rather than use the (non-portable) "test -S". + +- More platforms for for setproctitle() emulation (testing needed) + +- Improve PAM ChallengeResponseAuthentication + - Informational messages + - Use different PAM service name for kbdint vs regular auth (suggest from + Solar Designer) + - Ability to select which ChallengeResponseAuthentications may be used + and order to try them in e.g. "ChallengeResponseAuthentication skey, pam" + +- Complete Tru64 SIA support + - It looks like we could merge it into the password auth code to cut down + on diff size. Maybe PAM password auth too? + +- Finish integrating kernel-level auditing code for IRIX and SOLARIS + (Gilbert.r.loomis@saic.com) + +- 64-bit builds on HP-UX 11.X (stevesk@pobox.com): + - utmp/wtmp get corrupted (something in loginrec?) + - can't build with PAM (no 64-bit libpam yet) + +Clean up configure/makefiles: +- Clean up configure.ac - There are a few double #defined variables + left to do. HAVE_LOGIN is one of them. Consider NOT looking for + information in wtmpx or utmpx or any of that stuff if it's not detected + from the start + +- Replace the whole u_intXX_t evilness in acconfig.h with something better??? + - Do it in configure.ac + +- Consider splitting the u_intXX_t test for sys/bitype.h into seperate test + to allow people to (right/wrongfully) link against Bind directly. + +- Consider splitting configure.ac into seperate files which do logically + similar tests. E.g move all the type detection stuff into one file, + entropy related stuff into another. + +Packaging: +- HP-UX: Provide DEPOT package scripts. + (gilbert.r.loomis@saic.com) + +PrivSep Issues: +- mmap() issues. + + /dev/zero solution (Solaris) + + No/broken MAP_ANON (Irix) + + broken /dev/zero parse (Linux) +- PAM + + See above PAM notes +- AIX + + usrinfo() does not set TTY, but only required for legacy systems. Works + with PrivSep. +- OSF + + SIA is broken +- Cygwin + + Privsep for Pre-auth only (no fd passing) + +$Id: TODO,v 1.58 2004/12/06 11:40:11 dtucker Exp $ diff --git a/crypto/external/bsd/openssh/dist/audit-bsm.c b/crypto/external/bsd/openssh/dist/audit-bsm.c new file mode 100644 index 000000000..613559140 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/audit-bsm.c @@ -0,0 +1,457 @@ +/* $Id: audit-bsm.c,v 1.8 2012/02/23 23:40:43 dtucker Exp $ */ + +/* + * TODO + * + * - deal with overlap between this and sys_auth_allowed_user + * sys_auth_record_login and record_failed_login. + */ + +/* + * Copyright 1988-2002 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * 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. + * + */ +/* #pragma ident "@(#)bsmaudit.c 1.1 01/09/17 SMI" */ + +#include "includes.h" +#if defined(USE_BSM_AUDIT) + +#include + +#include +#include +#include +#include +#include + +#ifdef BROKEN_BSM_API +#include +#endif + +#include "ssh.h" +#include "log.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "xmalloc.h" + +#ifndef AUE_openssh +# define AUE_openssh 32800 +#endif +#include +#include +#include +#include +#include + +#if defined(HAVE_GETAUDIT_ADDR) +#define AuditInfoStruct auditinfo_addr +#define AuditInfoTermID au_tid_addr_t +#define SetAuditFunc(a,b) setaudit_addr((a),(b)) +#define SetAuditFuncText "setaudit_addr" +#define AUToSubjectFunc au_to_subject_ex +#define AUToReturnFunc(a,b) au_to_return32((a), (int32_t)(b)) +#else +#define AuditInfoStruct auditinfo +#define AuditInfoTermID au_tid_t +#define SetAuditFunc(a,b) setaudit(a) +#define SetAuditFuncText "setaudit" +#define AUToSubjectFunc au_to_subject +#define AUToReturnFunc(a,b) au_to_return((a), (u_int)(b)) +#endif + +#ifndef cannot_audit +extern int cannot_audit(int); +#endif +extern void aug_init(void); +extern void aug_save_auid(au_id_t); +extern void aug_save_uid(uid_t); +extern void aug_save_euid(uid_t); +extern void aug_save_gid(gid_t); +extern void aug_save_egid(gid_t); +extern void aug_save_pid(pid_t); +extern void aug_save_asid(au_asid_t); +extern void aug_save_tid(dev_t, unsigned int); +extern void aug_save_tid_ex(dev_t, u_int32_t *, u_int32_t); +extern int aug_save_me(void); +extern int aug_save_namask(void); +extern void aug_save_event(au_event_t); +extern void aug_save_sorf(int); +extern void aug_save_text(char *); +extern void aug_save_text1(char *); +extern void aug_save_text2(char *); +extern void aug_save_na(int); +extern void aug_save_user(char *); +extern void aug_save_path(char *); +extern int aug_save_policy(void); +extern void aug_save_afunc(int (*)(int)); +extern int aug_audit(void); +extern int aug_na_selected(void); +extern int aug_selected(void); +extern int aug_daemon_session(void); + +#ifndef HAVE_GETTEXT +# define gettext(a) (a) +#endif + +extern Authctxt *the_authctxt; +static AuditInfoTermID ssh_bsm_tid; + +#ifdef BROKEN_BSM_API +/* For some reason this constant is no longer defined + in Solaris 11. */ +#define BSM_TEXTBUFSZ 256 +#endif + +/* Below is the low-level BSM interface code */ + +/* + * aug_get_machine is only required on IPv6 capable machines, we use a + * different mechanism in audit_connection_from() for IPv4-only machines. + * getaudit_addr() is only present on IPv6 capable machines. + */ +#if defined(HAVE_AUG_GET_MACHINE) || !defined(HAVE_GETAUDIT_ADDR) +extern int aug_get_machine(char *, u_int32_t *, u_int32_t *); +#else +static int +aug_get_machine(char *host, u_int32_t *addr, u_int32_t *type) +{ + struct addrinfo *ai; + struct sockaddr_in *in4; + struct sockaddr_in6 *in6; + int ret = 0, r; + + if ((r = getaddrinfo(host, NULL, NULL, &ai)) != 0) { + error("BSM audit: getaddrinfo failed for %.100s: %.100s", host, + r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r)); + return -1; + } + + switch (ai->ai_family) { + case AF_INET: + in4 = (struct sockaddr_in *)ai->ai_addr; + *type = AU_IPv4; + memcpy(addr, &in4->sin_addr, sizeof(struct in_addr)); + break; +#ifdef AU_IPv6 + case AF_INET6: + in6 = (struct sockaddr_in6 *)ai->ai_addr; + *type = AU_IPv6; + memcpy(addr, &in6->sin6_addr, sizeof(struct in6_addr)); + break; +#endif + default: + error("BSM audit: unknown address family for %.100s: %d", + host, ai->ai_family); + ret = -1; + } + freeaddrinfo(ai); + return ret; +} +#endif + +#ifdef BROKEN_BSM_API +/* + In Solaris 11 the audit daemon has been moved to SMF. In the process + they simply dropped getacna() from the API, since it read from a now + non-existent config file. This function re-implements getacna() to + read from the SMF repository instead. + */ +int +getacna(char *auditstring, int len) +{ + scf_handle_t *handle = NULL; + scf_property_t *property = NULL; + scf_value_t *value = NULL; + int ret = 0; + + handle = scf_handle_create(SCF_VERSION); + if (handle == NULL) + return -2; /* The man page for getacna on Solaris 10 states + we should return -2 in case of error and set + errno to indicate the error. We don't bother + with errno here, though, since the only use + of this function below doesn't check for errors + anyway. + */ + + ret = scf_handle_bind(handle); + if (ret == -1) + return -2; + + property = scf_property_create(handle); + if (property == NULL) + return -2; + + ret = scf_handle_decode_fmri(handle, + "svc:/system/auditd:default/:properties/preselection/naflags", + NULL, NULL, NULL, NULL, property, 0); + if (ret == -1) + return -2; + + value = scf_value_create(handle); + if (value == NULL) + return -2; + + ret = scf_property_get_value(property, value); + if (ret == -1) + return -2; + + ret = scf_value_get_astring(value, auditstring, len); + if (ret == -1) + return -2; + + scf_value_destroy(value); + scf_property_destroy(property); + scf_handle_destroy(handle); + + return 0; +} +#endif + +/* + * Check if the specified event is selected (enabled) for auditing. + * Returns 1 if the event is selected, 0 if not and -1 on failure. + */ +static int +selected(char *username, uid_t uid, au_event_t event, int sf) +{ + int rc, sorf; + char naflags[512]; + struct au_mask mask; + + mask.am_success = mask.am_failure = 0; + if (uid < 0) { + /* get flags for non-attributable (to a real user) events */ + rc = getacna(naflags, sizeof(naflags)); + if (rc == 0) + (void) getauditflagsbin(naflags, &mask); + } else + rc = au_user_mask(username, &mask); + + sorf = (sf == 0) ? AU_PRS_SUCCESS : AU_PRS_FAILURE; + return(au_preselect(event, &mask, sorf, AU_PRS_REREAD)); +} + +static void +bsm_audit_record(int typ, char *string, au_event_t event_no) +{ + int ad, rc, sel; + uid_t uid = -1; + gid_t gid = -1; + pid_t pid = getpid(); + AuditInfoTermID tid = ssh_bsm_tid; + + if (the_authctxt != NULL && the_authctxt->valid) { + uid = the_authctxt->pw->pw_uid; + gid = the_authctxt->pw->pw_gid; + } + + rc = (typ == 0) ? 0 : -1; + sel = selected(the_authctxt->user, uid, event_no, rc); + debug3("BSM audit: typ %d rc %d \"%s\"", typ, rc, string); + if (!sel) + return; /* audit event does not match mask, do not write */ + + debug3("BSM audit: writing audit new record"); + ad = au_open(); + + (void) au_write(ad, AUToSubjectFunc(uid, uid, gid, uid, gid, + pid, pid, &tid)); + (void) au_write(ad, au_to_text(string)); + (void) au_write(ad, AUToReturnFunc(typ, rc)); + +#ifdef BROKEN_BSM_API + /* The last argument is the event modifier flags. For + some seemingly undocumented reason it was added in + Solaris 11. */ + rc = au_close(ad, AU_TO_WRITE, event_no, 0); +#else + rc = au_close(ad, AU_TO_WRITE, event_no); +#endif + + if (rc < 0) + error("BSM audit: %s failed to write \"%s\" record: %s", + __func__, string, strerror(errno)); +} + +static void +bsm_audit_session_setup(void) +{ + int rc; + struct AuditInfoStruct info; + au_mask_t mask; + + if (the_authctxt == NULL) { + error("BSM audit: session setup internal error (NULL ctxt)"); + return; + } + + if (the_authctxt->valid) + info.ai_auid = the_authctxt->pw->pw_uid; + else + info.ai_auid = -1; + info.ai_asid = getpid(); + mask.am_success = 0; + mask.am_failure = 0; + + (void) au_user_mask(the_authctxt->user, &mask); + + info.ai_mask.am_success = mask.am_success; + info.ai_mask.am_failure = mask.am_failure; + + info.ai_termid = ssh_bsm_tid; + + rc = SetAuditFunc(&info, sizeof(info)); + if (rc < 0) + error("BSM audit: %s: %s failed: %s", __func__, + SetAuditFuncText, strerror(errno)); +} + +static void +bsm_audit_bad_login(const char *what) +{ + char textbuf[BSM_TEXTBUFSZ]; + + if (the_authctxt->valid) { + (void) snprintf(textbuf, sizeof (textbuf), + gettext("invalid %s for user %s"), + what, the_authctxt->user); + bsm_audit_record(4, textbuf, AUE_openssh); + } else { + (void) snprintf(textbuf, sizeof (textbuf), + gettext("invalid user name \"%s\""), + the_authctxt->user); + bsm_audit_record(3, textbuf, AUE_openssh); + } +} + +/* Below is the sshd audit API code */ + +void +audit_connection_from(const char *host, int port) +{ + AuditInfoTermID *tid = &ssh_bsm_tid; + char buf[1024]; + + if (cannot_audit(0)) + return; + debug3("BSM audit: connection from %.100s port %d", host, port); + + /* populate our terminal id structure */ +#if defined(HAVE_GETAUDIT_ADDR) + tid->at_port = (dev_t)port; + aug_get_machine((char *)host, &(tid->at_addr[0]), &(tid->at_type)); + snprintf(buf, sizeof(buf), "%08x %08x %08x %08x", tid->at_addr[0], + tid->at_addr[1], tid->at_addr[2], tid->at_addr[3]); + debug3("BSM audit: iptype %d machine ID %s", (int)tid->at_type, buf); +#else + /* this is used on IPv4-only machines */ + tid->port = (dev_t)port; + tid->machine = inet_addr(host); + snprintf(buf, sizeof(buf), "%08x", tid->machine); + debug3("BSM audit: machine ID %s", buf); +#endif +} + +void +audit_run_command(const char *command) +{ + /* not implemented */ +} + +void +audit_session_open(struct logininfo *li) +{ + /* not implemented */ +} + +void +audit_session_close(struct logininfo *li) +{ + /* not implemented */ +} + +void +audit_event(ssh_audit_event_t event) +{ + char textbuf[BSM_TEXTBUFSZ]; + static int logged_in = 0; + const char *user = the_authctxt ? the_authctxt->user : "(unknown user)"; + + if (cannot_audit(0)) + return; + + switch(event) { + case SSH_AUTH_SUCCESS: + logged_in = 1; + bsm_audit_session_setup(); + snprintf(textbuf, sizeof(textbuf), + gettext("successful login %s"), user); + bsm_audit_record(0, textbuf, AUE_openssh); + break; + + case SSH_CONNECTION_CLOSE: + /* + * We can also get a close event if the user attempted auth + * but never succeeded. + */ + if (logged_in) { + snprintf(textbuf, sizeof(textbuf), + gettext("sshd logout %s"), the_authctxt->user); + bsm_audit_record(0, textbuf, AUE_logout); + } else { + debug("%s: connection closed without authentication", + __func__); + } + break; + + case SSH_NOLOGIN: + bsm_audit_record(1, + gettext("logins disabled by /etc/nologin"), AUE_openssh); + break; + + case SSH_LOGIN_EXCEED_MAXTRIES: + snprintf(textbuf, sizeof(textbuf), + gettext("too many tries for user %s"), the_authctxt->user); + bsm_audit_record(1, textbuf, AUE_openssh); + break; + + case SSH_LOGIN_ROOT_DENIED: + bsm_audit_record(2, gettext("not_console"), AUE_openssh); + break; + + case SSH_AUTH_FAIL_PASSWD: + bsm_audit_bad_login("password"); + break; + + case SSH_AUTH_FAIL_KBDINT: + bsm_audit_bad_login("interactive password entry"); + break; + + default: + debug("%s: unhandled event %d", __func__, event); + } +} +#endif /* BSM */ diff --git a/crypto/external/bsd/openssh/dist/audit-linux.c b/crypto/external/bsd/openssh/dist/audit-linux.c new file mode 100644 index 000000000..b3ee2f4da --- /dev/null +++ b/crypto/external/bsd/openssh/dist/audit-linux.c @@ -0,0 +1,126 @@ +/* $Id: audit-linux.c,v 1.1 2011/01/17 10:15:30 dtucker Exp $ */ + +/* + * Copyright 2010 Red Hat, Inc. All rights reserved. + * Use is subject to license terms. + * + * 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. + * + * Red Hat author: Jan F. Chadima + */ + +#include "includes.h" +#if defined(USE_LINUX_AUDIT) +#include +#include +#include + +#include "log.h" +#include "audit.h" +#include "canohost.h" + +const char* audit_username(void); + +int +linux_audit_record_event(int uid, const char *username, + const char *hostname, const char *ip, const char *ttyn, int success) +{ + int audit_fd, rc, saved_errno; + + audit_fd = audit_open(); + if (audit_fd < 0) { + if (errno == EINVAL || errno == EPROTONOSUPPORT || + errno == EAFNOSUPPORT) + return 1; /* No audit support in kernel */ + else + return 0; /* Must prevent login */ + } + rc = audit_log_acct_message(audit_fd, AUDIT_USER_LOGIN, + NULL, "login", username ? username : "(unknown)", + username == NULL ? uid : -1, hostname, ip, ttyn, success); + saved_errno = errno; + close(audit_fd); + /* + * Do not report error if the error is EPERM and sshd is run as non + * root user. + */ + if ((rc == -EPERM) && (geteuid() != 0)) + rc = 0; + errno = saved_errno; + return (rc >= 0); +} + +/* Below is the sshd audit API code */ + +void +audit_connection_from(const char *host, int port) +{ +} + /* not implemented */ + +void +audit_run_command(const char *command) +{ + /* not implemented */ +} + +void +audit_session_open(struct logininfo *li) +{ + if (linux_audit_record_event(li->uid, NULL, li->hostname, + NULL, li->line, 1) == 0) + fatal("linux_audit_write_entry failed: %s", strerror(errno)); +} + +void +audit_session_close(struct logininfo *li) +{ + /* not implemented */ +} + +void +audit_event(ssh_audit_event_t event) +{ + switch(event) { + case SSH_AUTH_SUCCESS: + case SSH_CONNECTION_CLOSE: + case SSH_NOLOGIN: + case SSH_LOGIN_EXCEED_MAXTRIES: + case SSH_LOGIN_ROOT_DENIED: + break; + + case SSH_AUTH_FAIL_NONE: + case SSH_AUTH_FAIL_PASSWD: + case SSH_AUTH_FAIL_KBDINT: + case SSH_AUTH_FAIL_PUBKEY: + case SSH_AUTH_FAIL_HOSTBASED: + case SSH_AUTH_FAIL_GSSAPI: + case SSH_INVALID_USER: + linux_audit_record_event(-1, audit_username(), NULL, + get_remote_ipaddr(), "sshd", 0); + break; + + default: + debug("%s: unhandled event %d", __func__, event); + } +} + +#endif /* USE_LINUX_AUDIT */ diff --git a/crypto/external/bsd/openssh/dist/audit.c b/crypto/external/bsd/openssh/dist/audit.c new file mode 100644 index 000000000..ced57fa64 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/audit.c @@ -0,0 +1,186 @@ +/* $Id: audit.c,v 1.6 2011/01/17 10:15:30 dtucker Exp $ */ + +/* + * Copyright (c) 2004, 2005 Darren Tucker. 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" + +#include +#include + +#ifdef SSH_AUDIT_EVENTS + +#include "audit.h" +#include "log.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" + +/* + * Care must be taken when using this since it WILL NOT be initialized when + * audit_connection_from() is called and MAY NOT be initialized when + * audit_event(CONNECTION_ABANDON) is called. Test for NULL before using. + */ +extern Authctxt *the_authctxt; + +/* Maybe add the audit class to struct Authmethod? */ +ssh_audit_event_t +audit_classify_auth(const char *method) +{ + if (strcmp(method, "none") == 0) + return SSH_AUTH_FAIL_NONE; + else if (strcmp(method, "password") == 0) + return SSH_AUTH_FAIL_PASSWD; + else if (strcmp(method, "publickey") == 0 || + strcmp(method, "rsa") == 0) + return SSH_AUTH_FAIL_PUBKEY; + else if (strncmp(method, "keyboard-interactive", 20) == 0 || + strcmp(method, "challenge-response") == 0) + return SSH_AUTH_FAIL_KBDINT; + else if (strcmp(method, "hostbased") == 0 || + strcmp(method, "rhosts-rsa") == 0) + return SSH_AUTH_FAIL_HOSTBASED; + else if (strcmp(method, "gssapi-with-mic") == 0) + return SSH_AUTH_FAIL_GSSAPI; + else + return SSH_AUDIT_UNKNOWN; +} + +/* helper to return supplied username */ +const char * +audit_username(void) +{ + static const char unknownuser[] = "(unknown user)"; + static const char invaliduser[] = "(invalid user)"; + + if (the_authctxt == NULL || the_authctxt->user == NULL) + return (unknownuser); + if (!the_authctxt->valid) + return (invaliduser); + return (the_authctxt->user); +} + +const char * +audit_event_lookup(ssh_audit_event_t ev) +{ + int i; + static struct event_lookup_struct { + ssh_audit_event_t event; + const char *name; + } event_lookup[] = { + {SSH_LOGIN_EXCEED_MAXTRIES, "LOGIN_EXCEED_MAXTRIES"}, + {SSH_LOGIN_ROOT_DENIED, "LOGIN_ROOT_DENIED"}, + {SSH_AUTH_SUCCESS, "AUTH_SUCCESS"}, + {SSH_AUTH_FAIL_NONE, "AUTH_FAIL_NONE"}, + {SSH_AUTH_FAIL_PASSWD, "AUTH_FAIL_PASSWD"}, + {SSH_AUTH_FAIL_KBDINT, "AUTH_FAIL_KBDINT"}, + {SSH_AUTH_FAIL_PUBKEY, "AUTH_FAIL_PUBKEY"}, + {SSH_AUTH_FAIL_HOSTBASED, "AUTH_FAIL_HOSTBASED"}, + {SSH_AUTH_FAIL_GSSAPI, "AUTH_FAIL_GSSAPI"}, + {SSH_INVALID_USER, "INVALID_USER"}, + {SSH_NOLOGIN, "NOLOGIN"}, + {SSH_CONNECTION_CLOSE, "CONNECTION_CLOSE"}, + {SSH_CONNECTION_ABANDON, "CONNECTION_ABANDON"}, + {SSH_AUDIT_UNKNOWN, "AUDIT_UNKNOWN"} + }; + + for (i = 0; event_lookup[i].event != SSH_AUDIT_UNKNOWN; i++) + if (event_lookup[i].event == ev) + break; + return(event_lookup[i].name); +} + +# ifndef CUSTOM_SSH_AUDIT_EVENTS +/* + * Null implementations of audit functions. + * These get used if SSH_AUDIT_EVENTS is defined but no audit module is enabled. + */ + +/* + * Called after a connection has been accepted but before any authentication + * has been attempted. + */ +void +audit_connection_from(const char *host, int port) +{ + debug("audit connection from %s port %d euid %d", host, port, + (int)geteuid()); +} + +/* + * Called when various events occur (see audit.h for a list of possible + * events and what they mean). + */ +void +audit_event(ssh_audit_event_t event) +{ + debug("audit event euid %d user %s event %d (%s)", geteuid(), + audit_username(), event, audit_event_lookup(event)); +} + +/* + * Called when a user session is started. Argument is the tty allocated to + * the session, or NULL if no tty was allocated. + * + * Note that this may be called multiple times if multiple sessions are used + * within a single connection. + */ +void +audit_session_open(struct logininfo *li) +{ + const char *t = li->line ? li->line : "(no tty)"; + + debug("audit session open euid %d user %s tty name %s", geteuid(), + audit_username(), t); +} + +/* + * Called when a user session is closed. Argument is the tty allocated to + * the session, or NULL if no tty was allocated. + * + * Note that this may be called multiple times if multiple sessions are used + * within a single connection. + */ +void +audit_session_close(struct logininfo *li) +{ + const char *t = li->line ? li->line : "(no tty)"; + + debug("audit session close euid %d user %s tty name %s", geteuid(), + audit_username(), t); +} + +/* + * This will be called when a user runs a non-interactive command. Note that + * it may be called multiple times for a single connection since SSH2 allows + * multiple sessions within a single connection. + */ +void +audit_run_command(const char *command) +{ + debug("audit run command euid %d user %s command '%.200s'", geteuid(), + audit_username(), command); +} +# endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ +#endif /* SSH_AUDIT_EVENTS */ diff --git a/crypto/external/bsd/openssh/dist/audit.h b/crypto/external/bsd/openssh/dist/audit.h new file mode 100644 index 000000000..92ede5bc4 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/audit.h @@ -0,0 +1,57 @@ +/* $Id: audit.h,v 1.4 2011/01/17 10:15:30 dtucker Exp $ */ + +/* + * Copyright (c) 2004, 2005 Darren Tucker. 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. + */ + +#ifndef _SSH_AUDIT_H +# define _SSH_AUDIT_H + +#include "loginrec.h" + +enum ssh_audit_event_type { + SSH_LOGIN_EXCEED_MAXTRIES, + SSH_LOGIN_ROOT_DENIED, + SSH_AUTH_SUCCESS, + SSH_AUTH_FAIL_NONE, + SSH_AUTH_FAIL_PASSWD, + SSH_AUTH_FAIL_KBDINT, /* keyboard-interactive or challenge-response */ + SSH_AUTH_FAIL_PUBKEY, /* ssh2 pubkey or ssh1 rsa */ + SSH_AUTH_FAIL_HOSTBASED, /* ssh2 hostbased or ssh1 rhostsrsa */ + SSH_AUTH_FAIL_GSSAPI, + SSH_INVALID_USER, + SSH_NOLOGIN, /* denied by /etc/nologin, not implemented */ + SSH_CONNECTION_CLOSE, /* closed after attempting auth or session */ + SSH_CONNECTION_ABANDON, /* closed without completing auth */ + SSH_AUDIT_UNKNOWN +}; +typedef enum ssh_audit_event_type ssh_audit_event_t; + +void audit_connection_from(const char *, int); +void audit_event(ssh_audit_event_t); +void audit_session_open(struct logininfo *); +void audit_session_close(struct logininfo *); +void audit_run_command(const char *); +ssh_audit_event_t audit_classify_auth(const char *); + +#endif /* _SSH_AUDIT_H */ diff --git a/crypto/external/bsd/openssh/dist/auth-shadow.c b/crypto/external/bsd/openssh/dist/auth-shadow.c new file mode 100644 index 000000000..219091677 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/auth-shadow.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2004 Darren Tucker. 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" + +#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE) +#include +#include +#include +#include + +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "buffer.h" +#include "log.h" + +#ifdef DAY +# undef DAY +#endif +#define DAY (24L * 60 * 60) /* 1 day in seconds */ + +extern Buffer loginmsg; + +/* + * For the account and password expiration functions, we assume the expiry + * occurs the day after the day specified. + */ + +/* + * Check if specified account is expired. Returns 1 if account is expired, + * 0 otherwise. + */ +int +auth_shadow_acctexpired(struct spwd *spw) +{ + time_t today; + int daysleft; + char buf[256]; + + today = time(NULL) / DAY; + daysleft = spw->sp_expire - today; + debug3("%s: today %d sp_expire %d days left %d", __func__, (int)today, + (int)spw->sp_expire, daysleft); + + if (spw->sp_expire == -1) { + debug3("account expiration disabled"); + } else if (daysleft < 0) { + logit("Account %.100s has expired", spw->sp_namp); + return 1; + } else if (daysleft <= spw->sp_warn) { + debug3("account will expire in %d days", daysleft); + snprintf(buf, sizeof(buf), + "Your account will expire in %d day%s.\n", daysleft, + daysleft == 1 ? "" : "s"); + buffer_append(&loginmsg, buf, strlen(buf)); + } + + return 0; +} + +/* + * Checks password expiry for platforms that use shadow passwd files. + * Returns: 1 = password expired, 0 = password not expired + */ +int +auth_shadow_pwexpired(Authctxt *ctxt) +{ + struct spwd *spw = NULL; + const char *user = ctxt->pw->pw_name; + char buf[256]; + time_t today; + int daysleft, disabled = 0; + + if ((spw = getspnam((char *)user)) == NULL) { + error("Could not get shadow information for %.100s", user); + return 0; + } + + today = time(NULL) / DAY; + debug3("%s: today %d sp_lstchg %d sp_max %d", __func__, (int)today, + (int)spw->sp_lstchg, (int)spw->sp_max); + +#if defined(__hpux) && !defined(HAVE_SECUREWARE) + if (iscomsec()) { + struct pr_passwd *pr; + + pr = getprpwnam((char *)user); + + /* Test for Trusted Mode expiry disabled */ + if (pr != NULL && pr->ufld.fd_min == 0 && + pr->ufld.fd_lifetime == 0 && pr->ufld.fd_expire == 0 && + pr->ufld.fd_pw_expire_warning == 0 && + pr->ufld.fd_schange != 0) + disabled = 1; + } +#endif + + /* TODO: check sp_inact */ + daysleft = spw->sp_lstchg + spw->sp_max - today; + if (disabled) { + debug3("password expiration disabled"); + } else if (spw->sp_lstchg == 0) { + logit("User %.100s password has expired (root forced)", user); + return 1; + } else if (spw->sp_max == -1) { + debug3("password expiration disabled"); + } else if (daysleft < 0) { + logit("User %.100s password has expired (password aged)", user); + return 1; + } else if (daysleft <= spw->sp_warn) { + debug3("password will expire in %d days", daysleft); + snprintf(buf, sizeof(buf), + "Your password will expire in %d day%s.\n", daysleft, + daysleft == 1 ? "" : "s"); + buffer_append(&loginmsg, buf, strlen(buf)); + } + + return 0; +} +#endif /* USE_SHADOW && HAS_SHADOW_EXPIRE */ diff --git a/crypto/external/bsd/openssh/dist/auth-sia.c b/crypto/external/bsd/openssh/dist/auth-sia.c new file mode 100644 index 000000000..a9e1c258c --- /dev/null +++ b/crypto/external/bsd/openssh/dist/auth-sia.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2002 Chris Adams. 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" + +#ifdef HAVE_OSF_SIA +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ssh.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "auth-sia.h" +#include "log.h" +#include "servconf.h" +#include "canohost.h" +#include "uidswap.h" + +extern ServerOptions options; +extern int saved_argc; +extern char **saved_argv; + +int +sys_auth_passwd(Authctxt *authctxt, const char *pass) +{ + int ret; + SIAENTITY *ent = NULL; + const char *host; + + host = get_canonical_hostname(options.use_dns); + + if (!authctxt->user || pass == NULL || pass[0] == '\0') + return (0); + + if (sia_ses_init(&ent, saved_argc, saved_argv, host, authctxt->user, + NULL, 0, NULL) != SIASUCCESS) + return (0); + + if ((ret = sia_ses_authent(NULL, pass, ent)) != SIASUCCESS) { + error("Couldn't authenticate %s from %s", + authctxt->user, host); + if (ret & SIASTOP) + sia_ses_release(&ent); + + return (0); + } + + sia_ses_release(&ent); + + return (1); +} + +void +session_setup_sia(struct passwd *pw, char *tty) +{ + SIAENTITY *ent = NULL; + const char *host; + + host = get_canonical_hostname(options.use_dns); + + if (sia_ses_init(&ent, saved_argc, saved_argv, host, pw->pw_name, + tty, 0, NULL) != SIASUCCESS) + fatal("sia_ses_init failed"); + + if (sia_make_entity_pwd(pw, ent) != SIASUCCESS) { + sia_ses_release(&ent); + fatal("sia_make_entity_pwd failed"); + } + + ent->authtype = SIA_A_NONE; + if (sia_ses_estab(sia_collect_trm, ent) != SIASUCCESS) + fatal("Couldn't establish session for %s from %s", + pw->pw_name, host); + + if (sia_ses_launch(sia_collect_trm, ent) != SIASUCCESS) + fatal("Couldn't launch session for %s from %s", + pw->pw_name, host); + + sia_ses_release(&ent); + + setuid(0); + permanently_set_uid(pw); +} + +#endif /* HAVE_OSF_SIA */ diff --git a/crypto/external/bsd/openssh/dist/auth-sia.h b/crypto/external/bsd/openssh/dist/auth-sia.h new file mode 100644 index 000000000..27cbb93f1 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/auth-sia.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2002 Chris Adams. 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" + +#ifdef HAVE_OSF_SIA + +void session_setup_sia(struct passwd *, char *); + +#endif /* HAVE_OSF_SIA */ diff --git a/crypto/external/bsd/openssh/dist/bindresvport.c b/crypto/external/bsd/openssh/dist/bindresvport.c new file mode 120000 index 000000000..97fa52656 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/bindresvport.c @@ -0,0 +1 @@ +openbsd-compat/bindresvport.c \ No newline at end of file diff --git a/crypto/external/bsd/openssh/dist/bsd-misc.c b/crypto/external/bsd/openssh/dist/bsd-misc.c new file mode 120000 index 000000000..353b22a33 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/bsd-misc.c @@ -0,0 +1 @@ +openbsd-compat/bsd-misc.c \ No newline at end of file diff --git a/crypto/external/bsd/openssh/dist/bsd-setres_id.c b/crypto/external/bsd/openssh/dist/bsd-setres_id.c new file mode 120000 index 000000000..0772787a2 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/bsd-setres_id.c @@ -0,0 +1 @@ +openbsd-compat/bsd-setres_id.c \ No newline at end of file diff --git a/crypto/external/bsd/openssh/dist/cipher-aes.c b/crypto/external/bsd/openssh/dist/cipher-aes.c new file mode 100644 index 000000000..8b1017272 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/cipher-aes.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2003 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" + +/* compatibility with old or broken OpenSSL versions */ +#include "openbsd-compat/openssl-compat.h" + +#ifdef USE_BUILTIN_RIJNDAEL +#include + +#include + +#include +#include + +#include "rijndael.h" +#include "xmalloc.h" +#include "log.h" + +#define RIJNDAEL_BLOCKSIZE 16 +struct ssh_rijndael_ctx +{ + rijndael_ctx r_ctx; + u_char r_iv[RIJNDAEL_BLOCKSIZE]; +}; + +static int +ssh_rijndael_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, + int enc) +{ + struct ssh_rijndael_ctx *c; + + if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { + c = xmalloc(sizeof(*c)); + EVP_CIPHER_CTX_set_app_data(ctx, c); + } + if (key != NULL) { + if (enc == -1) + enc = ctx->encrypt; + rijndael_set_key(&c->r_ctx, (u_char *)key, + 8*EVP_CIPHER_CTX_key_length(ctx), enc); + } + if (iv != NULL) + memcpy(c->r_iv, iv, RIJNDAEL_BLOCKSIZE); + return (1); +} + +static int +ssh_rijndael_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, + LIBCRYPTO_EVP_INL_TYPE len) +{ + struct ssh_rijndael_ctx *c; + u_char buf[RIJNDAEL_BLOCKSIZE]; + u_char *cprev, *cnow, *plain, *ivp; + int i, j, blocks = len / RIJNDAEL_BLOCKSIZE; + + if (len == 0) + return (1); + if (len % RIJNDAEL_BLOCKSIZE) + fatal("ssh_rijndael_cbc: bad len %d", len); + if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { + error("ssh_rijndael_cbc: no context"); + return (0); + } + if (ctx->encrypt) { + cnow = dest; + plain = (u_char *)src; + cprev = c->r_iv; + for (i = 0; i < blocks; i++, plain+=RIJNDAEL_BLOCKSIZE, + cnow+=RIJNDAEL_BLOCKSIZE) { + for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++) + buf[j] = plain[j] ^ cprev[j]; + rijndael_encrypt(&c->r_ctx, buf, cnow); + cprev = cnow; + } + memcpy(c->r_iv, cprev, RIJNDAEL_BLOCKSIZE); + } else { + cnow = (u_char *) (src+len-RIJNDAEL_BLOCKSIZE); + plain = dest+len-RIJNDAEL_BLOCKSIZE; + + memcpy(buf, cnow, RIJNDAEL_BLOCKSIZE); + for (i = blocks; i > 0; i--, cnow-=RIJNDAEL_BLOCKSIZE, + plain-=RIJNDAEL_BLOCKSIZE) { + rijndael_decrypt(&c->r_ctx, cnow, plain); + ivp = (i == 1) ? c->r_iv : cnow-RIJNDAEL_BLOCKSIZE; + for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++) + plain[j] ^= ivp[j]; + } + memcpy(c->r_iv, buf, RIJNDAEL_BLOCKSIZE); + } + return (1); +} + +static int +ssh_rijndael_cleanup(EVP_CIPHER_CTX *ctx) +{ + struct ssh_rijndael_ctx *c; + + if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { + memset(c, 0, sizeof(*c)); + free(c); + EVP_CIPHER_CTX_set_app_data(ctx, NULL); + } + return (1); +} + +void +ssh_rijndael_iv(EVP_CIPHER_CTX *evp, int doset, u_char * iv, u_int len) +{ + struct ssh_rijndael_ctx *c; + + if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) + fatal("ssh_rijndael_iv: no context"); + if (doset) + memcpy(c->r_iv, iv, len); + else + memcpy(iv, c->r_iv, len); +} + +const EVP_CIPHER * +evp_rijndael(void) +{ + static EVP_CIPHER rijndal_cbc; + + memset(&rijndal_cbc, 0, sizeof(EVP_CIPHER)); + rijndal_cbc.nid = NID_undef; + rijndal_cbc.block_size = RIJNDAEL_BLOCKSIZE; + rijndal_cbc.iv_len = RIJNDAEL_BLOCKSIZE; + rijndal_cbc.key_len = 16; + rijndal_cbc.init = ssh_rijndael_init; + rijndal_cbc.cleanup = ssh_rijndael_cleanup; + rijndal_cbc.do_cipher = ssh_rijndael_cbc; +#ifndef SSH_OLD_EVP + rijndal_cbc.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | + EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV; +#endif + return (&rijndal_cbc); +} +#endif /* USE_BUILTIN_RIJNDAEL */ diff --git a/crypto/external/bsd/openssh/dist/cipher-ctr.c b/crypto/external/bsd/openssh/dist/cipher-ctr.c new file mode 100644 index 000000000..32771f287 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/cipher-ctr.c @@ -0,0 +1,146 @@ +/* $OpenBSD: cipher-ctr.c,v 1.11 2010/10/01 23:05:32 djm Exp $ */ +/* + * Copyright (c) 2003 Markus Friedl + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "includes.h" + +#if defined(WITH_OPENSSL) && !defined(OPENSSL_HAVE_EVPCTR) +#include + +#include +#include + +#include + +#include "xmalloc.h" +#include "log.h" + +/* compatibility with old or broken OpenSSL versions */ +#include "openbsd-compat/openssl-compat.h" + +#ifndef USE_BUILTIN_RIJNDAEL +#include +#endif + +struct ssh_aes_ctr_ctx +{ + AES_KEY aes_ctx; + u_char aes_counter[AES_BLOCK_SIZE]; +}; + +/* + * increment counter 'ctr', + * the counter is of size 'len' bytes and stored in network-byte-order. + * (LSB at ctr[len-1], MSB at ctr[0]) + */ +static void +ssh_ctr_inc(u_char *ctr, size_t len) +{ + int i; + + for (i = len - 1; i >= 0; i--) + if (++ctr[i]) /* continue on overflow */ + return; +} + +static int +ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, + LIBCRYPTO_EVP_INL_TYPE len) +{ + struct ssh_aes_ctr_ctx *c; + size_t n = 0; + u_char buf[AES_BLOCK_SIZE]; + + if (len == 0) + return (1); + if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) + return (0); + + while ((len--) > 0) { + if (n == 0) { + AES_encrypt(c->aes_counter, buf, &c->aes_ctx); + ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE); + } + *(dest++) = *(src++) ^ buf[n]; + n = (n + 1) % AES_BLOCK_SIZE; + } + return (1); +} + +static int +ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, + int enc) +{ + struct ssh_aes_ctr_ctx *c; + + if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { + c = xmalloc(sizeof(*c)); + EVP_CIPHER_CTX_set_app_data(ctx, c); + } + if (key != NULL) + AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + &c->aes_ctx); + if (iv != NULL) + memcpy(c->aes_counter, iv, AES_BLOCK_SIZE); + return (1); +} + +static int +ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) +{ + struct ssh_aes_ctr_ctx *c; + + if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { + memset(c, 0, sizeof(*c)); + free(c); + EVP_CIPHER_CTX_set_app_data(ctx, NULL); + } + return (1); +} + +void +ssh_aes_ctr_iv(EVP_CIPHER_CTX *evp, int doset, u_char * iv, size_t len) +{ + struct ssh_aes_ctr_ctx *c; + + if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) + fatal("ssh_aes_ctr_iv: no context"); + if (doset) + memcpy(c->aes_counter, iv, len); + else + memcpy(iv, c->aes_counter, len); +} + +const EVP_CIPHER * +evp_aes_128_ctr(void) +{ + static EVP_CIPHER aes_ctr; + + memset(&aes_ctr, 0, sizeof(EVP_CIPHER)); + aes_ctr.nid = NID_undef; + aes_ctr.block_size = AES_BLOCK_SIZE; + aes_ctr.iv_len = AES_BLOCK_SIZE; + aes_ctr.key_len = 16; + aes_ctr.init = ssh_aes_ctr_init; + aes_ctr.cleanup = ssh_aes_ctr_cleanup; + aes_ctr.do_cipher = ssh_aes_ctr; +#ifndef SSH_OLD_EVP + aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | + EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV; +#endif + return (&aes_ctr); +} + +#endif /* defined(WITH_OPENSSL) && !defined(OPENSSL_HAVE_EVPCTR) */ diff --git a/crypto/external/bsd/openssh/dist/config.h b/crypto/external/bsd/openssh/dist/config.h new file mode 100644 index 000000000..8f6ba4e95 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/config.h @@ -0,0 +1,1708 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if you have a getaddrinfo that fails for the all-zeros IPv6 address + */ +/* #undef AIX_GETNAMEINFO_HACK */ + +/* Define if your AIX loginfailed() function takes 4 arguments (AIX >= 5.2) */ +/* #undef AIX_LOGINFAILED_4ARG */ + +/* System only supports IPv4 audit records */ +/* #undef AU_IPv4 */ + +/* Define if your resolver libs need this for getrrsetbyname */ +/* #undef BIND_8_COMPAT */ + +/* The system has incomplete BSM API */ +/* #undef BROKEN_BSM_API */ + +/* Define if cmsg_type is not passed correctly */ +/* #undef BROKEN_CMSG_TYPE */ + +/* getaddrinfo is broken (if present) */ +/* #undef BROKEN_GETADDRINFO */ + +/* getgroups(0,NULL) will return -1 */ +/* #undef BROKEN_GETGROUPS */ + +/* FreeBSD glob does not do what we need */ +/* #undef BROKEN_GLOB */ + +/* Define if you system's inet_ntoa is busted (e.g. Irix gcc issue) */ +/* #undef BROKEN_INET_NTOA */ + +/* ia_uinfo routines not supported by OS yet */ +/* #undef BROKEN_LIBIAF */ + +/* Ultrix mmap can't map files */ +/* #undef BROKEN_MMAP */ + +/* Define if your struct dirent expects you to allocate extra space for d_name + */ +/* #undef BROKEN_ONE_BYTE_DIRENT_D_NAME */ + +/* Can't do comparisons on readv */ +/* #undef BROKEN_READV_COMPARISON */ + +/* NetBSD read function is sometimes redirected, breaking atomicio comparisons + against it */ +/* #undef BROKEN_READ_COMPARISON */ + +/* realpath does not work with nonexistent files */ +#define BROKEN_REALPATH 1 + +/* Needed for NeXT */ +/* #undef BROKEN_SAVED_UIDS */ + +/* Define if your setregid() is broken */ +/* #undef BROKEN_SETREGID */ + +/* Define if your setresgid() is broken */ +/* #undef BROKEN_SETRESGID */ + +/* Define if your setresuid() is broken */ +/* #undef BROKEN_SETRESUID */ + +/* Define if your setreuid() is broken */ +/* #undef BROKEN_SETREUID */ + +/* LynxOS has broken setvbuf() implementation */ +/* #undef BROKEN_SETVBUF */ + +/* QNX shadow support is broken */ +/* #undef BROKEN_SHADOW_EXPIRE */ + +/* Define if your snprintf is busted */ +/* #undef BROKEN_SNPRINTF */ + +/* FreeBSD strnvis argument order is swapped compared to OpenBSD */ +/* #undef BROKEN_STRNVIS */ + +/* tcgetattr with ICANON may hang */ +/* #undef BROKEN_TCGETATTR_ICANON */ + +/* updwtmpx is broken (if present) */ +/* #undef BROKEN_UPDWTMPX */ + +/* Define if you have BSD auth support */ +/* #undef BSD_AUTH */ + +/* Define if you want to specify the path to your lastlog file */ +/* #undef CONF_LASTLOG_FILE */ + +/* Define if you want to specify the path to your utmp file */ +#define CONF_UTMP_FILE "/var/run/utmp" + +/* Define if you want to specify the path to your wtmpx file */ +/* #undef CONF_WTMPX_FILE */ + +/* Define if you want to specify the path to your wtmp file */ +/* #undef CONF_WTMP_FILE */ + +/* Define if your platform needs to skip post auth file descriptor passing */ +/* #undef DISABLE_FD_PASSING */ + +/* Define if you don't want to use lastlog */ +/* #undef DISABLE_LASTLOG */ + +/* Define if you don't want to use your system's login() call */ +/* #undef DISABLE_LOGIN */ + +/* Define if you don't want to use pututline() etc. to write [uw]tmp */ +/* #undef DISABLE_PUTUTLINE */ + +/* Define if you don't want to use pututxline() etc. to write [uw]tmpx */ +/* #undef DISABLE_PUTUTXLINE */ + +/* Define if you want to disable shadow passwords */ +/* #undef DISABLE_SHADOW */ + +/* Define if you don't want to use utmp */ +/* #undef DISABLE_UTMP */ + +/* Define if you don't want to use utmpx */ +/* #undef DISABLE_UTMPX */ + +/* Define if you don't want to use wtmp */ +#define DISABLE_WTMP 1 + +/* Define if you don't want to use wtmpx */ +#define DISABLE_WTMPX 1 + +/* Enable for PKCS#11 support */ +#define ENABLE_PKCS11 + +/* File names may not contain backslash characters */ +/* #undef FILESYSTEM_NO_BACKSLASH */ + +/* fsid_t has member val */ +/* #undef FSID_HAS_VAL */ + +/* fsid_t has member __val */ +/* #undef FSID_HAS___VAL */ + +/* Define to 1 if the `getpgrp' function requires zero arguments. */ +#define GETPGRP_VOID 1 + +/* Conflicting defs for getspnam */ +/* #undef GETSPNAM_CONFLICTING_DEFS */ + +/* Define if your system glob() function has the GLOB_ALTDIRFUNC extension */ +#define GLOB_HAS_ALTDIRFUNC 1 + +/* Define if your system glob() function has gl_matchc options in glob_t */ +#define GLOB_HAS_GL_MATCHC 1 + +/* Define if your system glob() function has gl_statv options in glob_t */ +/* #undef GLOB_HAS_GL_STATV */ + +/* Define this if you want GSSAPI support in the version 2 protocol */ +/* #undef GSSAPI */ + +/* Define if you want to use shadow password expire field */ +/* #undef HAS_SHADOW_EXPIRE */ + +/* Define if your system uses access rights style file descriptor passing */ +/* #undef HAVE_ACCRIGHTS_IN_MSGHDR */ + +/* Define if you have ut_addr in utmp.h */ +/* #undef HAVE_ADDR_IN_UTMP */ + +/* Define if you have ut_addr in utmpx.h */ +/* #undef HAVE_ADDR_IN_UTMPX */ + +/* Define if you have ut_addr_v6 in utmp.h */ +/* #undef HAVE_ADDR_V6_IN_UTMP */ + +/* Define if you have ut_addr_v6 in utmpx.h */ +/* #undef HAVE_ADDR_V6_IN_UTMPX */ + +/* Define to 1 if you have the `arc4random' function. */ +#define HAVE_ARC4RANDOM 1 + +/* Define to 1 if you have the `arc4random_buf' function. */ +#define HAVE_ARC4RANDOM_BUF 1 + +/* Define to 1 if you have the `arc4random_stir' function. */ +#define HAVE_ARC4RANDOM_STIR 1 + +/* Define to 1 if you have the `arc4random_uniform' function. */ +#define HAVE_ARC4RANDOM_UNIFORM 1 + +/* Define to 1 if you have the `asprintf' function. */ +#define HAVE_ASPRINTF 1 + +/* OpenBSD's gcc has bounded */ +/* #undef HAVE_ATTRIBUTE__BOUNDED__ */ + +/* Have attribute nonnull */ +#define HAVE_ATTRIBUTE__NONNULL__ 1 + +/* OpenBSD's gcc has sentinel */ +/* #undef HAVE_ATTRIBUTE__SENTINEL__ */ + +/* Define to 1 if you have the `aug_get_machine' function. */ +/* #undef HAVE_AUG_GET_MACHINE */ + +/* Define to 1 if you have the `b64_ntop' function. */ +/* #undef HAVE_B64_NTOP */ + +/* Define to 1 if you have the `b64_pton' function. */ +/* #undef HAVE_B64_PTON */ + +/* Define if you have the basename function. */ +#define HAVE_BASENAME 1 + +/* Define to 1 if you have the `bcopy' function. */ +#define HAVE_BCOPY 1 + +/* Define to 1 if you have the `bcrypt_pbkdf' function. */ +/* #undef HAVE_BCRYPT_PBKDF */ + +/* Define to 1 if you have the `bindresvport_sa' function. */ +/* #undef HAVE_BINDRESVPORT_SA */ + +/* Define to 1 if you have the `blf_enc' function. */ +/* #undef HAVE_BLF_ENC */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_BLF_H */ + +/* Define to 1 if you have the `Blowfish_expand0state' function. */ +/* #undef HAVE_BLOWFISH_EXPAND0STATE */ + +/* Define to 1 if you have the `Blowfish_expandstate' function. */ +/* #undef HAVE_BLOWFISH_EXPANDSTATE */ + +/* Define to 1 if you have the `Blowfish_initstate' function. */ +/* #undef HAVE_BLOWFISH_INITSTATE */ + +/* Define to 1 if you have the `Blowfish_stream2word' function. */ +/* #undef HAVE_BLOWFISH_STREAM2WORD */ + +/* Define to 1 if you have the `BN_is_prime_ex' function. */ +#define HAVE_BN_IS_PRIME_EX 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_BSD_LIBUTIL_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_BSM_AUDIT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_BSTRING_H */ + +/* Define to 1 if you have the `cap_rights_limit' function. */ +/* #undef HAVE_CAP_RIGHTS_LIMIT */ + +/* Define to 1 if you have the `clock' function. */ +#define HAVE_CLOCK 1 + +/* Have clock_gettime */ +#define HAVE_CLOCK_GETTIME 1 + +/* define if you have clock_t data type */ +#define HAVE_CLOCK_T 1 + +/* Define to 1 if you have the `closefrom' function. */ +#define HAVE_CLOSEFROM 1 + +/* Define if gai_strerror() returns const char * */ +#define HAVE_CONST_GAI_STRERROR_PROTO 1 + +/* Define if your system uses ancillary data style file descriptor passing */ +#define HAVE_CONTROL_IN_MSGHDR 1 + +/* Define to 1 if you have the `crypt' function. */ +#define HAVE_CRYPT 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_CRYPTO_SHA2_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_CRYPT_H */ + +/* Define if you are on Cygwin */ +/* #undef HAVE_CYGWIN */ + +/* Define if your libraries define daemon() */ +#define HAVE_DAEMON 1 + +/* Define to 1 if you have the declaration of `AI_NUMERICSERV', and to 0 if + you don't. */ +#define HAVE_DECL_AI_NUMERICSERV 1 + +/* Define to 1 if you have the declaration of `authenticate', and to 0 if you + don't. */ +/* #undef HAVE_DECL_AUTHENTICATE */ + +/* Define to 1 if you have the declaration of `GLOB_NOMATCH', and to 0 if you + don't. */ +#define HAVE_DECL_GLOB_NOMATCH 1 + +/* Define to 1 if you have the declaration of `GSS_C_NT_HOSTBASED_SERVICE', + and to 0 if you don't. */ +/* #undef HAVE_DECL_GSS_C_NT_HOSTBASED_SERVICE */ + +/* Define to 1 if you have the declaration of `howmany', and to 0 if you + don't. */ +#define HAVE_DECL_HOWMANY 1 + +/* Define to 1 if you have the declaration of `h_errno', and to 0 if you + don't. */ +#define HAVE_DECL_H_ERRNO 1 + +/* Define to 1 if you have the declaration of `loginfailed', and to 0 if you + don't. */ +/* #undef HAVE_DECL_LOGINFAILED */ + +/* Define to 1 if you have the declaration of `loginrestrictions', and to 0 if + you don't. */ +/* #undef HAVE_DECL_LOGINRESTRICTIONS */ + +/* Define to 1 if you have the declaration of `loginsuccess', and to 0 if you + don't. */ +/* #undef HAVE_DECL_LOGINSUCCESS */ + +/* Define to 1 if you have the declaration of `MAXSYMLINKS', and to 0 if you + don't. */ +#define HAVE_DECL_MAXSYMLINKS 1 + +/* Define to 1 if you have the declaration of `NFDBITS', and to 0 if you + don't. */ +#define HAVE_DECL_NFDBITS 1 + +/* Define to 1 if you have the declaration of `offsetof', and to 0 if you + don't. */ +#define HAVE_DECL_OFFSETOF 1 + +/* Define to 1 if you have the declaration of `O_NONBLOCK', and to 0 if you + don't. */ +#define HAVE_DECL_O_NONBLOCK 1 + +/* Define to 1 if you have the declaration of `passwdexpired', and to 0 if you + don't. */ +/* #undef HAVE_DECL_PASSWDEXPIRED */ + +/* Define to 1 if you have the declaration of `setauthdb', and to 0 if you + don't. */ +/* #undef HAVE_DECL_SETAUTHDB */ + +/* Define to 1 if you have the declaration of `SHUT_RD', and to 0 if you + don't. */ +#define HAVE_DECL_SHUT_RD 1 + +/* Define to 1 if you have the declaration of `writev', and to 0 if you don't. + */ +#define HAVE_DECL_WRITEV 1 + +/* Define to 1 if you have the declaration of `_getlong', and to 0 if you + don't. */ +#define HAVE_DECL__GETLONG 0 + +/* Define to 1 if you have the declaration of `_getshort', and to 0 if you + don't. */ +#define HAVE_DECL__GETSHORT 0 + +/* Define to 1 if you have the `DES_crypt' function. */ +#define HAVE_DES_CRYPT 1 + +/* Define if you have /dev/ptmx */ +#define HAVE_DEV_PTMX 1 + +/* Define if you have /dev/ptc */ +/* #undef HAVE_DEV_PTS_AND_PTC */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DIRENT_H 1 + +/* Define to 1 if you have the `dirfd' function. */ +/* #undef HAVE_DIRFD */ + +/* Define to 1 if you have the `dirname' function. */ +#define HAVE_DIRNAME 1 + +/* Define to 1 if you have the `DSA_generate_parameters_ex' function. */ +#define HAVE_DSA_GENERATE_PARAMETERS_EX 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ELF_H 1 + +/* Define to 1 if you have the `endgrent' function. */ +#define HAVE_ENDGRENT 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_ENDIAN_H */ + +/* Define to 1 if you have the `endutent' function. */ +#define HAVE_ENDUTENT 1 + +/* Define to 1 if you have the `endutxent' function. */ +#define HAVE_ENDUTXENT 1 + +/* Define if your system has /etc/default/login */ +/* #undef HAVE_ETC_DEFAULT_LOGIN */ + +/* Define if libcrypto has EVP_CIPHER_CTX_ctrl */ +#define HAVE_EVP_CIPHER_CTX_CTRL 1 + +/* Define to 1 if you have the `EVP_DigestFinal_ex' function. */ +#define HAVE_EVP_DIGESTFINAL_EX 1 + +/* Define to 1 if you have the `EVP_DigestInit_ex' function. */ +#define HAVE_EVP_DIGESTINIT_EX 1 + +/* Define to 1 if you have the `EVP_MD_CTX_cleanup' function. */ +#define HAVE_EVP_MD_CTX_CLEANUP 1 + +/* Define to 1 if you have the `EVP_MD_CTX_copy_ex' function. */ +#define HAVE_EVP_MD_CTX_COPY_EX 1 + +/* Define to 1 if you have the `EVP_MD_CTX_init' function. */ +#define HAVE_EVP_MD_CTX_INIT 1 + +/* Define to 1 if you have the `EVP_ripemd160' function. */ +#define HAVE_EVP_RIPEMD160 1 + +/* Define to 1 if you have the `EVP_sha256' function. */ +#define HAVE_EVP_SHA256 1 + +/* Define if you have ut_exit in utmp.h */ +/* #undef HAVE_EXIT_IN_UTMP */ + +/* Define to 1 if you have the `explicit_bzero' function. */ +/* #undef HAVE_EXPLICIT_BZERO */ + +/* Define to 1 if you have the `fchmod' function. */ +#define HAVE_FCHMOD 1 + +/* Define to 1 if you have the `fchown' function. */ +#define HAVE_FCHOWN 1 + +/* Use F_CLOSEM fcntl for closefrom */ +/* #undef HAVE_FCNTL_CLOSEM */ + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if the system has the type `fd_mask'. */ +#define HAVE_FD_MASK 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_FEATURES_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_FLOATINGPOINT_H */ + +/* Define to 1 if you have the `fmt_scaled' function. */ +/* #undef HAVE_FMT_SCALED */ + +/* Define to 1 if you have the `freeaddrinfo' function. */ +#define HAVE_FREEADDRINFO 1 + +/* Define to 1 if the system has the type `fsblkcnt_t'. */ +#define HAVE_FSBLKCNT_T 1 + +/* Define to 1 if the system has the type `fsfilcnt_t'. */ +#define HAVE_FSFILCNT_T 1 + +/* Define to 1 if you have the `fstatfs' function. */ +#define HAVE_FSTATFS 1 + +/* Define to 1 if you have the `fstatvfs' function. */ +#define HAVE_FSTATVFS 1 + +/* Define to 1 if you have the `futimes' function. */ +#define HAVE_FUTIMES 1 + +/* Define to 1 if you have the `gai_strerror' function. */ +#define HAVE_GAI_STRERROR 1 + +/* Define to 1 if you have the `getaddrinfo' function. */ +#define HAVE_GETADDRINFO 1 + +/* Define to 1 if you have the `getaudit' function. */ +/* #undef HAVE_GETAUDIT */ + +/* Define to 1 if you have the `getaudit_addr' function. */ +/* #undef HAVE_GETAUDIT_ADDR */ + +/* Define to 1 if you have the `getcwd' function. */ +#define HAVE_GETCWD 1 + +/* Define to 1 if you have the `getgrouplist' function. */ +#define HAVE_GETGROUPLIST 1 + +/* Define to 1 if you have the `getgrset' function. */ +/* #undef HAVE_GETGRSET */ + +/* Define to 1 if you have the `getlastlogxbyname' function. */ +/* #undef HAVE_GETLASTLOGXBYNAME */ + +/* Define to 1 if you have the `getluid' function. */ +/* #undef HAVE_GETLUID */ + +/* Define to 1 if you have the `getnameinfo' function. */ +#define HAVE_GETNAMEINFO 1 + +/* Define to 1 if you have the `getopt' function. */ +#define HAVE_GETOPT 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_GETOPT_H 1 + +/* Define if your getopt(3) defines and uses optreset */ +#define HAVE_GETOPT_OPTRESET 1 + +/* Define if your libraries define getpagesize() */ +#define HAVE_GETPAGESIZE 1 + +/* Define to 1 if you have the `getpeereid' function. */ +#define HAVE_GETPEEREID 1 + +/* Define to 1 if you have the `getpeerucred' function. */ +/* #undef HAVE_GETPEERUCRED */ + +/* Define to 1 if you have the `getpgid' function. */ +/* #undef HAVE_GETPGID */ + +/* Define to 1 if you have the `getpgrp' function. */ +#define HAVE_GETPGRP 1 + +/* Define to 1 if you have the `getpwanam' function. */ +/* #undef HAVE_GETPWANAM */ + +/* Define to 1 if you have the `getrlimit' function. */ +#define HAVE_GETRLIMIT 1 + +/* Define if getrrsetbyname() exists */ +/* #undef HAVE_GETRRSETBYNAME */ + +/* Define to 1 if you have the `getrusage' function. */ +/* #undef HAVE_GETRUSAGE */ + +/* Define to 1 if you have the `getseuserbyname' function. */ +/* #undef HAVE_GETSEUSERBYNAME */ + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the `getttyent' function. */ +#define HAVE_GETTTYENT 1 + +/* Define to 1 if you have the `getutent' function. */ +#define HAVE_GETUTENT 1 + +/* Define to 1 if you have the `getutid' function. */ +/* #undef HAVE_GETUTID */ + +/* Define to 1 if you have the `getutline' function. */ +/* #undef HAVE_GETUTLINE */ + +/* Define to 1 if you have the `getutxent' function. */ +#define HAVE_GETUTXENT 1 + +/* Define to 1 if you have the `getutxid' function. */ +#define HAVE_GETUTXID 1 + +/* Define to 1 if you have the `getutxline' function. */ +#define HAVE_GETUTXLINE 1 + +/* Define to 1 if you have the `getutxuser' function. */ +/* #undef HAVE_GETUTXUSER */ + +/* Define to 1 if you have the `get_default_context_with_level' function. */ +/* #undef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL */ + +/* Define to 1 if you have the `glob' function. */ +#define HAVE_GLOB 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_GLOB_H 1 + +/* Define to 1 if you have the `group_from_gid' function. */ +#define HAVE_GROUP_FROM_GID 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GSSAPI_GENERIC_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GSSAPI_GSSAPI_GENERIC_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GSSAPI_GSSAPI_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GSSAPI_GSSAPI_KRB5_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GSSAPI_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GSSAPI_KRB5_H */ + +/* Define if HEADER.ad exists in arpa/nameser.h */ +#define HAVE_HEADER_AD 1 + +/* Define to 1 if you have the `HMAC_CTX_init' function. */ +#define HAVE_HMAC_CTX_INIT 1 + +/* Define if you have ut_host in utmp.h */ +#define HAVE_HOST_IN_UTMP 1 + +/* Define if you have ut_host in utmpx.h */ +#define HAVE_HOST_IN_UTMPX 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_IAF_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_IA_H */ + +/* Define if you have ut_id in utmp.h */ +/* #undef HAVE_ID_IN_UTMP */ + +/* Define if you have ut_id in utmpx.h */ +#define HAVE_ID_IN_UTMPX 1 + +/* Define to 1 if you have the `inet_aton' function. */ +#define HAVE_INET_ATON 1 + +/* Define to 1 if you have the `inet_ntoa' function. */ +#define HAVE_INET_NTOA 1 + +/* Define to 1 if you have the `inet_ntop' function. */ +#define HAVE_INET_NTOP 1 + +/* Define to 1 if you have the `innetgr' function. */ +#define HAVE_INNETGR 1 + +/* define if you have int64_t data type */ +#define HAVE_INT64_T 1 + +/* Define to 1 if the system has the type `intmax_t'. */ +#define HAVE_INTMAX_T 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* define if you have intxx_t data type */ +#define HAVE_INTXX_T 1 + +/* Define to 1 if the system has the type `in_addr_t'. */ +#define HAVE_IN_ADDR_T 1 + +/* Define to 1 if the system has the type `in_port_t'. */ +#define HAVE_IN_PORT_T 1 + +/* Define if you have isblank(3C). */ +#define HAVE_ISBLANK 1 + +/* Define to 1 if you have the `krb5_cc_new_unique' function. */ +/* #undef HAVE_KRB5_CC_NEW_UNIQUE */ + +/* Define to 1 if you have the `krb5_free_error_message' function. */ +/* #undef HAVE_KRB5_FREE_ERROR_MESSAGE */ + +/* Define to 1 if you have the `krb5_get_error_message' function. */ +/* #undef HAVE_KRB5_GET_ERROR_MESSAGE */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LASTLOG_H */ + +/* Define if you want ldns support */ +/* #undef HAVE_LDNS */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LIBAUDIT_H */ + +/* Define to 1 if you have the `bsm' library (-lbsm). */ +/* #undef HAVE_LIBBSM */ + +/* Define to 1 if you have the `crypt' library (-lcrypt). */ +/* #undef HAVE_LIBCRYPT */ + +/* Define to 1 if you have the `dl' library (-ldl). */ +/* #undef HAVE_LIBDL */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LIBGEN_H 1 + +/* Define if system has libiaf that supports set_id */ +/* #undef HAVE_LIBIAF */ + +/* Define to 1 if you have the `network' library (-lnetwork). */ +/* #undef HAVE_LIBNETWORK */ + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +/* #undef HAVE_LIBNSL */ + +/* Define to 1 if you have the `pam' library (-lpam). */ +/* #undef HAVE_LIBPAM */ + +/* Define to 1 if you have the `socket' library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LIBUTIL_H 1 + +/* Define to 1 if you have the `xnet' library (-lxnet). */ +/* #undef HAVE_LIBXNET */ + +/* Define to 1 if you have the `z' library (-lz). */ +#define HAVE_LIBZ 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LINUX_AUDIT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LINUX_FILTER_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LINUX_IF_TUN_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LINUX_SECCOMP_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LOCALE_H 1 + +/* Define to 1 if you have the `login' function. */ +/* #undef HAVE_LOGIN */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LOGIN_CAP_H 1 + +/* Define to 1 if you have the `login_getcapbool' function. */ +#define HAVE_LOGIN_GETCAPBOOL 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LOGIN_H */ + +/* Define to 1 if you have the `logout' function. */ +#define HAVE_LOGOUT 1 + +/* Define to 1 if you have the `logwtmp' function. */ +#define HAVE_LOGWTMP 1 + +/* Define to 1 if the system has the type `long double'. */ +#define HAVE_LONG_DOUBLE 1 + +/* Define to 1 if the system has the type `long long'. */ +#define HAVE_LONG_LONG 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MAILLOCK_H */ + +/* Define to 1 if you have the `mblen' function. */ +#define HAVE_MBLEN 1 + +/* Define to 1 if you have the `md5_crypt' function. */ +/* #undef HAVE_MD5_CRYPT */ + +/* Define if you want to allow MD5 passwords */ +/* #undef HAVE_MD5_PASSWORDS */ + +/* Define to 1 if you have the `memmove' function. */ +#define HAVE_MEMMOVE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `memset_s' function. */ +/* #undef HAVE_MEMSET_S */ + +/* Define to 1 if you have the `mkdtemp' function. */ +#define HAVE_MKDTEMP 1 + +/* Define to 1 if you have the `mmap' function. */ +#define HAVE_MMAP 1 + +/* define if you have mode_t data type */ +#define HAVE_MODE_T 1 + +/* Some systems put nanosleep outside of libc */ +#define HAVE_NANOSLEEP 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_NDIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETGROUP_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_NET_IF_TUN_H */ + +/* Define if you are on NeXT */ +/* #undef HAVE_NEXT */ + +/* Define to 1 if you have the `ngetaddrinfo' function. */ +/* #undef HAVE_NGETADDRINFO */ + +/* Define to 1 if you have the `nsleep' function. */ +/* #undef HAVE_NSLEEP */ + +/* Define to 1 if you have the `ogetaddrinfo' function. */ +/* #undef HAVE_OGETADDRINFO */ + +/* Define if you have an old version of PAM which takes only one argument to + pam_strerror */ +/* #undef HAVE_OLD_PAM */ + +/* Define to 1 if you have the `openlog_r' function. */ +#define HAVE_OPENLOG_R 1 + +/* Define to 1 if you have the `openpty' function. */ +#define HAVE_OPENPTY 1 + +/* Define if your ssl headers are included with #include */ +#define HAVE_OPENSSL 1 + +/* Define if you have Digital Unix Security Integration Architecture */ +/* #undef HAVE_OSF_SIA */ + +/* Define to 1 if you have the `pam_getenvlist' function. */ +/* #undef HAVE_PAM_GETENVLIST */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_PAM_PAM_APPL_H */ + +/* Define to 1 if you have the `pam_putenv' function. */ +/* #undef HAVE_PAM_PUTENV */ + +/* Define to 1 if you have the header file. */ +#define HAVE_PATHS_H 1 + +/* Define if you have ut_pid in utmp.h */ +/* #undef HAVE_PID_IN_UTMP */ + +/* define if you have pid_t data type */ +#define HAVE_PID_T 1 + +/* Define to 1 if you have the `poll' function. */ +#define HAVE_POLL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_POLL_H 1 + +/* Define to 1 if you have the `prctl' function. */ +/* #undef HAVE_PRCTL */ + +/* Define if you have /proc/$pid/fd */ +/* #undef HAVE_PROC_PID */ + +/* Define to 1 if you have the `pstat' function. */ +/* #undef HAVE_PSTAT */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_PTY_H */ + +/* Define to 1 if you have the `pututline' function. */ +/* #undef HAVE_PUTUTLINE */ + +/* Define to 1 if you have the `pututxline' function. */ +#define HAVE_PUTUTXLINE 1 + +/* Define to 1 if you have the `readpassphrase' function. */ +/* #undef HAVE_READPASSPHRASE */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_READPASSPHRASE_H */ + +/* Define to 1 if you have the `reallocarray' function. */ +/*#define HAVE_REALLOCARRAY 1*/ + +/* Define to 1 if you have the `realpath' function. */ +#define HAVE_REALPATH 1 + +/* Define to 1 if you have the `recvmsg' function. */ +#define HAVE_RECVMSG 1 + +/* sys/resource.h has RLIMIT_NPROC */ +#define HAVE_RLIMIT_NPROC + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_RPC_TYPES_H */ + +/* Define to 1 if you have the `rresvport_af' function. */ +#define HAVE_RRESVPORT_AF 1 + +/* Define to 1 if you have the `RSA_generate_key_ex' function. */ +#define HAVE_RSA_GENERATE_KEY_EX 1 + +/* Define to 1 if you have the `RSA_get_default_method' function. */ +#define HAVE_RSA_GET_DEFAULT_METHOD 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SANDBOX_H */ + +/* Define to 1 if you have the `sandbox_init' function. */ +/* #undef HAVE_SANDBOX_INIT */ + +/* define if you have sa_family_t data type */ +#define HAVE_SA_FAMILY_T 1 + +/* Define to 1 if you have the `scan_scaled' function. */ +/* #undef HAVE_SCAN_SCALED */ + +/* Define if you have SecureWare-based protected password database */ +/* #undef HAVE_SECUREWARE */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SECURITY_PAM_APPL_H */ + +/* Define to 1 if you have the `sendmsg' function. */ +#define HAVE_SENDMSG 1 + +/* Define to 1 if you have the `setauthdb' function. */ +/* #undef HAVE_SETAUTHDB */ + +/* Define to 1 if you have the `setdtablesize' function. */ +/* #undef HAVE_SETDTABLESIZE */ + +/* Define to 1 if you have the `setegid' function. */ +#define HAVE_SETEGID 1 + +/* Define to 1 if you have the `setenv' function. */ +#define HAVE_SETENV 1 + +/* Define to 1 if you have the `seteuid' function. */ +#define HAVE_SETEUID 1 + +/* Define to 1 if you have the `setgroupent' function. */ +#define HAVE_SETGROUPENT 1 + +/* Define to 1 if you have the `setgroups' function. */ +#define HAVE_SETGROUPS 1 + +/* Define to 1 if you have the `setlinebuf' function. */ +#define HAVE_SETLINEBUF 1 + +/* Define to 1 if you have the `setlogin' function. */ +/* #undef HAVE_SETLOGIN */ + +/* Define to 1 if you have the `setluid' function. */ +/* #undef HAVE_SETLUID */ + +/* Define to 1 if you have the `setpassent' function. */ +#define HAVE_SETPASSENT 1 + +/* Define to 1 if you have the `setpcred' function. */ +/* #undef HAVE_SETPCRED */ + +/* Define to 1 if you have the `setproctitle' function. */ +#define HAVE_SETPROCTITLE 1 + +/* Define to 1 if you have the `setregid' function. */ +/* #undef HAVE_SETREGID */ + +/* Define to 1 if you have the `setresgid' function. */ +/* #undef HAVE_SETRESGID */ + +/* Define to 1 if you have the `setresuid' function. */ +/* #undef HAVE_SETRESUID */ + +/* Define to 1 if you have the `setreuid' function. */ +/* #undef HAVE_SETREUID */ + +/* Define to 1 if you have the `setrlimit' function. */ +#define HAVE_SETRLIMIT 1 + +/* Define to 1 if you have the `setsid' function. */ +#define HAVE_SETSID 1 + +/* Define to 1 if you have the `setutent' function. */ +#define HAVE_SETUTENT 1 + +/* Define to 1 if you have the `setutxdb' function. */ +/* #undef HAVE_SETUTXDB */ + +/* Define to 1 if you have the `setutxent' function. */ +#define HAVE_SETUTXENT 1 + +/* Define to 1 if you have the `setvbuf' function. */ +#define HAVE_SETVBUF 1 + +/* Define to 1 if you have the `set_id' function. */ +/* #undef HAVE_SET_ID */ + +/* Define to 1 if you have the `SHA256_Update' function. */ +#define HAVE_SHA256_UPDATE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SHA2_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SHADOW_H */ + +/* Define to 1 if you have the `sigaction' function. */ +#define HAVE_SIGACTION 1 + +/* Define to 1 if you have the `sigvec' function. */ +#define HAVE_SIGVEC 1 + +/* Define to 1 if the system has the type `sig_atomic_t'. */ +#define HAVE_SIG_ATOMIC_T 1 + +/* define if you have size_t data type */ +#define HAVE_SIZE_T 1 + +/* Define to 1 if you have the `snprintf' function. */ +#define HAVE_SNPRINTF 1 + +/* Define to 1 if you have the `socketpair' function. */ +#define HAVE_SOCKETPAIR 1 + +/* Have PEERCRED socket option */ +/* #undef HAVE_SO_PEERCRED */ + +/* define if you have ssize_t data type */ +#define HAVE_SSIZE_T 1 + +/* Fields in struct sockaddr_storage */ +#define HAVE_SS_FAMILY_IN_SS 1 + +/* Define to 1 if you have the `statfs' function. */ +/* #undef HAVE_STATFS */ + +/* Define to 1 if you have the `statvfs' function. */ +#define HAVE_STATVFS 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the `strerror' function. */ +#define HAVE_STRERROR 1 + +/* Define to 1 if you have the `strftime' function. */ +#define HAVE_STRFTIME 1 + +/* Silly mkstemp() */ +/* #undef HAVE_STRICT_MKSTEMP */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strlcat' function. */ +#define HAVE_STRLCAT 1 + +/* Define to 1 if you have the `strlcpy' function. */ +#define HAVE_STRLCPY 1 + +/* Define to 1 if you have the `strmode' function. */ +#define HAVE_STRMODE 1 + +/* Define to 1 if you have the `strnlen' function. */ +#define HAVE_STRNLEN 1 + +/* Define to 1 if you have the `strnvis' function. */ +#define HAVE_STRNVIS 1 + +/* Define to 1 if you have the `strptime' function. */ +#define HAVE_STRPTIME 1 + +/* Define to 1 if you have the `strsep' function. */ +#define HAVE_STRSEP 1 + +/* Define to 1 if you have the `strtoll' function. */ +#define HAVE_STRTOLL 1 + +/* Define to 1 if you have the `strtonum' function. */ +/*#define HAVE_STRTONUM 1*/ + +/* Define to 1 if you have the `strtoul' function. */ +#define HAVE_STRTOUL 1 + +/* Define to 1 if you have the `strtoull' function. */ +#define HAVE_STRTOULL 1 + +/* define if you have struct addrinfo data type */ +#define HAVE_STRUCT_ADDRINFO 1 + +/* define if you have struct in6_addr data type */ +#define HAVE_STRUCT_IN6_ADDR 1 + +/* Define to 1 if `pw_change' is member of `struct passwd'. */ +#define HAVE_STRUCT_PASSWD_PW_CHANGE 1 + +/* Define to 1 if `pw_class' is member of `struct passwd'. */ +#define HAVE_STRUCT_PASSWD_PW_CLASS 1 + +/* Define to 1 if `pw_expire' is member of `struct passwd'. */ +#define HAVE_STRUCT_PASSWD_PW_EXPIRE 1 + +/* Define to 1 if `pw_gecos' is member of `struct passwd'. */ +#define HAVE_STRUCT_PASSWD_PW_GECOS 1 + +/* define if you have struct sockaddr_in6 data type */ +#define HAVE_STRUCT_SOCKADDR_IN6 1 + +/* Define to 1 if `sin6_scope_id' is member of `struct sockaddr_in6'. */ +#define HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID 1 + +/* define if you have struct sockaddr_storage data type */ +#define HAVE_STRUCT_SOCKADDR_STORAGE 1 + +/* Define to 1 if `st_blksize' is member of `struct stat'. */ +#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 + +/* Define to 1 if the system has the type `struct timespec'. */ +#define HAVE_STRUCT_TIMESPEC 1 + +/* define if you have struct timeval */ +#define HAVE_STRUCT_TIMEVAL 1 + +/* Define to 1 if you have the `swap32' function. */ +/* #undef HAVE_SWAP32 */ + +/* Define to 1 if you have the `sysconf' function. */ +#define HAVE_SYSCONF 1 + +/* Define if you have syslen in utmpx.h */ +/* #undef HAVE_SYSLEN_IN_UTMPX */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_AUDIT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_BITYPES_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_BSDTTY_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_CAPABILITY_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_CDEFS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_DIR_H 1 + +/* Define if your system defines sys_errlist[] */ +#define HAVE_SYS_ERRLIST 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_MMAN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_MOUNT_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define if your system defines sys_nerr */ +#define HAVE_SYS_NERR 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_POLL_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_PRCTL_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_PSTAT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_PTMS_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STATVFS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_STREAM_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_STROPTS_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_STRTIO_H */ + +/* Force use of sys/syslog.h on Ultrix */ +/* #undef HAVE_SYS_SYSLOG_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SYSMACROS_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_TIMERS_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UN_H 1 + +/* Define to 1 if you have the `tcgetpgrp' function. */ +#define HAVE_TCGETPGRP 1 + +/* Define to 1 if you have the `tcsendbreak' function. */ +#define HAVE_TCSENDBREAK 1 + +/* Define to 1 if you have the `time' function. */ +#define HAVE_TIME 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_TIME_H 1 + +/* Define if you have ut_time in utmp.h */ +#define HAVE_TIME_IN_UTMP 1 + +/* Define if you have ut_time in utmpx.h */ +/* #undef HAVE_TIME_IN_UTMPX */ + +/* Define to 1 if you have the `timingsafe_bcmp' function. */ +/* #undef HAVE_TIMINGSAFE_BCMP */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_TMPDIR_H */ + +/* Define to 1 if you have the `truncate' function. */ +#define HAVE_TRUNCATE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_TTYENT_H 1 + +/* Define if you have ut_tv in utmp.h */ +/* #undef HAVE_TV_IN_UTMP */ + +/* Define if you have ut_tv in utmpx.h */ +#define HAVE_TV_IN_UTMPX 1 + +/* Define if you have ut_type in utmp.h */ +/* #undef HAVE_TYPE_IN_UTMP */ + +/* Define if you have ut_type in utmpx.h */ +#define HAVE_TYPE_IN_UTMPX 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UCRED_H */ + +/* Define to 1 if the system has the type `uintmax_t'. */ +#define HAVE_UINTMAX_T 1 + +/* define if you have uintxx_t data type */ +#define HAVE_UINTXX_T 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `unsetenv' function. */ +#define HAVE_UNSETENV 1 + +/* Define to 1 if the system has the type `unsigned long long'. */ +#define HAVE_UNSIGNED_LONG_LONG 1 + +/* Define to 1 if you have the `updwtmp' function. */ +/* #undef HAVE_UPDWTMP */ + +/* Define to 1 if you have the `updwtmpx' function. */ +#define HAVE_UPDWTMPX 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_USERSEC_H */ + +/* Define to 1 if you have the `user_from_uid' function. */ +#define HAVE_USER_FROM_UID 1 + +/* Define to 1 if you have the `usleep' function. */ +#define HAVE_USLEEP 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UTIL_H 1 + +/* Define to 1 if you have the `utimes' function. */ +#define HAVE_UTIMES 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UTIME_H 1 + +/* Define to 1 if you have the `utmpname' function. */ +#define HAVE_UTMPNAME 1 + +/* Define to 1 if you have the `utmpxname' function. */ +#define HAVE_UTMPXNAME 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UTMPX_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UTMP_H 1 + +/* define if you have u_char data type */ +#define HAVE_U_CHAR 1 + +/* define if you have u_int data type */ +#define HAVE_U_INT 1 + +/* define if you have u_int64_t data type */ +#define HAVE_U_INT64_T 1 + +/* define if you have u_intxx_t data type */ +#define HAVE_U_INTXX_T 1 + +/* Define to 1 if you have the `vasprintf' function. */ +#define HAVE_VASPRINTF 1 + +/* Define if va_copy exists */ +#define HAVE_VA_COPY 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_VIS_H 1 + +/* Define to 1 if you have the `vsnprintf' function. */ +#define HAVE_VSNPRINTF 1 + +/* Define to 1 if you have the `waitpid' function. */ +#define HAVE_WAITPID 1 + +/* Define to 1 if you have the `_getlong' function. */ +#define HAVE__GETLONG 1 + +/* Define to 1 if you have the `_getpty' function. */ +/* #undef HAVE__GETPTY */ + +/* Define to 1 if you have the `_getshort' function. */ +#define HAVE__GETSHORT 1 + +/* Define if you have struct __res_state _res as an extern */ +#define HAVE__RES_EXTERN 1 + +/* Define to 1 if you have the `__b64_ntop' function. */ +#define HAVE___B64_NTOP 1 + +/* Define to 1 if you have the `__b64_pton' function. */ +#define HAVE___B64_PTON 1 + +/* Define if compiler implements __FUNCTION__ */ +#define HAVE___FUNCTION__ 1 + +/* Define if libc defines __progname */ +#define HAVE___PROGNAME 1 + +/* Fields in struct sockaddr_storage */ +/* #undef HAVE___SS_FAMILY_IN_SS */ + +/* Define if __va_copy exists */ +#define HAVE___VA_COPY 1 + +/* Define if compiler implements __func__ */ +#define HAVE___func__ 1 + +/* Define this if you are using the Heimdal version of Kerberos V5 */ +/* #undef HEIMDAL */ + +/* Define if you need to use IP address instead of hostname in $DISPLAY */ +/* #undef IPADDR_IN_DISPLAY */ + +/* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */ +/* #undef IPV4_IN_IPV6 */ + +/* Define if your system choked on IP TOS setting */ +/* #undef IP_TOS_IS_BROKEN */ + +/* Define if you want Kerberos 5 support */ +/* #undef KRB5 */ + +/* Define if pututxline updates lastlog too */ +/* #undef LASTLOG_WRITE_PUTUTXLINE */ + +/* Define to whatever link() returns for "not supported" if it doesn't return + EOPNOTSUPP. */ +/* #undef LINK_OPNOTSUPP_ERRNO */ + +/* Adjust Linux out-of-memory killer */ +/* #undef LINUX_OOM_ADJUST */ + +/* max value of long long calculated by configure */ +/* #undef LLONG_MAX */ + +/* min value of long long calculated by configure */ +/* #undef LLONG_MIN */ + +/* Account locked with pw(1) */ +/* #undef LOCKED_PASSWD_PREFIX */ + +/* String used in /etc/passwd to denote locked account */ +/* #undef LOCKED_PASSWD_STRING */ + +/* String used in /etc/passwd to denote locked account */ +/* #undef LOCKED_PASSWD_SUBSTR */ + +/* Some versions of /bin/login need the TERM supplied on the commandline */ +/* #undef LOGIN_NEEDS_TERM */ + +/* Some systems need a utmpx entry for /bin/login to work */ +/* #undef LOGIN_NEEDS_UTMPX */ + +/* Define if your login program cannot handle end of options ("--") */ +/* #undef LOGIN_NO_ENDOPT */ + +/* If your header files don't define LOGIN_PROGRAM, then use this (detected) + from environment and PATH */ +#define LOGIN_PROGRAM_FALLBACK "/usr/bin/login" + +/* Set this to your mail directory if you do not have _PATH_MAILDIR */ +/* #undef MAIL_DIRECTORY */ + +/* Need setpgrp to acquire controlling tty */ +/* #undef NEED_SETPGRP */ + +/* compiler does not accept __attribute__ on return types */ +/* #undef NO_ATTRIBUTE_ON_RETURN_TYPE */ + +/* Define if the concept of ports only accessible to superusers isn't known */ +/* #undef NO_IPPORT_RESERVED_CONCEPT */ + +/* Define if you don't want to use lastlog in session.c */ +/* #undef NO_SSH_LASTLOG */ + +/* Define if X11 doesn't support AF_UNIX sockets on that system */ +/* #undef NO_X11_UNIX_SOCKETS */ + +/* Define if EVP_DigestUpdate returns void */ +/* #undef OPENSSL_EVP_DIGESTUPDATE_VOID */ + +/* OpenSSL has ECC */ +#define OPENSSL_HAS_ECC 1 + +/* libcrypto has NID_X9_62_prime256v1 */ +#define OPENSSL_HAS_NISTP256 1 + +/* libcrypto has NID_secp384r1 */ +#define OPENSSL_HAS_NISTP384 1 + +/* libcrypto has NID_secp521r1 */ +#define OPENSSL_HAS_NISTP521 1 + +/* libcrypto has EVP AES CTR */ +#define OPENSSL_HAVE_EVPCTR 1 + +/* libcrypto has EVP AES GCM */ +#define OPENSSL_HAVE_EVPGCM 1 + +/* libcrypto is missing AES 192 and 256 bit functions */ +/* #undef OPENSSL_LOBOTOMISED_AES */ + +/* Define if you want the OpenSSL internally seeded PRNG only */ +#define OPENSSL_PRNG_ONLY 1 + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "openssh-unix-dev@mindrot.org" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "OpenSSH" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "OpenSSH Portable" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "openssh" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "Portable" + +/* Define if you are using Solaris-derived PAM which passes pam_messages to + the conversation function with an extra level of indirection */ +/* #undef PAM_SUN_CODEBASE */ + +/* Work around problematic Linux PAM modules handling of PAM_TTY */ +/* #undef PAM_TTY_KLUDGE */ + +/* must supply username to passwd */ +/* #undef PASSWD_NEEDS_USERNAME */ + +/* System dirs owned by bin (uid 2) */ +/* #undef PLATFORM_SYS_DIR_UID */ + +/* Port number of PRNGD/EGD random number socket */ +/* #undef PRNGD_PORT */ + +/* Location of PRNGD/EGD random number socket */ +/* #undef PRNGD_SOCKET */ + +/* read(1) can return 0 for a non-closed fd */ +/* #undef PTY_ZEROREAD */ + +/* Sandbox using capsicum */ +/* #undef SANDBOX_CAPSICUM */ + +/* Sandbox using Darwin sandbox_init(3) */ +/* #undef SANDBOX_DARWIN */ + +/* no privsep sandboxing */ +#define SANDBOX_NULL 1 + +/* Sandbox using setrlimit(2) */ +/* #undef SANDBOX_RLIMIT */ + +/* Sandbox using seccomp filter */ +/* #undef SANDBOX_SECCOMP_FILTER */ + +/* setrlimit RLIMIT_FSIZE works */ +/* #undef SANDBOX_SKIP_RLIMIT_FSIZE */ + +/* define if setrlimit RLIMIT_NOFILE breaks things */ +/* #undef SANDBOX_SKIP_RLIMIT_NOFILE */ + +/* Sandbox using systrace(4) */ +/* #undef SANDBOX_SYSTRACE */ + +/* Specify the system call convention in use */ +/* #undef SECCOMP_AUDIT_ARCH */ + +/* Define if your platform breaks doing a seteuid before a setuid */ +/* #undef SETEUID_BREAKS_SETUID */ + +/* The size of `int', as computed by sizeof. */ +#define SIZEOF_INT 4 + +/* The size of `long int', as computed by sizeof. */ +#define SIZEOF_LONG_INT 4 + +/* The size of `long long int', as computed by sizeof. */ +#define SIZEOF_LONG_LONG_INT 8 + +/* The size of `short int', as computed by sizeof. */ +#define SIZEOF_SHORT_INT 2 + +/* Define if you want S/Key support */ +/* #undef SKEY */ + +/* Define if your skeychallenge() function takes 4 arguments (NetBSD) */ +/* #undef SKEYCHALLENGE_4ARG */ + +/* Define as const if snprintf() can declare const char *fmt */ +#define SNPRINTF_CONST /* not const */ + +/* Define to a Set Process Title type if your system is supported by + bsd-setproctitle.c */ +/* #undef SPT_TYPE */ + +/* Define if sshd somehow reacquires a controlling TTY after setsid() */ +/* #undef SSHD_ACQUIRES_CTTY */ + +/* Define if pam_chauthtok wants real uid set to the unpriv'ed user */ +/* #undef SSHPAM_CHAUTHTOK_NEEDS_RUID */ + +/* Use audit debugging module */ +/* #undef SSH_AUDIT_EVENTS */ + +/* Windows is sensitive to read buffer size */ +/* #undef SSH_IOBUFSZ */ + +/* non-privileged user for privilege separation */ +#define SSH_PRIVSEP_USER "sshd" + +/* Use tunnel device compatibility to OpenBSD */ +/* #undef SSH_TUN_COMPAT_AF */ + +/* Open tunnel devices the FreeBSD way */ +/* #undef SSH_TUN_FREEBSD */ + +/* Open tunnel devices the Linux tun/tap way */ +/* #undef SSH_TUN_LINUX */ + +/* No layer 2 tunnel support */ +/* #undef SSH_TUN_NO_L2 */ + +/* Open tunnel devices the OpenBSD way */ +/* #undef SSH_TUN_OPENBSD */ + +/* Prepend the address family to IP tunnel traffic */ +/* #undef SSH_TUN_PREPEND_AF */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you want a different $PATH for the superuser */ +/* #undef SUPERUSER_PATH */ + +/* syslog_r function is safe to use in in a signal handler */ +/* #undef SYSLOG_R_SAFE_IN_SIGHAND */ + +/* Support passwords > 8 chars */ +/* #undef UNIXWARE_LONG_PASSWORDS */ + +/* Specify default $PATH */ +/* #undef USER_PATH */ + +/* Define this if you want to use libkafs' AFS support */ +/* #undef USE_AFS */ + +/* Use BSM audit module */ +/* #undef USE_BSM_AUDIT */ + +/* Use btmp to log bad logins */ +/* #undef USE_BTMP */ + +/* Use libedit for sftp */ +/* #undef USE_LIBEDIT */ + +/* Use Linux audit module */ +/* #undef USE_LINUX_AUDIT */ + +/* Enable OpenSSL engine support */ +/* #undef USE_OPENSSL_ENGINE */ + +/* Define if you want to enable PAM support */ +/* #undef USE_PAM */ + +/* Use PIPES instead of a socketpair() */ +/* #undef USE_PIPES */ + +/* Define if you have Solaris process contracts */ +/* #undef USE_SOLARIS_PROCESS_CONTRACTS */ + +/* Define if you have Solaris projects */ +/* #undef USE_SOLARIS_PROJECTS */ + +/* Define if you shouldn't strip 'tty' from your ttyname in [uw]tmp */ +/* #undef WITH_ABBREV_NO_TTY */ + +/* Define if you want to enable AIX4's authenticate function */ +/* #undef WITH_AIXAUTHENTICATE */ + +/* Define if you have/want arrays (cluster-wide session managment, not C + arrays) */ +/* #undef WITH_IRIX_ARRAY */ + +/* Define if you want IRIX audit trails */ +/* #undef WITH_IRIX_AUDIT */ + +/* Define if you want IRIX kernel jobs */ +/* #undef WITH_IRIX_JOBS */ + +/* Define if you want IRIX project management */ +/* #undef WITH_IRIX_PROJECT */ + +/* use libcrypto for cryptography */ +#define WITH_OPENSSL 1 + +/* Define if you want SELinux support. */ +/* #undef WITH_SELINUX */ + +/* include SSH protocol version 1 support */ +/* #undef WITH_SSH1 */ + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +/* #undef WORDS_BIGENDIAN */ + +/* Define if xauth is found in your path */ +#define XAUTH_PATH "/usr/X11R7/bin/xauth" + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* log for bad login attempts */ +/* #undef _PATH_BTMP */ + +/* Full path of your "passwd" program */ +#define _PATH_PASSWD_PROG "/usr/bin/passwd" + +/* Specify location of ssh.pid */ +#define _PATH_SSH_PIDDIR "/var/run" + +/* Define if we don't have struct __res_state in resolv.h */ +/* #undef __res_state */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* type to use in place of socklen_t if not defined */ +/* #undef socklen_t */ diff --git a/crypto/external/bsd/openssh/dist/contrib/Makefile b/crypto/external/bsd/openssh/dist/contrib/Makefile new file mode 100644 index 000000000..eaf7fe2fd --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/Makefile @@ -0,0 +1,17 @@ +PKG_CONFIG = pkg-config + +all: + @echo "Valid targets: gnome-ssh-askpass1 gnome-ssh-askpass2" + +gnome-ssh-askpass1: gnome-ssh-askpass1.c + $(CC) $(CFLAGS) `gnome-config --cflags gnome gnomeui` \ + gnome-ssh-askpass1.c -o gnome-ssh-askpass1 \ + `gnome-config --libs gnome gnomeui` + +gnome-ssh-askpass2: gnome-ssh-askpass2.c + $(CC) $(CFLAGS) `$(PKG_CONFIG) --cflags gtk+-2.0` \ + gnome-ssh-askpass2.c -o gnome-ssh-askpass2 \ + `$(PKG_CONFIG) --libs gtk+-2.0 x11` + +clean: + rm -f *.o gnome-ssh-askpass1 gnome-ssh-askpass2 gnome-ssh-askpass diff --git a/crypto/external/bsd/openssh/dist/contrib/README b/crypto/external/bsd/openssh/dist/contrib/README new file mode 100644 index 000000000..60e19ba9f --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/README @@ -0,0 +1,70 @@ +Other patches and addons for OpenSSH. Please send submissions to +djm@mindrot.org + +Externally maintained +--------------------- + +SSH Proxy Command -- connect.c + +Shun-ichi GOTO has written a very useful ProxyCommand +which allows the use of outbound SSH from behind a SOCKS4, SOCKS5 or +https CONNECT style proxy server. His page for connect.c has extensive +documentation on its use as well as compiled versions for Win32. + +https://bitbucket.org/gotoh/connect/wiki/Home + + +X11 SSH Askpass: + +Jim Knoble has written an excellent X11 +passphrase requester. This is highly recommended: + +http://www.jmknoble.net/software/x11-ssh-askpass/ + + +In this directory +----------------- + +ssh-copy-id: + +Phil Hands' shell script to automate the process of adding +your public key to a remote machine's ~/.ssh/authorized_keys file. + +gnome-ssh-askpass[12]: + +A GNOME and Gtk2 passphrase requesters. Use "make gnome-ssh-askpass1" or +"make gnome-ssh-askpass2" to build. + +sshd.pam.generic: + +A generic PAM config file which may be useful on your system. YMMV + +sshd.pam.freebsd: + +A PAM config file which works with FreeBSD's PAM port. Contributed by +Dominik Brettnacher + +findssl.sh: + +Search for all instances of OpenSSL headers and libraries and print their +versions. This is intended to help diagnose OpenSSH's "OpenSSL headers do not +match your library" errors. + +aix: + Files to build an AIX native (installp or SMIT installable) package. + +caldera: + RPM spec file and scripts for building Caldera OpenLinuix packages + +cygwin: + Support files for Cygwin + +hpux: + Support files for HP-UX + +redhat: + RPM spec file and scripts for building Redhat packages + +suse: + RPM spec file and scripts for building SuSE packages + diff --git a/crypto/external/bsd/openssh/dist/contrib/aix/README b/crypto/external/bsd/openssh/dist/contrib/aix/README new file mode 100644 index 000000000..2a299350a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/aix/README @@ -0,0 +1,50 @@ +Overview: + +This directory contains files to build an AIX native (installp or SMIT +installable) openssh package. + + +Directions: + +(optional) create config.local in your build dir +./configure [options] +contrib/aix/buildbff.sh + +The file config.local or the environment is read to set the following options +(default first): +PERMIT_ROOT_LOGIN=[no|yes] +X11_FORWARDING=[no|yes] +AIX_SRC=[no|yes] + +Acknowledgements: + +The contents of this directory are based on Ben Lindstrom's Solaris +buildpkg.sh. Ben also supplied inventory.sh. + +Jim Abbey's (GPL'ed) lppbuild-2.1 was used to learn how to build .bff's +and for comparison with the output from this script, however no code +from lppbuild is included and it is not required for operation. + +SRC support based on examples provided by Sandor Sklar and Maarten Kreuger. +PrivSep account handling fixes contributed by W. Earl Allen. + + +Other notes: + +The script treats all packages as USR packages (not ROOT+USR when +appropriate). It seems to work, though...... + +If there are any patches to this that have not yet been integrated they +may be found at http://www.zip.com.au/~dtucker/openssh/. + + +Disclaimer: + +It is hoped that it is useful but there is no warranty. If it breaks +you get to keep both pieces. + + + - Darren Tucker (dtucker at zip dot com dot au) + 2002/03/01 + +$Id: README,v 1.4 2003/08/25 05:01:04 dtucker Exp $ diff --git a/crypto/external/bsd/openssh/dist/contrib/aix/buildbff.sh b/crypto/external/bsd/openssh/dist/contrib/aix/buildbff.sh new file mode 100755 index 000000000..81d8cc301 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/aix/buildbff.sh @@ -0,0 +1,381 @@ +#!/bin/sh +# +# buildbff.sh: Create AIX SMIT-installable OpenSSH packages +# $Id: buildbff.sh,v 1.13 2011/05/05 03:48:41 djm Exp $ +# +# Author: Darren Tucker (dtucker at zip dot com dot au) +# This file is placed in the public domain and comes with absolutely +# no warranty. +# +# Based originally on Ben Lindstrom's buildpkg.sh for Solaris +# + +# +# Tunable configuration settings +# create a "config.local" in your build directory or set +# environment variables to override these. +# +[ -z "$PERMIT_ROOT_LOGIN" ] && PERMIT_ROOT_LOGIN=no +[ -z "$X11_FORWARDING" ] && X11_FORWARDING=no +[ -z "$AIX_SRC" ] && AIX_SRC=no + +umask 022 + +startdir=`pwd` + +perl -v >/dev/null || (echo perl required; exit 1) + +# Path to inventory.sh: same place as buildbff.sh +if echo $0 | egrep '^/' +then + inventory=`dirname $0`/inventory.sh # absolute path +else + inventory=`pwd`/`dirname $0`/inventory.sh # relative path +fi + +# +# We still support running from contrib/aix, but this is deprecated +# +if pwd | egrep 'contrib/aix$' +then + echo "Changing directory to `pwd`/../.." + echo "Please run buildbff.sh from your build directory in future." + cd ../.. + contribaix=1 +fi + +if [ ! -f Makefile ] +then + echo "Makefile not found (did you run configure?)" + exit 1 +fi + +# +# Directories used during build: +# current dir = $objdir directory you ran ./configure in. +# $objdir/$PKGDIR/ directory package files are constructed in +# $objdir/$PKGDIR/root/ package root ($FAKE_ROOT) +# +objdir=`pwd` +PKGNAME=openssh +PKGDIR=package + +# +# Collect local configuration settings to override defaults +# +if [ -s ./config.local ] +then + echo Reading local settings from config.local + . ./config.local +fi + +# +# Fill in some details from Makefile, like prefix and sysconfdir +# the eval also expands variables like sysconfdir=${prefix}/etc +# provided they are eval'ed in the correct order +# +for confvar in prefix exec_prefix bindir sbindir libexecdir datadir mandir mansubdir sysconfdir piddir srcdir +do + eval $confvar=`grep "^$confvar=" $objdir/Makefile | cut -d = -f 2` +done + +# +# Collect values of privsep user and privsep path +# currently only found in config.h +# +for confvar in SSH_PRIVSEP_USER PRIVSEP_PATH +do + eval $confvar=`awk '/#define[ \t]'$confvar'/{print $3}' $objdir/config.h` +done + +# Set privsep defaults if not defined +if [ -z "$SSH_PRIVSEP_USER" ] +then + SSH_PRIVSEP_USER=sshd +fi +if [ -z "$PRIVSEP_PATH" ] +then + PRIVSEP_PATH=/var/empty +fi + +# Clean package build directory +rm -rf $objdir/$PKGDIR +FAKE_ROOT=$objdir/$PKGDIR/root +mkdir -p $FAKE_ROOT + +# Start by faking root install +echo "Faking root install..." +cd $objdir +make install-nokeys DESTDIR=$FAKE_ROOT + +if [ $? -gt 0 ] +then + echo "Fake root install failed, stopping." + exit 1 +fi + +# +# Copy informational files to include in package +# +cp $srcdir/LICENCE $objdir/$PKGDIR/ +cp $srcdir/README* $objdir/$PKGDIR/ + +# +# Extract common info requires for the 'info' part of the package. +# AIX requires 4-part version numbers +# +VERSION=`./ssh -V 2>&1 | cut -f 1 -d , | cut -f 2 -d _` +MAJOR=`echo $VERSION | cut -f 1 -d p | cut -f 1 -d .` +MINOR=`echo $VERSION | cut -f 1 -d p | cut -f 2 -d .` +PATCH=`echo $VERSION | cut -f 1 -d p | cut -f 3 -d .` +PORTABLE=`echo $VERSION | awk 'BEGIN{FS="p"}{print $2}'` +[ "$PATCH" = "" ] && PATCH=0 +[ "$PORTABLE" = "" ] && PORTABLE=0 +BFFVERSION=`printf "%d.%d.%d.%d" $MAJOR $MINOR $PATCH $PORTABLE` + +echo "Building BFF for $PKGNAME $VERSION (package version $BFFVERSION)" + +# +# Set ssh and sshd parameters as per config.local +# +if [ "${PERMIT_ROOT_LOGIN}" = no ] +then + perl -p -i -e "s/#PermitRootLogin yes/PermitRootLogin no/" \ + $FAKE_ROOT/${sysconfdir}/sshd_config +fi +if [ "${X11_FORWARDING}" = yes ] +then + perl -p -i -e "s/#X11Forwarding no/X11Forwarding yes/" \ + $FAKE_ROOT/${sysconfdir}/sshd_config +fi + + +# Rename config files; postinstall script will copy them if necessary +for cfgfile in ssh_config sshd_config +do + mv $FAKE_ROOT/$sysconfdir/$cfgfile $FAKE_ROOT/$sysconfdir/$cfgfile.default +done + +# +# Generate lpp control files. +# working dir is $FAKE_ROOT but files are generated in dir above +# and moved into place just before creation of .bff +# +cd $FAKE_ROOT +echo Generating LPP control files +find . ! -name . -print >../openssh.al +$inventory >../openssh.inventory + +cat <../openssh.copyright +This software is distributed under a BSD-style license. +For the full text of the license, see /usr/lpp/openssh/LICENCE +EOD + +# +# openssh.size file allows filesystem expansion as required +# generate list of directories containing files +# then calculate disk usage for each directory and store in openssh.size +# +files=`find . -type f -print` +dirs=`for file in $files; do dirname $file; done | sort -u` +for dir in $dirs +do + du $dir +done > ../openssh.size + +# +# Create postinstall script +# +cat <>../openssh.post_i +#!/bin/sh + +echo Creating configs from defaults if necessary. +for cfgfile in ssh_config sshd_config +do + if [ ! -f $sysconfdir/\$cfgfile ] + then + echo "Creating \$cfgfile from default" + cp $sysconfdir/\$cfgfile.default $sysconfdir/\$cfgfile + else + echo "\$cfgfile already exists." + fi +done +echo + +# Create PrivilegeSeparation user and group if not present +echo Checking for PrivilegeSeparation user and group. +if cut -f1 -d: /etc/group | egrep '^'$SSH_PRIVSEP_USER'\$' >/dev/null +then + echo "PrivSep group $SSH_PRIVSEP_USER already exists." +else + echo "Creating PrivSep group $SSH_PRIVSEP_USER." + mkgroup -A $SSH_PRIVSEP_USER +fi + +# Create user if required +if lsuser "$SSH_PRIVSEP_USER" >/dev/null +then + echo "PrivSep user $SSH_PRIVSEP_USER already exists." +else + echo "Creating PrivSep user $SSH_PRIVSEP_USER." + mkuser gecos='SSHD PrivSep User' login=false rlogin=false account_locked=true pgrp=$SSH_PRIVSEP_USER $SSH_PRIVSEP_USER +fi + +if egrep '^[ \t]*UsePrivilegeSeparation[ \t]+no' $sysconfdir/sshd_config >/dev/null +then + echo UsePrivilegeSeparation not enabled, privsep directory not required. +else + # create chroot directory if required + if [ -d $PRIVSEP_PATH ] + then + echo "PrivSep chroot directory $PRIVSEP_PATH already exists." + else + echo "Creating PrivSep chroot directory $PRIVSEP_PATH." + mkdir $PRIVSEP_PATH + chown 0 $PRIVSEP_PATH + chgrp 0 $PRIVSEP_PATH + chmod 755 $PRIVSEP_PATH + fi +fi +echo + +# Generate keys unless they already exist +echo Creating host keys if required. +if [ -f "$sysconfdir/ssh_host_key" ] ; then + echo "$sysconfdir/ssh_host_key already exists, skipping." +else + $bindir/ssh-keygen -t rsa1 -f $sysconfdir/ssh_host_key -N "" +fi +if [ -f $sysconfdir/ssh_host_dsa_key ] ; then + echo "$sysconfdir/ssh_host_dsa_key already exists, skipping." +else + $bindir/ssh-keygen -t dsa -f $sysconfdir/ssh_host_dsa_key -N "" +fi +if [ -f $sysconfdir/ssh_host_rsa_key ] ; then + echo "$sysconfdir/ssh_host_rsa_key already exists, skipping." +else + $bindir/ssh-keygen -t rsa -f $sysconfdir/ssh_host_rsa_key -N "" +fi +echo + +# Set startup command depending on SRC support +if [ "$AIX_SRC" = "yes" ] +then + echo Creating SRC sshd subsystem. + rmssys -s sshd 2>&1 >/dev/null + mkssys -s sshd -p "$sbindir/sshd" -a '-D' -u 0 -S -n 15 -f 9 -R -G tcpip + startupcmd="start $sbindir/sshd \\\"\\\$src_running\\\"" + oldstartcmd="$sbindir/sshd" +else + startupcmd="$sbindir/sshd" + oldstartcmd="start $sbindir/sshd \\\"$src_running\\\"" +fi + +# If migrating to or from SRC, change previous startup command +# otherwise add to rc.tcpip +if egrep "^\$oldstartcmd" /etc/rc.tcpip >/dev/null +then + if sed "s|^\$oldstartcmd|\$startupcmd|g" /etc/rc.tcpip >/etc/rc.tcpip.new + then + chmod 0755 /etc/rc.tcpip.new + mv /etc/rc.tcpip /etc/rc.tcpip.old && \ + mv /etc/rc.tcpip.new /etc/rc.tcpip + else + echo "Updating /etc/rc.tcpip failed, please check." + fi +else + # Add to system startup if required + if grep "^\$startupcmd" /etc/rc.tcpip >/dev/null + then + echo "sshd found in rc.tcpip, not adding." + else + echo "Adding sshd to rc.tcpip" + echo >>/etc/rc.tcpip + echo "# Start sshd" >>/etc/rc.tcpip + echo "\$startupcmd" >>/etc/rc.tcpip + fi +fi +EOF + +# +# Create liblpp.a and move control files into it +# +echo Creating liblpp.a +( + cd .. + for i in openssh.al openssh.copyright openssh.inventory openssh.post_i openssh.size LICENCE README* + do + ar -r liblpp.a $i + rm $i + done +) + +# +# Create lpp_name +# +# This will end up looking something like: +# 4 R I OpenSSH { +# OpenSSH 3.0.2.1 1 N U en_US OpenSSH 3.0.2p1 Portable for AIX +# [ +# % +# /usr/local/bin 8073 +# /usr/local/etc 189 +# /usr/local/libexec 185 +# /usr/local/man/man1 145 +# /usr/local/man/man8 83 +# /usr/local/sbin 2105 +# /usr/local/share 3 +# % +# ] +# } + +echo Creating lpp_name +cat <../lpp_name +4 R I $PKGNAME { +$PKGNAME $BFFVERSION 1 N U en_US OpenSSH $VERSION Portable for AIX +[ +% +EOF + +for i in $bindir $sysconfdir $libexecdir $mandir/${mansubdir}1 $mandir/${mansubdir}8 $sbindir $datadir /usr/lpp/openssh +do + # get size in 512 byte blocks + if [ -d $FAKE_ROOT/$i ] + then + size=`du $FAKE_ROOT/$i | awk '{print $1}'` + echo "$i $size" >>../lpp_name + fi +done + +echo '%' >>../lpp_name +echo ']' >>../lpp_name +echo '}' >>../lpp_name + +# +# Move pieces into place +# +mkdir -p usr/lpp/openssh +mv ../liblpp.a usr/lpp/openssh +mv ../lpp_name . + +# +# Now invoke backup to create .bff file +# note: lpp_name needs to be the first file so we generate the +# file list on the fly and feed it to backup using -i +# +echo Creating $PKGNAME-$VERSION.bff with backup... +rm -f $PKGNAME-$VERSION.bff +( + echo "./lpp_name" + find . ! -name lpp_name -a ! -name . -print +) | backup -i -q -f ../$PKGNAME-$VERSION.bff $filelist + +# +# Move package into final location and clean up +# +mv ../$PKGNAME-$VERSION.bff $startdir +cd $startdir +rm -rf $objdir/$PKGDIR + +echo $0: done. + diff --git a/crypto/external/bsd/openssh/dist/contrib/aix/inventory.sh b/crypto/external/bsd/openssh/dist/contrib/aix/inventory.sh new file mode 100755 index 000000000..e2641e79c --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/aix/inventory.sh @@ -0,0 +1,63 @@ +#!/bin/sh +# +# inventory.sh +# $Id: inventory.sh,v 1.6 2003/11/21 12:48:56 djm Exp $ +# +# Originally written by Ben Lindstrom, modified by Darren Tucker to use perl +# This file is placed into the public domain. +# +# This will produce an AIX package inventory file, which looks like: +# +# /usr/local/bin: +# class=apply,inventory,openssh +# owner=root +# group=system +# mode=755 +# type=DIRECTORY +# /usr/local/bin/slogin: +# class=apply,inventory,openssh +# owner=root +# group=system +# mode=777 +# type=SYMLINK +# target=ssh +# /usr/local/share/Ssh.bin: +# class=apply,inventory,openssh +# owner=root +# group=system +# mode=644 +# type=FILE +# size=VOLATILE +# checksum=VOLATILE + +find . ! -name . -print | perl -ne '{ + chomp; + if ( -l $_ ) { + ($dev,$ino,$mod,$nl,$uid,$gid,$rdev,$sz,$at,$mt,$ct,$bsz,$blk)=lstat; + } else { + ($dev,$ino,$mod,$nl,$uid,$gid,$rdev,$sz,$at,$mt,$ct,$bsz,$blk)=stat; + } + + # Start to display inventory information + $name = $_; + $name =~ s|^.||; # Strip leading dot from path + print "$name:\n"; + print "\tclass=apply,inventory,openssh\n"; + print "\towner=root\n"; + print "\tgroup=system\n"; + printf "\tmode=%lo\n", $mod & 07777; # Mask perm bits + + if ( -l $_ ) { + # Entry is SymLink + print "\ttype=SYMLINK\n"; + printf "\ttarget=%s\n", readlink($_); + } elsif ( -f $_ ) { + # Entry is File + print "\ttype=FILE\n"; + print "\tsize=$sz\n"; + print "\tchecksum=VOLATILE\n"; + } elsif ( -d $_ ) { + # Entry is Directory + print "\ttype=DIRECTORY\n"; + } +}' diff --git a/crypto/external/bsd/openssh/dist/contrib/aix/pam.conf b/crypto/external/bsd/openssh/dist/contrib/aix/pam.conf new file mode 100644 index 000000000..f1528b005 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/aix/pam.conf @@ -0,0 +1,20 @@ +# +# PAM configuration file /etc/pam.conf +# Example for OpenSSH on AIX 5.2 +# + +# Authentication Management +sshd auth required /usr/lib/security/pam_aix +OTHER auth required /usr/lib/security/pam_aix + +# Account Management +sshd account required /usr/lib/security/pam_aix +OTHER account required /usr/lib/security/pam_aix + +# Password Management +sshd password required /usr/lib/security/pam_aix +OTHER password required /usr/lib/security/pam_aix + +# Session Management +sshd session required /usr/lib/security/pam_aix +OTHER session required /usr/lib/security/pam_aix diff --git a/crypto/external/bsd/openssh/dist/contrib/cygwin/Makefile b/crypto/external/bsd/openssh/dist/contrib/cygwin/Makefile new file mode 100644 index 000000000..a0261f48d --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/cygwin/Makefile @@ -0,0 +1,77 @@ +srcdir=../.. +copyidsrcdir=.. +prefix=/usr +exec_prefix=$(prefix) +bindir=$(prefix)/bin +datadir=$(prefix)/share +mandir=$(datadir)/man +docdir=$(datadir)/doc +sshdocdir=$(docdir)/openssh +cygdocdir=$(docdir)/Cygwin +sysconfdir=/etc +defaultsdir=$(sysconfdir)/defaults/etc +inetdefdir=$(defaultsdir)/inetd.d +PRIVSEP_PATH=/var/empty +INSTALL=/usr/bin/install -c + +DESTDIR= + +all: + @echo + @echo "Use \`make cygwin-postinstall DESTDIR=[package directory]'" + @echo "Be sure having DESTDIR set correctly!" + @echo + +move-config-files: $(DESTDIR)$(sysconfdir)/ssh_config $(DESTDIR)$(sysconfdir)/sshd_config + $(srcdir)/mkinstalldirs $(DESTDIR)$(defaultsdir) + mv $(DESTDIR)$(sysconfdir)/ssh_config $(DESTDIR)$(defaultsdir) + mv $(DESTDIR)$(sysconfdir)/sshd_config $(DESTDIR)$(defaultsdir) + +remove-empty-dir: + rm -rf $(DESTDIR)$(PRIVSEP_PATH) + +install-inetd-config: + $(srcdir)/mkinstalldirs $(DESTDIR)$(inetdefdir) + $(INSTALL) -m 644 sshd-inetd $(DESTDIR)$(inetdefdir)/sshd-inetd + +install-sshdoc: + $(srcdir)/mkinstalldirs $(DESTDIR)$(sshdocdir) + -$(INSTALL) -m 644 $(srcdir)/CREDITS $(DESTDIR)$(sshdocdir)/CREDITS + -$(INSTALL) -m 644 $(srcdir)/ChangeLog $(DESTDIR)$(sshdocdir)/ChangeLog + -$(INSTALL) -m 644 $(srcdir)/LICENCE $(DESTDIR)$(sshdocdir)/LICENCE + -$(INSTALL) -m 644 $(srcdir)/OVERVIEW $(DESTDIR)$(sshdocdir)/OVERVIEW + -$(INSTALL) -m 644 $(srcdir)/PROTOCOL $(DESTDIR)$(sshdocdir)/PROTOCOL + -$(INSTALL) -m 644 $(srcdir)/PROTOCOL.agent $(DESTDIR)$(sshdocdir)/PROTOCOL.agent + -$(INSTALL) -m 644 $(srcdir)/PROTOCOL.certkeys $(DESTDIR)$(sshdocdir)/PROTOCOL.certkeys + -$(INSTALL) -m 644 $(srcdir)/PROTOCOL.mux $(DESTDIR)$(sshdocdir)/PROTOCOL.mux + -$(INSTALL) -m 644 $(srcdir)/README $(DESTDIR)$(sshdocdir)/README + -$(INSTALL) -m 644 $(srcdir)/README.dns $(DESTDIR)$(sshdocdir)/README.dns + -$(INSTALL) -m 644 $(srcdir)/README.platform $(DESTDIR)$(sshdocdir)/README.platform + -$(INSTALL) -m 644 $(srcdir)/README.privsep $(DESTDIR)$(sshdocdir)/README.privsep + -$(INSTALL) -m 644 $(srcdir)/README.tun $(DESTDIR)$(sshdocdir)/README.tun + -$(INSTALL) -m 644 $(srcdir)/TODO $(DESTDIR)$(sshdocdir)/TODO + +install-cygwindoc: README + $(srcdir)/mkinstalldirs $(DESTDIR)$(cygdocdir) + $(INSTALL) -m 644 README $(DESTDIR)$(cygdocdir)/openssh.README + +install-doc: install-sshdoc install-cygwindoc + +install-scripts: ssh-host-config ssh-user-config + $(srcdir)/mkinstalldirs $(DESTDIR)$(bindir) + $(INSTALL) -m 755 ssh-host-config $(DESTDIR)$(bindir)/ssh-host-config + $(INSTALL) -m 755 ssh-user-config $(DESTDIR)$(bindir)/ssh-user-config + +install-copy-id: $(copyidsrcdir)/ssh-copy-id $(copyidsrcdir)/ssh-copy-id.1 + $(INSTALL) -m 755 $(copyidsrcdir)/ssh-copy-id $(DESTDIR)$(bindir)/ssh-copy-id + $(INSTALL) -m 644 $(copyidsrcdir)/ssh-copy-id.1 $(DESTDIR)$(mandir)/man1/ssh-copy-id.1 + +gzip-man-pages: + rm $(DESTDIR)$(mandir)/man1/slogin.1 + gzip $(DESTDIR)$(mandir)/man1/*.1 + gzip $(DESTDIR)$(mandir)/man5/*.5 + gzip $(DESTDIR)$(mandir)/man8/*.8 + cd $(DESTDIR)$(mandir)/man1 && ln -s ssh.1.gz slogin.1.gz + +cygwin-postinstall: move-config-files remove-empty-dir install-inetd-config install-doc install-scripts install-copy-id gzip-man-pages + @echo "Cygwin specific configuration finished." diff --git a/crypto/external/bsd/openssh/dist/contrib/cygwin/README b/crypto/external/bsd/openssh/dist/contrib/cygwin/README new file mode 100644 index 000000000..1396d99cd --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/cygwin/README @@ -0,0 +1,90 @@ +This package describes important Cygwin specific stuff concerning OpenSSH. + +The binary package is usually built for recent Cygwin versions and might +not run on older versions. Please check http://cygwin.com/ for information +about current Cygwin releases. + +================== +Host configuration +================== + +If you are installing OpenSSH the first time, you can generate global config +files and server keys, as well as installing sshd as a service, by running + + /usr/bin/ssh-host-config + +Note that this binary archive doesn't contain default config files in /etc. +That files are only created if ssh-host-config is started. + +To support testing and unattended installation ssh-host-config got +some options: + +usage: ssh-host-config [OPTION]... +Options: + --debug -d Enable shell's debug output. + --yes -y Answer all questions with "yes" automatically. + --no -n Answer all questions with "no" automatically. + --cygwin -c Use "options" as value for CYGWIN environment var. + --port -p sshd listens on port n. + --user -u privileged user for service, default 'cyg_server'. + --pwd -w Use "pwd" as password for privileged user. + --privileged On Windows XP, require privileged user + instead of LocalSystem for sshd service. + +Installing sshd as daemon via ssh-host-config is recommended. + +Alternatively you can start sshd via inetd, if you have the inetutils +package installed. Just run ssh-host-config, but answer "no" when asked +to install sshd as service. The ssh-host-config script also adds the +required lines to /etc/inetd.conf and /etc/services. + +================== +User configuration +================== + +Any user can simplify creating the own private and public keys by running + + /usr/bin/ssh-user-config + +To support testing and unattended installation ssh-user-config got +some options as well: + +usage: ssh-user-config [OPTION]... +Options: + --debug -d Enable shell's debug output. + --yes -y Answer all questions with "yes" automatically. + --no -n Answer all questions with "no" automatically. + --passphrase -p word Use "word" as passphrase automatically. + +Please note that OpenSSH does never use the value of $HOME to +search for the users configuration files! It always uses the +value of the pw_dir field in /etc/passwd as the home directory. +If no home diretory is set in /etc/passwd, the root directory +is used instead! + +================ +Building OpenSSH +================ + +Building from source is easy. Just unpack the source archive, cd to that +directory, and call cygport: + + cygport openssh.cygport all + +You must have installed the following packages to be able to build OpenSSH +with the aforementioned cygport script: + + zlib + crypt + openssl-devel + libedit-devel + libkrb5-devel + +Please send requests, error reports etc. to cygwin@cygwin.com. + + +Have fun, + +Corinna Vinschen +Cygwin Developer +Red Hat Inc. diff --git a/crypto/external/bsd/openssh/dist/contrib/cygwin/ssh-host-config b/crypto/external/bsd/openssh/dist/contrib/cygwin/ssh-host-config new file mode 100644 index 000000000..d934d09b5 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/cygwin/ssh-host-config @@ -0,0 +1,718 @@ +#!/bin/bash +# +# ssh-host-config, Copyright 2000-2014 Red Hat Inc. +# +# This file is part of the Cygwin port of OpenSSH. +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR +# THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +# ====================================================================== +# Initialization +# ====================================================================== + +CSIH_SCRIPT=/usr/share/csih/cygwin-service-installation-helper.sh + +# List of apps used. This is checkad for existance in csih_sanity_check +# Don't use *any* transient commands before sourcing the csih helper script, +# otherwise the sanity checks are short-circuited. +declare -a csih_required_commands=( + /usr/bin/basename coreutils + /usr/bin/cat coreutils + /usr/bin/chmod coreutils + /usr/bin/dirname coreutils + /usr/bin/id coreutils + /usr/bin/mv coreutils + /usr/bin/rm coreutils + /usr/bin/cygpath cygwin + /usr/bin/mkpasswd cygwin + /usr/bin/mount cygwin + /usr/bin/ps cygwin + /usr/bin/umount cygwin + /usr/bin/cmp diffutils + /usr/bin/grep grep + /usr/bin/awk gawk + /usr/bin/ssh-keygen openssh + /usr/sbin/sshd openssh + /usr/bin/sed sed +) +csih_sanity_check_server=yes +source ${CSIH_SCRIPT} + +PROGNAME=$(/usr/bin/basename $0) +_tdir=$(/usr/bin/dirname $0) +PROGDIR=$(cd $_tdir && pwd) + +# Subdirectory where the new package is being installed +PREFIX=/usr + +# Directory where the config files are stored +SYSCONFDIR=/etc +LOCALSTATEDIR=/var + +sshd_config_configured=no +port_number=22 +service_name=sshd +strictmodes=yes +privsep_used=yes +cygwin_value="" +user_account= +password_value= +opt_force=no + +# ====================================================================== +# Routine: update_services_file +# ====================================================================== +update_services_file() { + local _my_etcdir="/ssh-host-config.$$" + local _win_etcdir + local _services + local _spaces + local _serv_tmp + local _wservices + local ret=0 + + _win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc" + _services="${_my_etcdir}/services" + _spaces=" #" + _serv_tmp="${_my_etcdir}/srv.out.$$" + + /usr/bin/mount -o text,posix=0,noacl -f "${_win_etcdir}" "${_my_etcdir}" + + # Depends on the above mount + _wservices=`cygpath -w "${_services}"` + + # Add ssh 22/tcp and ssh 22/udp to services + if [ `/usr/bin/grep -q 'ssh[[:space:]][[:space:]]*22' "${_services}"; echo $?` -ne 0 ] + then + if /usr/bin/awk '{ if ( $2 ~ /^23\/tcp/ ) print "ssh 22/tcp'"${_spaces}"'SSH Remote Login Protocol\nssh 22/udp'"${_spaces}"'SSH Remote Login Protocol"; print $0; }' < "${_services}" > "${_serv_tmp}" + then + if /usr/bin/mv "${_serv_tmp}" "${_services}" + then + csih_inform "Added ssh to ${_wservices}" + else + csih_warning "Adding ssh to ${_wservices} failed!" + let ++ret + fi + /usr/bin/rm -f "${_serv_tmp}" + else + csih_warning "Adding ssh to ${_wservices} failed!" + let ++ret + fi + fi + /usr/bin/umount "${_my_etcdir}" + return $ret +} # --- End of update_services_file --- # + +# ====================================================================== +# Routine: sshd_strictmodes +# MODIFIES: strictmodes +# ====================================================================== +sshd_strictmodes() { + if [ "${sshd_config_configured}" != "yes" ] + then + echo + csih_inform "StrictModes is set to 'yes' by default." + csih_inform "This is the recommended setting, but it requires that the POSIX" + csih_inform "permissions of the user's home directory, the user's .ssh" + csih_inform "directory, and the user's ssh key files are tight so that" + csih_inform "only the user has write permissions." + csih_inform "On the other hand, StrictModes don't work well with default" + csih_inform "Windows permissions of a home directory mounted with the" + csih_inform "'noacl' option, and they don't work at all if the home" + csih_inform "directory is on a FAT or FAT32 partition." + if ! csih_request "Should StrictModes be used?" + then + strictmodes=no + fi + fi + return 0 +} + +# ====================================================================== +# Routine: sshd_privsep +# MODIFIES: privsep_used +# ====================================================================== +sshd_privsep() { + local ret=0 + + if [ "${sshd_config_configured}" != "yes" ] + then + echo + csih_inform "Privilege separation is set to 'sandbox' by default since" + csih_inform "OpenSSH 6.1. This is unsupported by Cygwin and has to be set" + csih_inform "to 'yes' or 'no'." + csih_inform "However, using privilege separation requires a non-privileged account" + csih_inform "called 'sshd'." + csih_inform "For more info on privilege separation read /usr/share/doc/openssh/README.privsep." + if csih_request "Should privilege separation be used?" + then + privsep_used=yes + if ! csih_create_unprivileged_user sshd + then + csih_error_recoverable "Couldn't create user 'sshd'!" + csih_error_recoverable "Privilege separation set to 'no' again!" + csih_error_recoverable "Check your ${SYSCONFDIR}/sshd_config file!" + let ++ret + privsep_used=no + fi + else + privsep_used=no + fi + fi + return $ret +} # --- End of sshd_privsep --- # + +# ====================================================================== +# Routine: sshd_config_tweak +# ====================================================================== +sshd_config_tweak() { + local ret=0 + + # Modify sshd_config + csih_inform "Updating ${SYSCONFDIR}/sshd_config file" + if [ "${port_number}" -ne 22 ] + then + /usr/bin/sed -i -e "s/^#\?[[:space:]]*Port[[:space:]].*/Port ${port_number}/" \ + ${SYSCONFDIR}/sshd_config + if [ $? -ne 0 ] + then + csih_warning "Setting listening port to ${port_number} failed!" + csih_warning "Check your ${SYSCONFDIR}/sshd_config file!" + let ++ret + fi + fi + if [ "${strictmodes}" = "no" ] + then + /usr/bin/sed -i -e "s/^#\?[[:space:]]*StrictModes[[:space:]].*/StrictModes no/" \ + ${SYSCONFDIR}/sshd_config + if [ $? -ne 0 ] + then + csih_warning "Setting StrictModes to 'no' failed!" + csih_warning "Check your ${SYSCONFDIR}/sshd_config file!" + let ++ret + fi + fi + if [ "${sshd_config_configured}" != "yes" ] + then + /usr/bin/sed -i -e " + s/^#\?UsePrivilegeSeparation .*/UsePrivilegeSeparation ${privsep_used}/" \ + ${SYSCONFDIR}/sshd_config + if [ $? -ne 0 ] + then + csih_warning "Setting privilege separation failed!" + csih_warning "Check your ${SYSCONFDIR}/sshd_config file!" + let ++ret + fi + fi + return $ret +} # --- End of sshd_config_tweak --- # + +# ====================================================================== +# Routine: update_inetd_conf +# ====================================================================== +update_inetd_conf() { + local _inetcnf="${SYSCONFDIR}/inetd.conf" + local _inetcnf_tmp="${SYSCONFDIR}/inetd.conf.$$" + local _inetcnf_dir="${SYSCONFDIR}/inetd.d" + local _sshd_inetd_conf="${_inetcnf_dir}/sshd-inetd" + local _sshd_inetd_conf_tmp="${_inetcnf_dir}/sshd-inetd.$$" + local _with_comment=1 + local ret=0 + + if [ -d "${_inetcnf_dir}" ] + then + # we have inetutils-1.5 inetd.d support + if [ -f "${_inetcnf}" ] + then + /usr/bin/grep -q '^[[:space:]]*ssh' "${_inetcnf}" && _with_comment=0 + + # check for sshd OR ssh in top-level inetd.conf file, and remove + # will be replaced by a file in inetd.d/ + if [ $(/usr/bin/grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?) -eq 0 ] + then + /usr/bin/grep -v '^[# \t]*ssh' "${_inetcnf}" >> "${_inetcnf_tmp}" + if [ -f "${_inetcnf_tmp}" ] + then + if /usr/bin/mv "${_inetcnf_tmp}" "${_inetcnf}" + then + csih_inform "Removed ssh[d] from ${_inetcnf}" + else + csih_warning "Removing ssh[d] from ${_inetcnf} failed!" + let ++ret + fi + /usr/bin/rm -f "${_inetcnf_tmp}" + else + csih_warning "Removing ssh[d] from ${_inetcnf} failed!" + let ++ret + fi + fi + fi + + csih_install_config "${_sshd_inetd_conf}" "${SYSCONFDIR}/defaults" + if /usr/bin/cmp "${SYSCONFDIR}/defaults${_sshd_inetd_conf}" "${_sshd_inetd_conf}" >/dev/null 2>&1 + then + if [ "${_with_comment}" -eq 0 ] + then + /usr/bin/sed -e 's/@COMMENT@[[:space:]]*//' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}" + else + /usr/bin/sed -e 's/@COMMENT@[[:space:]]*/# /' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}" + fi + if /usr/bin/mv "${_sshd_inetd_conf_tmp}" "${_sshd_inetd_conf}" + then + csih_inform "Updated ${_sshd_inetd_conf}" + else + csih_warning "Updating ${_sshd_inetd_conf} failed!" + let ++ret + fi + fi + + elif [ -f "${_inetcnf}" ] + then + /usr/bin/grep -q '^[[:space:]]*sshd' "${_inetcnf}" && _with_comment=0 + + # check for sshd in top-level inetd.conf file, and remove + # will be replaced by a file in inetd.d/ + if [ `/usr/bin/grep -q '^#\?[[:space:]]*sshd' "${_inetcnf}"; echo $?` -eq 0 ] + then + /usr/bin/grep -v '^#\?[[:space:]]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}" + if [ -f "${_inetcnf_tmp}" ] + then + if /usr/bin/mv "${_inetcnf_tmp}" "${_inetcnf}" + then + csih_inform "Removed sshd from ${_inetcnf}" + else + csih_warning "Removing sshd from ${_inetcnf} failed!" + let ++ret + fi + /usr/bin/rm -f "${_inetcnf_tmp}" + else + csih_warning "Removing sshd from ${_inetcnf} failed!" + let ++ret + fi + fi + + # Add ssh line to inetd.conf + if [ `/usr/bin/grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -ne 0 ] + then + if [ "${_with_comment}" -eq 0 ] + then + echo 'ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}" + else + echo '# ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}" + fi + if [ $? -eq 0 ] + then + csih_inform "Added ssh to ${_inetcnf}" + else + csih_warning "Adding ssh to ${_inetcnf} failed!" + let ++ret + fi + fi + fi + return $ret +} # --- End of update_inetd_conf --- # + +# ====================================================================== +# Routine: check_service_files_ownership +# Checks that the files in /etc and /var belong to the right owner +# ====================================================================== +check_service_files_ownership() { + local run_service_as=$1 + local ret=0 + + if [ -z "${run_service_as}" ] + then + accnt_name=$(/usr/bin/cygrunsrv -VQ sshd | + /usr/bin/sed -ne 's/^Account *: *//gp') + if [ "${accnt_name}" = "LocalSystem" ] + then + # Convert "LocalSystem" to "SYSTEM" as is the correct account name + run_service_as="SYSTEM" + else + dom="${accnt_name%%\\*}" + accnt_name="${accnt_name#*\\}" + if [ "${dom}" = '.' ] + then + # Check local account + run_service_as=$(/usr/bin/mkpasswd -l -u "${accnt_name}" | + /usr/bin/awk -F: '{print $1;}') + else + # Check domain + run_service_as=$(/usr/bin/mkpasswd -d "${dom}" -u "${accnt_name}" | + /usr/bin/awk -F: '{print $1;}') + fi + fi + if [ -z "${run_service_as}" ] + then + csih_warning "Couldn't determine name of user running sshd service from account database!" + csih_warning "As a result, this script cannot make sure that the files used" + csih_warning "by the sshd service belong to the user running the service." + return 1 + fi + fi + for i in "${SYSCONFDIR}"/ssh_config "${SYSCONFDIR}"/sshd_config "${SYSCONFDIR}"/ssh_host_*key "${SYSCONFDIR}"/ssh_host_*key.pub + do + if [ -f "$i" ] + then + if ! chown "${run_service_as}".544 "$i" >/dev/null 2>&1 + then + csih_warning "Couldn't change owner of $i!" + let ++ret + fi + fi + done + if ! chown "${run_service_as}".544 ${LOCALSTATEDIR}/empty >/dev/null 2>&1 + then + csih_warning "Couldn't change owner of ${LOCALSTATEDIR}/empty!" + let ++ret + fi + if ! chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/lastlog >/dev/null 2>&1 + then + csih_warning "Couldn't change owner of ${LOCALSTATEDIR}/log/lastlog!" + let ++ret + fi + if [ -f ${LOCALSTATEDIR}/log/sshd.log ] + then + if ! chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/sshd.log >/dev/null 2>&1 + then + csih_warning "Couldn't change owner of ${LOCALSTATEDIR}/log/sshd.log!" + let ++ret + fi + fi + if [ $ret -ne 0 ] + then + csih_warning "Couldn't change owner of important files to ${run_service_as}!" + csih_warning "This may cause the sshd service to fail! Please make sure that" + csih_warning "you have suufficient permissions to change the ownership of files" + csih_warning "and try to run the ssh-host-config script again." + fi + return $ret +} # --- End of check_service_files_ownership --- # + +# ====================================================================== +# Routine: install_service +# Install sshd as a service +# ====================================================================== +install_service() { + local run_service_as + local password + local ret=0 + + echo + if /usr/bin/cygrunsrv -Q ${service_name} >/dev/null 2>&1 + then + csih_inform "Sshd service is already installed." + check_service_files_ownership "" || let ret+=$? + else + echo -e "${_csih_QUERY_STR} Do you want to install sshd as a service?" + if csih_request "(Say \"no\" if it is already installed as a service)" + then + csih_get_cygenv "${cygwin_value}" + + if ( csih_is_nt2003 || [ "$csih_FORCE_PRIVILEGED_USER" = "yes" ] ) + then + csih_inform "On Windows Server 2003, Windows Vista, and above, the" + csih_inform "SYSTEM account cannot setuid to other users -- a capability" + csih_inform "sshd requires. You need to have or to create a privileged" + csih_inform "account. This script will help you do so." + echo + + [ "${opt_force}" = "yes" ] && opt_f=-f + [ -n "${user_account}" ] && opt_u="-u ""${user_account}""" + csih_select_privileged_username ${opt_f} ${opt_u} sshd + + if ! csih_create_privileged_user "${password_value}" + then + csih_error_recoverable "There was a serious problem creating a privileged user." + csih_request "Do you want to proceed anyway?" || exit 1 + let ++ret + fi + fi + + # Never returns empty if NT or above + run_service_as=$(csih_service_should_run_as) + + if [ "${run_service_as}" = "${csih_PRIVILEGED_USERNAME}" ] + then + password="${csih_PRIVILEGED_PASSWORD}" + if [ -z "${password}" ] + then + csih_get_value "Please enter the password for user '${run_service_as}':" "-s" + password="${csih_value}" + fi + fi + + # At this point, we either have $run_service_as = "system" and + # $password is empty, or $run_service_as is some privileged user and + # (hopefully) $password contains the correct password. So, from here + # out, we use '-z "${password}"' to discriminate the two cases. + + csih_check_user "${run_service_as}" + + if [ -n "${csih_cygenv}" ] + then + cygwin_env=( -e "CYGWIN=${csih_cygenv}" ) + fi + if [ -z "${password}" ] + then + if /usr/bin/cygrunsrv -I ${service_name} -d "CYGWIN ${service_name}" -p /usr/sbin/sshd \ + -a "-D" -y tcpip "${cygwin_env[@]}" + then + echo + csih_inform "The sshd service has been installed under the LocalSystem" + csih_inform "account (also known as SYSTEM). To start the service now, call" + csih_inform "\`net start sshd' or \`cygrunsrv -S sshd'. Otherwise, it" + csih_inform "will start automatically after the next reboot." + fi + else + if /usr/bin/cygrunsrv -I ${service_name} -d "CYGWIN ${service_name}" -p /usr/sbin/sshd \ + -a "-D" -y tcpip "${cygwin_env[@]}" \ + -u "${run_service_as}" -w "${password}" + then + /usr/bin/editrights -u "${run_service_as}" -a SeServiceLogonRight + echo + csih_inform "The sshd service has been installed under the '${run_service_as}'" + csih_inform "account. To start the service now, call \`net start ${service_name}' or" + csih_inform "\`cygrunsrv -S ${service_name}'. Otherwise, it will start automatically" + csih_inform "after the next reboot." + fi + fi + + if /usr/bin/cygrunsrv -Q ${service_name} >/dev/null 2>&1 + then + check_service_files_ownership "${run_service_as}" || let ret+=$? + else + csih_error_recoverable "Installing sshd as a service failed!" + let ++ret + fi + fi # user allowed us to install as service + fi # service not yet installed + return $ret +} # --- End of install_service --- # + +# ====================================================================== +# Main Entry Point +# ====================================================================== + +# Check how the script has been started. If +# (1) it has been started by giving the full path and +# that path is /etc/postinstall, OR +# (2) Otherwise, if the environment variable +# SSH_HOST_CONFIG_AUTO_ANSWER_NO is set +# then set auto_answer to "no". This allows automatic +# creation of the config files in /etc w/o overwriting +# them if they already exist. In both cases, color +# escape sequences are suppressed, so as to prevent +# cluttering setup's logfiles. +if [ "$PROGDIR" = "/etc/postinstall" ] +then + csih_auto_answer="no" + csih_disable_color + opt_force=yes +fi +if [ -n "${SSH_HOST_CONFIG_AUTO_ANSWER_NO}" ] +then + csih_auto_answer="no" + csih_disable_color + opt_force=yes +fi + +# ====================================================================== +# Parse options +# ====================================================================== +while : +do + case $# in + 0) + break + ;; + esac + + option=$1 + shift + + case "${option}" in + -d | --debug ) + set -x + csih_trace_on + ;; + + -y | --yes ) + csih_auto_answer=yes + opt_force=yes + ;; + + -n | --no ) + csih_auto_answer=no + opt_force=yes + ;; + + -c | --cygwin ) + cygwin_value="$1" + shift + ;; + + -N | --name ) + service_name=$1 + shift + ;; + + -p | --port ) + port_number=$1 + shift + ;; + + -u | --user ) + user_account="$1" + shift + ;; + + -w | --pwd ) + password_value="$1" + shift + ;; + + --privileged ) + csih_FORCE_PRIVILEGED_USER=yes + ;; + + *) + echo "usage: ${progname} [OPTION]..." + echo + echo "This script creates an OpenSSH host configuration." + echo + echo "Options:" + echo " --debug -d Enable shell's debug output." + echo " --yes -y Answer all questions with \"yes\" automatically." + echo " --no -n Answer all questions with \"no\" automatically." + echo " --cygwin -c Use \"options\" as value for CYGWIN environment var." + echo " --name -N sshd windows service name." + echo " --port -p sshd listens on port n." + echo " --user -u privileged user for service, default 'cyg_server'." + echo " --pwd -w Use \"pwd\" as password for privileged user." + echo " --privileged On Windows XP, require privileged user" + echo " instead of LocalSystem for sshd service." + echo + exit 1 + ;; + + esac +done + +# ====================================================================== +# Action! +# ====================================================================== + +# Check for running ssh/sshd processes first. Refuse to do anything while +# some ssh processes are still running +if /usr/bin/ps -ef | /usr/bin/grep -q '/sshd\?$' +then + echo + csih_error "There are still ssh processes running. Please shut them down first." +fi + +# Make sure the user is running in an administrative context +admin=$(/usr/bin/id -G | /usr/bin/grep -Eq '\<544\>' && echo yes || echo no) +if [ "${admin}" != "yes" ] +then + echo + csih_warning "Running this script typically requires administrator privileges!" + csih_warning "However, it seems your account does not have these privileges." + csih_warning "Here's the list of groups in your user token:" + echo + /usr/bin/id -Gnz | xargs -0n1 echo " " + echo + csih_warning "This usually means you're running this script from a non-admin" + csih_warning "desktop session, or in a non-elevated shell under UAC control." + echo + csih_warning "Make sure you have the appropriate privileges right now," + csih_warning "otherwise parts of this script will probably fail!" + echo + echo -e "${_csih_QUERY_STR} Are you sure you want to continue? (Say \"no\" if you're not sure" + if ! csih_request "you have the required privileges)" + then + echo + csih_inform "Ok. Exiting. Make sure to switch to an administrative account" + csih_inform "or to start this script from an elevated shell." + exit 1 + fi +fi + +echo + +warning_cnt=0 + +# Create /var/log/lastlog if not already exists +if [ -e ${LOCALSTATEDIR}/log/lastlog -a ! -f ${LOCALSTATEDIR}/log/lastlog ] +then + echo + csih_error_multi "${LOCALSTATEDIR}/log/lastlog exists, but is not a file." \ + "Cannot create ssh host configuration." +fi +if [ ! -e ${LOCALSTATEDIR}/log/lastlog ] +then + /usr/bin/cat /dev/null > ${LOCALSTATEDIR}/log/lastlog + if ! /usr/bin/chmod 644 ${LOCALSTATEDIR}/log/lastlog >/dev/null 2>&1 + then + csih_warning "Can't set permissions on ${LOCALSTATEDIR}/log/lastlog!" + let ++warning_cnt + fi +fi + +# Create /var/empty file used as chroot jail for privilege separation +csih_make_dir "${LOCALSTATEDIR}/empty" "Cannot create ${LOCALSTATEDIR}/empty directory." +if ! /usr/bin/chmod 755 "${LOCALSTATEDIR}/empty" >/dev/null 2>&1 +then + csih_warning "Can't set permissions on ${LOCALSTATEDIR}/empty!" + let ++warning_cnt +fi + +# generate missing host keys +csih_inform "Generating missing SSH host keys" +/usr/bin/ssh-keygen -A || let warning_cnt+=$? + +# handle ssh_config +csih_install_config "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults" || let ++warning_cnt +if /usr/bin/cmp "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/ssh_config" >/dev/null 2>&1 +then + if [ "${port_number}" != "22" ] + then + csih_inform "Updating ${SYSCONFDIR}/ssh_config file with requested port" + echo "Host localhost" >> ${SYSCONFDIR}/ssh_config + echo " Port ${port_number}" >> ${SYSCONFDIR}/ssh_config + fi +fi + +# handle sshd_config (and privsep) +csih_install_config "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults" || let ++warning_cnt +if ! /usr/bin/cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1 +then + sshd_config_configured=yes +fi +sshd_strictmodes || let warning_cnt+=$? +sshd_privsep || let warning_cnt+=$? +sshd_config_tweak || let warning_cnt+=$? +update_services_file || let warning_cnt+=$? +update_inetd_conf || let warning_cnt+=$? +install_service || let warning_cnt+=$? + +echo +if [ $warning_cnt -eq 0 ] +then + csih_inform "Host configuration finished. Have fun!" +else + csih_warning "Host configuration exited with ${warning_cnt} errors or warnings!" + csih_warning "Make sure that all problems reported are fixed," + csih_warning "then re-run ssh-host-config." +fi +exit $warning_cnt diff --git a/crypto/external/bsd/openssh/dist/contrib/cygwin/ssh-user-config b/crypto/external/bsd/openssh/dist/contrib/cygwin/ssh-user-config new file mode 100644 index 000000000..33dc0cbea --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/cygwin/ssh-user-config @@ -0,0 +1,257 @@ +#!/bin/bash +# +# ssh-user-config, Copyright 2000-2014 Red Hat Inc. +# +# This file is part of the Cygwin port of OpenSSH. +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR +# THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +# ====================================================================== +# Initialization +# ====================================================================== +PROGNAME=$(basename -- $0) +_tdir=$(dirname -- $0) +PROGDIR=$(cd $_tdir && pwd) + +CSIH_SCRIPT=/usr/share/csih/cygwin-service-installation-helper.sh + +# Subdirectory where the new package is being installed +PREFIX=/usr + +# Directory where the config files are stored +SYSCONFDIR=/etc + +source ${CSIH_SCRIPT} + +auto_passphrase="no" +passphrase="" +pwdhome= +with_passphrase= + +# ====================================================================== +# Routine: create_identity +# optionally create identity of type argument in ~/.ssh +# optionally add result to ~/.ssh/authorized_keys +# ====================================================================== +create_identity() { + local file="$1" + local type="$2" + local name="$3" + if [ ! -f "${pwdhome}/.ssh/${file}" ] + then + if csih_request "Shall I create a ${name} identity file for you?" + then + csih_inform "Generating ${pwdhome}/.ssh/${file}" + if [ "${with_passphrase}" = "yes" ] + then + ssh-keygen -t "${type}" -N "${passphrase}" -f "${pwdhome}/.ssh/${file}" > /dev/null + else + ssh-keygen -t "${type}" -f "${pwdhome}/.ssh/${file}" > /dev/null + fi + if csih_request "Do you want to use this identity to login to this machine?" + then + csih_inform "Adding to ${pwdhome}/.ssh/authorized_keys" + cat "${pwdhome}/.ssh/${file}.pub" >> "${pwdhome}/.ssh/authorized_keys" + fi + fi + fi +} # === End of create_ssh1_identity() === # +readonly -f create_identity + +# ====================================================================== +# Routine: check_user_homedir +# Perform various checks on the user's home directory +# SETS GLOBAL VARIABLE: +# pwdhome +# ====================================================================== +check_user_homedir() { + pwdhome=$(getent passwd $UID | awk -F: '{ print $6; }') + if [ "X${pwdhome}" = "X" ] + then + csih_error_multi \ + "There is no home directory set for you in the account database." \ + 'Setting $HOME is not sufficient!' + fi + + if [ ! -d "${pwdhome}" ] + then + csih_error_multi \ + "${pwdhome} is set in the account database as your home directory" \ + 'but it is not a valid directory. Cannot create user identity files.' + fi + + # If home is the root dir, set home to empty string to avoid error messages + # in subsequent parts of that script. + if [ "X${pwdhome}" = "X/" ] + then + # But first raise a warning! + csih_warning "Your home directory in the account database is set to root (/). This is not recommended!" + if csih_request "Would you like to proceed anyway?" + then + pwdhome='' + else + csih_warning "Exiting. Configuration is not complete" + exit 1 + fi + fi + + if [ -d "${pwdhome}" -a -n "`chmod -c g-w,o-w "${pwdhome}"`" ] + then + echo + csih_warning 'group and other have been revoked write permission to your home' + csih_warning "directory ${pwdhome}." + csih_warning 'This is required by OpenSSH to allow public key authentication using' + csih_warning 'the key files stored in your .ssh subdirectory.' + csih_warning 'Revert this change ONLY if you know what you are doing!' + echo + fi +} # === End of check_user_homedir() === # +readonly -f check_user_homedir + +# ====================================================================== +# Routine: check_user_dot_ssh_dir +# Perform various checks on the ~/.ssh directory +# PREREQUISITE: +# pwdhome -- check_user_homedir() +# ====================================================================== +check_user_dot_ssh_dir() { + if [ -e "${pwdhome}/.ssh" -a ! -d "${pwdhome}/.ssh" ] + then + csih_error "${pwdhome}/.ssh is existant but not a directory. Cannot create user identity files." + fi + + if [ ! -e "${pwdhome}/.ssh" ] + then + mkdir "${pwdhome}/.ssh" + if [ ! -e "${pwdhome}/.ssh" ] + then + csih_error "Creating users ${pwdhome}/.ssh directory failed" + fi + fi +} # === End of check_user_dot_ssh_dir() === # +readonly -f check_user_dot_ssh_dir + +# ====================================================================== +# Routine: fix_authorized_keys_perms +# Corrects the permissions of ~/.ssh/authorized_keys +# PREREQUISITE: +# pwdhome -- check_user_homedir() +# ====================================================================== +fix_authorized_keys_perms() { + if [ -e "${pwdhome}/.ssh/authorized_keys" ] + then + setfacl -b "${pwdhome}/.ssh/authorized_keys" 2>/dev/null || echo -n + if ! chmod u-x,g-wx,o-wx "${pwdhome}/.ssh/authorized_keys" + then + csih_warning "Setting correct permissions to ${pwdhome}/.ssh/authorized_keys" + csih_warning "failed. Please care for the correct permissions. The minimum requirement" + csih_warning "is, the owner needs read permissions." + echo + fi + fi +} # === End of fix_authorized_keys_perms() === # +readonly -f fix_authorized_keys_perms + + +# ====================================================================== +# Main Entry Point +# ====================================================================== + +# Check how the script has been started. If +# (1) it has been started by giving the full path and +# that path is /etc/postinstall, OR +# (2) Otherwise, if the environment variable +# SSH_USER_CONFIG_AUTO_ANSWER_NO is set +# then set auto_answer to "no". This allows automatic +# creation of the config files in /etc w/o overwriting +# them if they already exist. In both cases, color +# escape sequences are suppressed, so as to prevent +# cluttering setup's logfiles. +if [ "$PROGDIR" = "/etc/postinstall" ] +then + csih_auto_answer="no" + csih_disable_color +fi +if [ -n "${SSH_USER_CONFIG_AUTO_ANSWER_NO}" ] +then + csih_auto_answer="no" + csih_disable_color +fi + +# ====================================================================== +# Parse options +# ====================================================================== +while : +do + case $# in + 0) + break + ;; + esac + + option=$1 + shift + + case "$option" in + -d | --debug ) + set -x + csih_trace_on + ;; + + -y | --yes ) + csih_auto_answer=yes + ;; + + -n | --no ) + csih_auto_answer=no + ;; + + -p | --passphrase ) + with_passphrase="yes" + passphrase=$1 + shift + ;; + + *) + echo "usage: ${PROGNAME} [OPTION]..." + echo + echo "This script creates an OpenSSH user configuration." + echo + echo "Options:" + echo " --debug -d Enable shell's debug output." + echo " --yes -y Answer all questions with \"yes\" automatically." + echo " --no -n Answer all questions with \"no\" automatically." + echo " --passphrase -p word Use \"word\" as passphrase automatically." + echo + exit 1 + ;; + + esac +done + +# ====================================================================== +# Action! +# ====================================================================== + +check_user_homedir +check_user_dot_ssh_dir +create_identity id_rsa rsa "SSH2 RSA" +create_identity id_dsa dsa "SSH2 DSA" +create_identity id_ecdsa ecdsa "SSH2 ECDSA" +create_identity identity rsa1 "(deprecated) SSH1 RSA" +fix_authorized_keys_perms + +echo +csih_inform "Configuration finished. Have fun!" + + diff --git a/crypto/external/bsd/openssh/dist/contrib/cygwin/sshd-inetd b/crypto/external/bsd/openssh/dist/contrib/cygwin/sshd-inetd new file mode 100644 index 000000000..aa6bf073f --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/cygwin/sshd-inetd @@ -0,0 +1,4 @@ +# This file can be used to enable sshd as a slave of the inetd service +# To do so, the line below should be uncommented. +@COMMENT@ ssh stream tcp nowait root /usr/sbin/sshd sshd -i + diff --git a/crypto/external/bsd/openssh/dist/contrib/findssl.sh b/crypto/external/bsd/openssh/dist/contrib/findssl.sh new file mode 100644 index 000000000..263fd2644 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/findssl.sh @@ -0,0 +1,186 @@ +#!/bin/sh +# +# $Id: findssl.sh,v 1.4 2007/02/19 11:44:25 dtucker Exp $ +# +# findssl.sh +# Search for all instances of OpenSSL headers and libraries +# and print their versions. +# Intended to help diagnose OpenSSH's "OpenSSL headers do not +# match your library" errors. +# +# Written by Darren Tucker (dtucker at zip dot com dot au) +# This file is placed in the public domain. +# +# Release history: +# 2002-07-27: Initial release. +# 2002-08-04: Added public domain notice. +# 2003-06-24: Incorporated readme, set library paths. First cvs version. +# 2004-12-13: Add traps to cleanup temp files, from Amarendra Godbole. +# +# "OpenSSL headers do not match your library" are usually caused by +# OpenSSH's configure picking up an older version of OpenSSL headers +# or libraries. You can use the following # procedure to help identify +# the cause. +# +# The output of configure will tell you the versions of the OpenSSL +# headers and libraries that were picked up, for example: +# +# checking OpenSSL header version... 90604f (OpenSSL 0.9.6d 9 May 2002) +# checking OpenSSL library version... 90602f (OpenSSL 0.9.6b [engine] 9 Jul 2001) +# checking whether OpenSSL's headers match the library... no +# configure: error: Your OpenSSL headers do not match your library +# +# Now run findssl.sh. This should identify the headers and libraries +# present and their versions. You should be able to identify the +# libraries and headers used and adjust your CFLAGS or remove incorrect +# versions. The output will show OpenSSL's internal version identifier +# and should look something like: + +# $ ./findssl.sh +# Searching for OpenSSL header files. +# 0x0090604fL /usr/include/openssl/opensslv.h +# 0x0090604fL /usr/local/ssl/include/openssl/opensslv.h +# +# Searching for OpenSSL shared library files. +# 0x0090602fL /lib/libcrypto.so.0.9.6b +# 0x0090602fL /lib/libcrypto.so.2 +# 0x0090581fL /usr/lib/libcrypto.so.0 +# 0x0090602fL /usr/lib/libcrypto.so +# 0x0090581fL /usr/lib/libcrypto.so.0.9.5a +# 0x0090600fL /usr/lib/libcrypto.so.0.9.6 +# 0x0090600fL /usr/lib/libcrypto.so.1 +# +# Searching for OpenSSL static library files. +# 0x0090602fL /usr/lib/libcrypto.a +# 0x0090604fL /usr/local/ssl/lib/libcrypto.a +# +# In this example, I gave configure no extra flags, so it's picking up +# the OpenSSL header from /usr/include/openssl (90604f) and the library +# from /usr/lib/ (90602f). + +# +# Adjust these to suit your compiler. +# You may also need to set the *LIB*PATH environment variables if +# DEFAULT_LIBPATH is not correct for your system. +# +CC=gcc +STATIC=-static + +# +# Cleanup on interrupt +# +trap 'rm -f conftest.c' INT HUP TERM + +# +# Set up conftest C source +# +rm -f findssl.log +cat >conftest.c < +int main(){printf("0x%08xL\n", SSLeay());} +EOD + +# +# Set default library paths if not already set +# +DEFAULT_LIBPATH=/usr/lib:/usr/local/lib +LIBPATH=${LIBPATH:=$DEFAULT_LIBPATH} +LD_LIBRARY_PATH=${LD_LIBRARY_PATH:=$DEFAULT_LIBPATH} +LIBRARY_PATH=${LIBRARY_PATH:=$DEFAULT_LIBPATH} +export LIBPATH LD_LIBRARY_PATH LIBRARY_PATH + +# not all platforms have a 'which' command +if which ls >/dev/null 2>/dev/null; then + : which is defined +else + which () { + saveIFS="$IFS" + IFS=: + for p in $PATH; do + if test -x "$p/$1" -a -f "$p/$1"; then + IFS="$saveIFS" + echo "$p/$1" + return 0 + fi + done + IFS="$saveIFS" + return 1 + } +fi + +# +# Search for OpenSSL headers and print versions +# +echo Searching for OpenSSL header files. +if [ -x "`which locate`" ] +then + headers=`locate opensslv.h` +else + headers=`find / -name opensslv.h -print 2>/dev/null` +fi + +for header in $headers +do + ver=`awk '/OPENSSL_VERSION_NUMBER/{printf \$3}' $header` + echo "$ver $header" +done +echo + +# +# Search for shared libraries. +# Relies on shared libraries looking like "libcrypto.s*" +# +echo Searching for OpenSSL shared library files. +if [ -x "`which locate`" ] +then + libraries=`locate libcrypto.s` +else + libraries=`find / -name 'libcrypto.s*' -print 2>/dev/null` +fi + +for lib in $libraries +do + (echo "Trying libcrypto $lib" >>findssl.log + dir=`dirname $lib` + LIBPATH="$dir:$LIBPATH" + LD_LIBRARY_PATH="$dir:$LIBPATH" + LIBRARY_PATH="$dir:$LIBPATH" + export LIBPATH LD_LIBRARY_PATH LIBRARY_PATH + ${CC} -o conftest conftest.c $lib 2>>findssl.log + if [ -x ./conftest ] + then + ver=`./conftest 2>/dev/null` + rm -f ./conftest + echo "$ver $lib" + fi) +done +echo + +# +# Search for static OpenSSL libraries and print versions +# +echo Searching for OpenSSL static library files. +if [ -x "`which locate`" ] +then + libraries=`locate libcrypto.a` +else + libraries=`find / -name libcrypto.a -print 2>/dev/null` +fi + +for lib in $libraries +do + libdir=`dirname $lib` + echo "Trying libcrypto $lib" >>findssl.log + ${CC} ${STATIC} -o conftest conftest.c -L${libdir} -lcrypto 2>>findssl.log + if [ -x ./conftest ] + then + ver=`./conftest 2>/dev/null` + rm -f ./conftest + echo "$ver $lib" + fi +done + +# +# Clean up +# +rm -f conftest.c diff --git a/crypto/external/bsd/openssh/dist/contrib/gnome-ssh-askpass1.c b/crypto/external/bsd/openssh/dist/contrib/gnome-ssh-askpass1.c new file mode 100644 index 000000000..4d51032d1 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/gnome-ssh-askpass1.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2000-2002 Damien Miller. 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. + */ + +/* + * This is a simple GNOME SSH passphrase grabber. To use it, set the + * environment variable SSH_ASKPASS to point to the location of + * gnome-ssh-askpass before calling "ssh-add < /dev/null". + * + * There is only two run-time options: if you set the environment variable + * "GNOME_SSH_ASKPASS_GRAB_SERVER=true" then gnome-ssh-askpass will grab + * the X server. If you set "GNOME_SSH_ASKPASS_GRAB_POINTER=true", then the + * pointer will be grabbed too. These may have some benefit to security if + * you don't trust your X server. We grab the keyboard always. + */ + +/* + * Compile with: + * + * cc `gnome-config --cflags gnome gnomeui` \ + * gnome-ssh-askpass1.c -o gnome-ssh-askpass \ + * `gnome-config --libs gnome gnomeui` + * + */ + +#include +#include +#include +#include +#include +#include + +void +report_failed_grab (void) +{ + GtkWidget *err; + + err = gnome_message_box_new("Could not grab keyboard or mouse.\n" + "A malicious client may be eavesdropping on your session.", + GNOME_MESSAGE_BOX_ERROR, "EXIT", NULL); + gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER); + gtk_object_set(GTK_OBJECT(err), "type", GTK_WINDOW_POPUP, NULL); + + gnome_dialog_run_and_close(GNOME_DIALOG(err)); +} + +int +passphrase_dialog(char *message) +{ + char *passphrase; + char **messages; + int result, i, grab_server, grab_pointer; + GtkWidget *dialog, *entry, *label; + + grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL); + grab_pointer = (getenv("GNOME_SSH_ASKPASS_GRAB_POINTER") != NULL); + + dialog = gnome_dialog_new("OpenSSH", GNOME_STOCK_BUTTON_OK, + GNOME_STOCK_BUTTON_CANCEL, NULL); + + messages = g_strsplit(message, "\\n", 0); + if (messages) + for(i = 0; messages[i]; i++) { + label = gtk_label_new(messages[i]); + gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), + label, FALSE, FALSE, 0); + } + + entry = gtk_entry_new(); + gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), entry, FALSE, + FALSE, 0); + gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); + gtk_widget_grab_focus(entry); + + /* Center window and prepare for grab */ + gtk_object_set(GTK_OBJECT(dialog), "type", GTK_WINDOW_POPUP, NULL); + gnome_dialog_set_default(GNOME_DIALOG(dialog), 0); + gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); + gtk_window_set_policy(GTK_WINDOW(dialog), FALSE, FALSE, TRUE); + gnome_dialog_close_hides(GNOME_DIALOG(dialog), TRUE); + gtk_container_set_border_width(GTK_CONTAINER(GNOME_DIALOG(dialog)->vbox), + GNOME_PAD); + gtk_widget_show_all(dialog); + + /* Grab focus */ + if (grab_server) + XGrabServer(GDK_DISPLAY()); + if (grab_pointer && gdk_pointer_grab(dialog->window, TRUE, 0, + NULL, NULL, GDK_CURRENT_TIME)) + goto nograb; + if (gdk_keyboard_grab(dialog->window, FALSE, GDK_CURRENT_TIME)) + goto nograbkb; + + /* Make close dialog */ + gnome_dialog_editable_enters(GNOME_DIALOG(dialog), GTK_EDITABLE(entry)); + + /* Run dialog */ + result = gnome_dialog_run(GNOME_DIALOG(dialog)); + + /* Ungrab */ + if (grab_server) + XUngrabServer(GDK_DISPLAY()); + if (grab_pointer) + gdk_pointer_ungrab(GDK_CURRENT_TIME); + gdk_keyboard_ungrab(GDK_CURRENT_TIME); + gdk_flush(); + + /* Report passphrase if user selected OK */ + passphrase = gtk_entry_get_text(GTK_ENTRY(entry)); + if (result == 0) + puts(passphrase); + + /* Zero passphrase in memory */ + memset(passphrase, '\0', strlen(passphrase)); + gtk_entry_set_text(GTK_ENTRY(entry), passphrase); + + gnome_dialog_close(GNOME_DIALOG(dialog)); + return (result == 0 ? 0 : -1); + + /* At least one grab failed - ungrab what we got, and report + the failure to the user. Note that XGrabServer() cannot + fail. */ + nograbkb: + gdk_pointer_ungrab(GDK_CURRENT_TIME); + nograb: + if (grab_server) + XUngrabServer(GDK_DISPLAY()); + gnome_dialog_close(GNOME_DIALOG(dialog)); + + report_failed_grab(); + return (-1); +} + +int +main(int argc, char **argv) +{ + char *message; + int result; + + gnome_init("GNOME ssh-askpass", "0.1", argc, argv); + + if (argc == 2) + message = argv[1]; + else + message = "Enter your OpenSSH passphrase:"; + + setvbuf(stdout, 0, _IONBF, 0); + result = passphrase_dialog(message); + + return (result); +} diff --git a/crypto/external/bsd/openssh/dist/contrib/gnome-ssh-askpass2.c b/crypto/external/bsd/openssh/dist/contrib/gnome-ssh-askpass2.c new file mode 100644 index 000000000..9d97c30c0 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/gnome-ssh-askpass2.c @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2000-2002 Damien Miller. 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. + */ + +/* GTK2 support by Nalin Dahyabhai */ + +/* + * This is a simple GNOME SSH passphrase grabber. To use it, set the + * environment variable SSH_ASKPASS to point to the location of + * gnome-ssh-askpass before calling "ssh-add < /dev/null". + * + * There is only two run-time options: if you set the environment variable + * "GNOME_SSH_ASKPASS_GRAB_SERVER=true" then gnome-ssh-askpass will grab + * the X server. If you set "GNOME_SSH_ASKPASS_GRAB_POINTER=true", then the + * pointer will be grabbed too. These may have some benefit to security if + * you don't trust your X server. We grab the keyboard always. + */ + +#define GRAB_TRIES 16 +#define GRAB_WAIT 250 /* milliseconds */ + +/* + * Compile with: + * + * cc -Wall `pkg-config --cflags gtk+-2.0` \ + * gnome-ssh-askpass2.c -o gnome-ssh-askpass \ + * `pkg-config --libs gtk+-2.0` + * + */ + +#include +#include +#include +#include +#include +#include +#include + +static void +report_failed_grab (const char *what) +{ + GtkWidget *err; + + err = gtk_message_dialog_new(NULL, 0, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "Could not grab %s. " + "A malicious client may be eavesdropping " + "on your session.", what); + gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER); + gtk_label_set_line_wrap(GTK_LABEL((GTK_MESSAGE_DIALOG(err))->label), + TRUE); + + gtk_dialog_run(GTK_DIALOG(err)); + + gtk_widget_destroy(err); +} + +static void +ok_dialog(GtkWidget *entry, gpointer dialog) +{ + g_return_if_fail(GTK_IS_DIALOG(dialog)); + gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); +} + +static int +passphrase_dialog(char *message) +{ + const char *failed; + char *passphrase, *local; + int result, grab_tries, grab_server, grab_pointer; + GtkWidget *dialog, *entry; + GdkGrabStatus status; + + grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL); + grab_pointer = (getenv("GNOME_SSH_ASKPASS_GRAB_POINTER") != NULL); + grab_tries = 0; + + dialog = gtk_message_dialog_new(NULL, 0, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_OK_CANCEL, + "%s", + message); + + entry = gtk_entry_new(); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), entry, FALSE, + FALSE, 0); + gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); + gtk_widget_grab_focus(entry); + gtk_widget_show(entry); + + gtk_window_set_title(GTK_WINDOW(dialog), "OpenSSH"); + gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); + gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); + gtk_label_set_line_wrap(GTK_LABEL((GTK_MESSAGE_DIALOG(dialog))->label), + TRUE); + + /* Make close dialog */ + gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); + g_signal_connect(G_OBJECT(entry), "activate", + G_CALLBACK(ok_dialog), dialog); + + gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); + + /* Grab focus */ + gtk_widget_show_now(dialog); + if (grab_pointer) { + for(;;) { + status = gdk_pointer_grab( + (GTK_WIDGET(dialog))->window, TRUE, 0, NULL, + NULL, GDK_CURRENT_TIME); + if (status == GDK_GRAB_SUCCESS) + break; + usleep(GRAB_WAIT * 1000); + if (++grab_tries > GRAB_TRIES) { + failed = "mouse"; + goto nograb; + } + } + } + for(;;) { + status = gdk_keyboard_grab((GTK_WIDGET(dialog))->window, + FALSE, GDK_CURRENT_TIME); + if (status == GDK_GRAB_SUCCESS) + break; + usleep(GRAB_WAIT * 1000); + if (++grab_tries > GRAB_TRIES) { + failed = "keyboard"; + goto nograbkb; + } + } + if (grab_server) { + gdk_x11_grab_server(); + } + + result = gtk_dialog_run(GTK_DIALOG(dialog)); + + /* Ungrab */ + if (grab_server) + XUngrabServer(GDK_DISPLAY()); + if (grab_pointer) + gdk_pointer_ungrab(GDK_CURRENT_TIME); + gdk_keyboard_ungrab(GDK_CURRENT_TIME); + gdk_flush(); + + /* Report passphrase if user selected OK */ + passphrase = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry))); + if (result == GTK_RESPONSE_OK) { + local = g_locale_from_utf8(passphrase, strlen(passphrase), + NULL, NULL, NULL); + if (local != NULL) { + puts(local); + memset(local, '\0', strlen(local)); + g_free(local); + } else { + puts(passphrase); + } + } + + /* Zero passphrase in memory */ + memset(passphrase, '\b', strlen(passphrase)); + gtk_entry_set_text(GTK_ENTRY(entry), passphrase); + memset(passphrase, '\0', strlen(passphrase)); + g_free(passphrase); + + gtk_widget_destroy(dialog); + return (result == GTK_RESPONSE_OK ? 0 : -1); + + /* At least one grab failed - ungrab what we got, and report + the failure to the user. Note that XGrabServer() cannot + fail. */ + nograbkb: + gdk_pointer_ungrab(GDK_CURRENT_TIME); + nograb: + if (grab_server) + XUngrabServer(GDK_DISPLAY()); + gtk_widget_destroy(dialog); + + report_failed_grab(failed); + + return (-1); +} + +int +main(int argc, char **argv) +{ + char *message; + int result; + + gtk_init(&argc, &argv); + + if (argc > 1) { + message = g_strjoinv(" ", argv + 1); + } else { + message = g_strdup("Enter your OpenSSH passphrase:"); + } + + setvbuf(stdout, 0, _IONBF, 0); + result = passphrase_dialog(message); + g_free(message); + + return (result); +} diff --git a/crypto/external/bsd/openssh/dist/contrib/hpux/README b/crypto/external/bsd/openssh/dist/contrib/hpux/README new file mode 100644 index 000000000..f8bfa84e4 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/hpux/README @@ -0,0 +1,45 @@ +README for OpenSSH HP-UX contrib files +Kevin Steves + +sshd: configuration file for sshd.rc +sshd.rc: SSH startup script +egd: configuration file for egd.rc +egd.rc: EGD (entropy gathering daemon) startup script + +To install: + +sshd.rc: + +o Verify paths in sshd.rc match your local installation + (WHAT_PATH and WHAT_PID) +o Customize sshd if needed (SSHD_ARGS) +o Install: + + # cp sshd /etc/rc.config.d + # chmod 444 /etc/rc.config.d/sshd + # cp sshd.rc /sbin/init.d + # chmod 555 /sbin/init.d/sshd.rc + # ln -s /sbin/init.d/sshd.rc /sbin/rc1.d/K100sshd + # ln -s /sbin/init.d/sshd.rc /sbin/rc2.d/S900sshd + +egd.rc: + +o Verify egd.pl path in egd.rc matches your local installation + (WHAT_PATH) +o Customize egd if needed (EGD_ARGS and EGD_LOG) +o Add pseudo account: + + # groupadd egd + # useradd -g egd egd + # mkdir -p /etc/opt/egd + # chown egd:egd /etc/opt/egd + # chmod 711 /etc/opt/egd + +o Install: + + # cp egd /etc/rc.config.d + # chmod 444 /etc/rc.config.d/egd + # cp egd.rc /sbin/init.d + # chmod 555 /sbin/init.d/egd.rc + # ln -s /sbin/init.d/egd.rc /sbin/rc1.d/K600egd + # ln -s /sbin/init.d/egd.rc /sbin/rc2.d/S400egd diff --git a/crypto/external/bsd/openssh/dist/contrib/hpux/egd b/crypto/external/bsd/openssh/dist/contrib/hpux/egd new file mode 100644 index 000000000..21af0bd13 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/hpux/egd @@ -0,0 +1,15 @@ +# EGD_START: Set to 1 to start entropy gathering daemon +# EGD_ARGS: Command line arguments to pass to egd +# EGD_LOG: EGD stdout and stderr log file (default /etc/opt/egd/egd.log) +# +# To configure the egd environment: + +# groupadd egd +# useradd -g egd egd +# mkdir -p /etc/opt/egd +# chown egd:egd /etc/opt/egd +# chmod 711 /etc/opt/egd + +EGD_START=1 +EGD_ARGS='/etc/opt/egd/entropy' +EGD_LOG= diff --git a/crypto/external/bsd/openssh/dist/contrib/hpux/egd.rc b/crypto/external/bsd/openssh/dist/contrib/hpux/egd.rc new file mode 100755 index 000000000..919dea725 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/hpux/egd.rc @@ -0,0 +1,98 @@ +#!/sbin/sh + +# +# egd.rc: EGD start-up and shutdown script +# + +# Allowed exit values: +# 0 = success; causes "OK" to show up in checklist. +# 1 = failure; causes "FAIL" to show up in checklist. +# 2 = skip; causes "N/A" to show up in the checklist. +# Use this value if execution of this script is overridden +# by the use of a control variable, or if this script is not +# appropriate to execute for some other reason. +# 3 = reboot; causes the system to be rebooted after execution. + +# Input and output: +# stdin is redirected from /dev/null +# +# stdout and stderr are redirected to the /etc/rc.log file +# during checklist mode, or to the console in raw mode. + +umask 022 + +PATH=/usr/sbin:/usr/bin:/sbin +export PATH + +WHAT='EGD (entropy gathering daemon)' +WHAT_PATH=/opt/perl/bin/egd.pl +WHAT_CONFIG=/etc/rc.config.d/egd +WHAT_LOG=/etc/opt/egd/egd.log + +# NOTE: If your script executes in run state 0 or state 1, then /usr might +# not be available. Do not attempt to access commands or files in +# /usr unless your script executes in run state 2 or greater. Other +# file systems typically not mounted until run state 2 include /var +# and /opt. + +rval=0 + +# Check the exit value of a command run by this script. If non-zero, the +# exit code is echoed to the log file and the return value of this script +# is set to indicate failure. + +set_return() { + x=$? + if [ $x -ne 0 ]; then + echo "EXIT CODE: $x" + rval=1 # script FAILed + fi +} + +case $1 in +'start_msg') + echo "Starting $WHAT" + ;; + +'stop_msg') + echo "Stopping $WHAT" + ;; + +'start') + if [ -f $WHAT_CONFIG ] ; then + . $WHAT_CONFIG + else + echo "ERROR: $WHAT_CONFIG defaults file MISSING" + fi + + + if [ "$EGD_START" -eq 1 -a -x $WHAT_PATH ]; then + EGD_LOG=${EGD_LOG:-$WHAT_LOG} + su egd -c "nohup $WHAT_PATH $EGD_ARGS >$EGD_LOG 2>&1" && + echo $WHAT started + set_return + else + rval=2 + fi + ;; + +'stop') + pid=`ps -fuegd | awk '$1 == "egd" { print $2 }'` + if [ "X$pid" != "X" ]; then + if kill "$pid"; then + echo "$WHAT stopped" + else + rval=1 + echo "Unable to stop $WHAT" + fi + fi + set_return + ;; + +*) + echo "usage: $0 {start|stop|start_msg|stop_msg}" + rval=1 + ;; +esac + +exit $rval diff --git a/crypto/external/bsd/openssh/dist/contrib/hpux/sshd b/crypto/external/bsd/openssh/dist/contrib/hpux/sshd new file mode 100644 index 000000000..8eb5e92a3 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/hpux/sshd @@ -0,0 +1,5 @@ +# SSHD_START: Set to 1 to start SSH daemon +# SSHD_ARGS: Command line arguments to pass to sshd +# +SSHD_START=1 +SSHD_ARGS= diff --git a/crypto/external/bsd/openssh/dist/contrib/hpux/sshd.rc b/crypto/external/bsd/openssh/dist/contrib/hpux/sshd.rc new file mode 100755 index 000000000..f9a10999b --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/hpux/sshd.rc @@ -0,0 +1,90 @@ +#!/sbin/sh + +# +# sshd.rc: SSH daemon start-up and shutdown script +# + +# Allowed exit values: +# 0 = success; causes "OK" to show up in checklist. +# 1 = failure; causes "FAIL" to show up in checklist. +# 2 = skip; causes "N/A" to show up in the checklist. +# Use this value if execution of this script is overridden +# by the use of a control variable, or if this script is not +# appropriate to execute for some other reason. +# 3 = reboot; causes the system to be rebooted after execution. + +# Input and output: +# stdin is redirected from /dev/null +# +# stdout and stderr are redirected to the /etc/rc.log file +# during checklist mode, or to the console in raw mode. + +PATH=/usr/sbin:/usr/bin:/sbin +export PATH + +WHAT='OpenSSH' +WHAT_PATH=/opt/openssh/sbin/sshd +WHAT_PID=/var/run/sshd.pid +WHAT_CONFIG=/etc/rc.config.d/sshd + +# NOTE: If your script executes in run state 0 or state 1, then /usr might +# not be available. Do not attempt to access commands or files in +# /usr unless your script executes in run state 2 or greater. Other +# file systems typically not mounted until run state 2 include /var +# and /opt. + +rval=0 + +# Check the exit value of a command run by this script. If non-zero, the +# exit code is echoed to the log file and the return value of this script +# is set to indicate failure. + +set_return() { + x=$? + if [ $x -ne 0 ]; then + echo "EXIT CODE: $x" + rval=1 # script FAILed + fi +} + +case $1 in +'start_msg') + echo "Starting $WHAT" + ;; + +'stop_msg') + echo "Stopping $WHAT" + ;; + +'start') + if [ -f $WHAT_CONFIG ] ; then + . $WHAT_CONFIG + else + echo "ERROR: $WHAT_CONFIG defaults file MISSING" + fi + + if [ "$SSHD_START" -eq 1 -a -x "$WHAT_PATH" ]; then + $WHAT_PATH $SSHD_ARGS && echo "$WHAT started" + set_return + else + rval=2 + fi + ;; + +'stop') + if kill `cat $WHAT_PID`; then + echo "$WHAT stopped" + else + rval=1 + echo "Unable to stop $WHAT" + fi + set_return + ;; + +*) + echo "usage: $0 {start|stop|start_msg|stop_msg}" + rval=1 + ;; +esac + +exit $rval diff --git a/crypto/external/bsd/openssh/dist/contrib/redhat/gnome-ssh-askpass.csh b/crypto/external/bsd/openssh/dist/contrib/redhat/gnome-ssh-askpass.csh new file mode 100644 index 000000000..dd77712cd --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/redhat/gnome-ssh-askpass.csh @@ -0,0 +1 @@ +setenv SSH_ASKPASS /usr/libexec/openssh/gnome-ssh-askpass diff --git a/crypto/external/bsd/openssh/dist/contrib/redhat/gnome-ssh-askpass.sh b/crypto/external/bsd/openssh/dist/contrib/redhat/gnome-ssh-askpass.sh new file mode 100644 index 000000000..355189f45 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/redhat/gnome-ssh-askpass.sh @@ -0,0 +1,2 @@ +SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass +export SSH_ASKPASS diff --git a/crypto/external/bsd/openssh/dist/contrib/redhat/openssh.spec b/crypto/external/bsd/openssh/dist/contrib/redhat/openssh.spec new file mode 100644 index 000000000..5b27106fb --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/redhat/openssh.spec @@ -0,0 +1,811 @@ +%define ver 7.1p1 +%define rel 1 + +# OpenSSH privilege separation requires a user & group ID +%define sshd_uid 74 +%define sshd_gid 74 + +# Version of ssh-askpass +%define aversion 1.2.4.1 + +# Do we want to disable building of x11-askpass? (1=yes 0=no) +%define no_x11_askpass 0 + +# Do we want to disable building of gnome-askpass? (1=yes 0=no) +%define no_gnome_askpass 0 + +# Do we want to link against a static libcrypto? (1=yes 0=no) +%define static_libcrypto 0 + +# Do we want smartcard support (1=yes 0=no) +%define scard 0 + +# Use GTK2 instead of GNOME in gnome-ssh-askpass +%define gtk2 1 + +# Is this build for RHL 6.x? +%define build6x 0 + +# Do we want kerberos5 support (1=yes 0=no) +%define kerberos5 1 + +# Reserve options to override askpass settings with: +# rpm -ba|--rebuild --define 'skip_xxx 1' +%{?skip_x11_askpass:%define no_x11_askpass 1} +%{?skip_gnome_askpass:%define no_gnome_askpass 1} + +# Add option to build without GTK2 for older platforms with only GTK+. +# RedHat <= 7.2 and Red Hat Advanced Server 2.1 are examples. +# rpm -ba|--rebuild --define 'no_gtk2 1' +%{?no_gtk2:%define gtk2 0} + +# Is this a build for RHL 6.x or earlier? +%{?build_6x:%define build6x 1} + +# If this is RHL 6.x, the default configuration has sysconfdir in /usr/etc. +%if %{build6x} +%define _sysconfdir /etc +%endif + +# Options for static OpenSSL link: +# rpm -ba|--rebuild --define "static_openssl 1" +%{?static_openssl:%define static_libcrypto 1} + +# Options for Smartcard support: (needs libsectok and openssl-engine) +# rpm -ba|--rebuild --define "smartcard 1" +%{?smartcard:%define scard 1} + +# Is this a build for the rescue CD (without PAM, with MD5)? (1=yes 0=no) +%define rescue 0 +%{?build_rescue:%define rescue 1} + +# Turn off some stuff for resuce builds +%if %{rescue} +%define kerberos5 0 +%endif + +Summary: The OpenSSH implementation of SSH protocol versions 1 and 2. +Name: openssh +Version: %{ver} +%if %{rescue} +Release: %{rel}rescue +%else +Release: %{rel} +%endif +URL: http://www.openssh.com/portable.html +Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz +%if ! %{no_x11_askpass} +Source1: http://www.jmknoble.net/software/x11-ssh-askpass/x11-ssh-askpass-%{aversion}.tar.gz +%endif +License: BSD +Group: Applications/Internet +BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot +Obsoletes: ssh +%if %{build6x} +PreReq: initscripts >= 5.00 +%else +Requires: initscripts >= 5.20 +%endif +BuildRequires: perl, openssl-devel +BuildRequires: /bin/login +%if ! %{build6x} +BuildPreReq: glibc-devel, pam +%else +BuildRequires: /usr/include/security/pam_appl.h +%endif +%if ! %{no_x11_askpass} +BuildRequires: /usr/include/X11/Xlib.h +%endif +%if ! %{no_gnome_askpass} +BuildRequires: pkgconfig +%endif +%if %{kerberos5} +BuildRequires: krb5-devel +BuildRequires: krb5-libs +%endif + +%package clients +Summary: OpenSSH clients. +Requires: openssh = %{version}-%{release} +Group: Applications/Internet +Obsoletes: ssh-clients + +%package server +Summary: The OpenSSH server daemon. +Group: System Environment/Daemons +Obsoletes: ssh-server +Requires: openssh = %{version}-%{release}, chkconfig >= 0.9 +%if ! %{build6x} +Requires: /etc/pam.d/system-auth +%endif + +%package askpass +Summary: A passphrase dialog for OpenSSH and X. +Group: Applications/Internet +Requires: openssh = %{version}-%{release} +Obsoletes: ssh-extras + +%package askpass-gnome +Summary: A passphrase dialog for OpenSSH, X, and GNOME. +Group: Applications/Internet +Requires: openssh = %{version}-%{release} +Obsoletes: ssh-extras + +%description +SSH (Secure SHell) is a program for logging into and executing +commands on a remote machine. SSH is intended to replace rlogin and +rsh, and to provide secure encrypted communications between two +untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's version of the last free version of SSH, bringing +it up to date in terms of security and features, as well as removing +all patented algorithms to separate libraries. + +This package includes the core files necessary for both the OpenSSH +client and server. To make this package useful, you should also +install openssh-clients, openssh-server, or both. + +%description clients +OpenSSH is a free version of SSH (Secure SHell), a program for logging +into and executing commands on a remote machine. This package includes +the clients necessary to make encrypted connections to SSH servers. +You'll also need to install the openssh package on OpenSSH clients. + +%description server +OpenSSH is a free version of SSH (Secure SHell), a program for logging +into and executing commands on a remote machine. This package contains +the secure shell daemon (sshd). The sshd daemon allows SSH clients to +securely connect to your SSH server. You also need to have the openssh +package installed. + +%description askpass +OpenSSH is a free version of SSH (Secure SHell), a program for logging +into and executing commands on a remote machine. This package contains +an X11 passphrase dialog for OpenSSH. + +%description askpass-gnome +OpenSSH is a free version of SSH (Secure SHell), a program for logging +into and executing commands on a remote machine. This package contains +an X11 passphrase dialog for OpenSSH and the GNOME GUI desktop +environment. + +%prep + +%if ! %{no_x11_askpass} +%setup -q -a 1 +%else +%setup -q +%endif + +%build +%if %{rescue} +CFLAGS="$RPM_OPT_FLAGS -Os"; export CFLAGS +%endif + +%if %{kerberos5} +K5DIR=`rpm -ql krb5-devel | grep include/krb5.h | sed 's,\/include\/krb5.h,,'` +echo K5DIR=$K5DIR +%endif + +%configure \ + --sysconfdir=%{_sysconfdir}/ssh \ + --libexecdir=%{_libexecdir}/openssh \ + --datadir=%{_datadir}/openssh \ + --with-rsh=%{_bindir}/rsh \ + --with-default-path=/usr/local/bin:/bin:/usr/bin \ + --with-superuser-path=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin \ + --with-privsep-path=%{_var}/empty/sshd \ + --with-md5-passwords \ +%if %{scard} + --with-smartcard \ +%endif +%if %{rescue} + --without-pam \ +%else + --with-pam \ +%endif +%if %{kerberos5} + --with-kerberos5=$K5DIR \ +%endif + + +%if %{static_libcrypto} +perl -pi -e "s|-lcrypto|%{_libdir}/libcrypto.a|g" Makefile +%endif + +make + +%if ! %{no_x11_askpass} +pushd x11-ssh-askpass-%{aversion} +%configure --libexecdir=%{_libexecdir}/openssh +xmkmf -a +make +popd +%endif + +# Define a variable to toggle gnome1/gtk2 building. This is necessary +# because RPM doesn't handle nested %if statements. +%if %{gtk2} + gtk2=yes +%else + gtk2=no +%endif + +%if ! %{no_gnome_askpass} +pushd contrib +if [ $gtk2 = yes ] ; then + make gnome-ssh-askpass2 + mv gnome-ssh-askpass2 gnome-ssh-askpass +else + make gnome-ssh-askpass1 + mv gnome-ssh-askpass1 gnome-ssh-askpass +fi +popd +%endif + +%install +rm -rf $RPM_BUILD_ROOT +mkdir -p -m755 $RPM_BUILD_ROOT%{_sysconfdir}/ssh +mkdir -p -m755 $RPM_BUILD_ROOT%{_libexecdir}/openssh +mkdir -p -m755 $RPM_BUILD_ROOT%{_var}/empty/sshd + +make install DESTDIR=$RPM_BUILD_ROOT + +install -d $RPM_BUILD_ROOT/etc/pam.d/ +install -d $RPM_BUILD_ROOT/etc/rc.d/init.d +install -d $RPM_BUILD_ROOT%{_libexecdir}/openssh +%if %{build6x} +install -m644 contrib/redhat/sshd.pam.old $RPM_BUILD_ROOT/etc/pam.d/sshd +%else +install -m644 contrib/redhat/sshd.pam $RPM_BUILD_ROOT/etc/pam.d/sshd +%endif +install -m755 contrib/redhat/sshd.init $RPM_BUILD_ROOT/etc/rc.d/init.d/sshd + +%if ! %{no_x11_askpass} +install -s x11-ssh-askpass-%{aversion}/x11-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/x11-ssh-askpass +ln -s x11-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/ssh-askpass +%endif + +%if ! %{no_gnome_askpass} +install -s contrib/gnome-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/gnome-ssh-askpass +%endif + +%if ! %{scard} + rm -f $RPM_BUILD_ROOT/usr/share/openssh/Ssh.bin +%endif + +%if ! %{no_gnome_askpass} +install -m 755 -d $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/ +install -m 755 contrib/redhat/gnome-ssh-askpass.csh $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/ +install -m 755 contrib/redhat/gnome-ssh-askpass.sh $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/ +%endif + +perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/* + +%clean +rm -rf $RPM_BUILD_ROOT + +%triggerun server -- ssh-server +if [ "$1" != 0 -a -r /var/run/sshd.pid ] ; then + touch /var/run/sshd.restart +fi + +%triggerun server -- openssh-server < 2.5.0p1 +# Count the number of HostKey and HostDsaKey statements we have. +gawk 'BEGIN {IGNORECASE=1} + /^hostkey/ || /^hostdsakey/ {sawhostkey = sawhostkey + 1} + END {exit sawhostkey}' /etc/ssh/sshd_config +# And if we only found one, we know the client was relying on the old default +# behavior, which loaded the the SSH2 DSA host key when HostDsaKey wasn't +# specified. Now that HostKey is used for both SSH1 and SSH2 keys, specifying +# one nullifies the default, which would have loaded both. +if [ $? -eq 1 ] ; then + echo HostKey /etc/ssh/ssh_host_rsa_key >> /etc/ssh/sshd_config + echo HostKey /etc/ssh/ssh_host_dsa_key >> /etc/ssh/sshd_config +fi + +%triggerpostun server -- ssh-server +if [ "$1" != 0 ] ; then + /sbin/chkconfig --add sshd + if test -f /var/run/sshd.restart ; then + rm -f /var/run/sshd.restart + /sbin/service sshd start > /dev/null 2>&1 || : + fi +fi + +%pre server +%{_sbindir}/groupadd -r -g %{sshd_gid} sshd 2>/dev/null || : +%{_sbindir}/useradd -d /var/empty/sshd -s /bin/false -u %{sshd_uid} \ + -g sshd -M -r sshd 2>/dev/null || : + +%post server +/sbin/chkconfig --add sshd + +%postun server +/sbin/service sshd condrestart > /dev/null 2>&1 || : + +%preun server +if [ "$1" = 0 ] +then + /sbin/service sshd stop > /dev/null 2>&1 || : + /sbin/chkconfig --del sshd +fi + +%files +%defattr(-,root,root) +%doc CREDITS ChangeLog INSTALL LICENCE OVERVIEW README* PROTOCOL* TODO +%attr(0755,root,root) %{_bindir}/scp +%attr(0644,root,root) %{_mandir}/man1/scp.1* +%attr(0755,root,root) %dir %{_sysconfdir}/ssh +%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/moduli +%if ! %{rescue} +%attr(0755,root,root) %{_bindir}/ssh-keygen +%attr(0644,root,root) %{_mandir}/man1/ssh-keygen.1* +%attr(0755,root,root) %dir %{_libexecdir}/openssh +%attr(4711,root,root) %{_libexecdir}/openssh/ssh-keysign +%attr(0755,root,root) %{_libexecdir}/openssh/ssh-pkcs11-helper +%attr(0644,root,root) %{_mandir}/man8/ssh-keysign.8* +%attr(0644,root,root) %{_mandir}/man8/ssh-pkcs11-helper.8* +%endif +%if %{scard} +%attr(0755,root,root) %dir %{_datadir}/openssh +%attr(0644,root,root) %{_datadir}/openssh/Ssh.bin +%endif + +%files clients +%defattr(-,root,root) +%attr(0755,root,root) %{_bindir}/ssh +%attr(0644,root,root) %{_mandir}/man1/ssh.1* +%attr(0644,root,root) %{_mandir}/man5/ssh_config.5* +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ssh_config +%attr(-,root,root) %{_bindir}/slogin +%attr(-,root,root) %{_mandir}/man1/slogin.1* +%if ! %{rescue} +%attr(2755,root,nobody) %{_bindir}/ssh-agent +%attr(0755,root,root) %{_bindir}/ssh-add +%attr(0755,root,root) %{_bindir}/ssh-keyscan +%attr(0755,root,root) %{_bindir}/sftp +%attr(0644,root,root) %{_mandir}/man1/ssh-agent.1* +%attr(0644,root,root) %{_mandir}/man1/ssh-add.1* +%attr(0644,root,root) %{_mandir}/man1/ssh-keyscan.1* +%attr(0644,root,root) %{_mandir}/man1/sftp.1* +%endif + +%if ! %{rescue} +%files server +%defattr(-,root,root) +%dir %attr(0111,root,root) %{_var}/empty/sshd +%attr(0755,root,root) %{_sbindir}/sshd +%attr(0755,root,root) %{_libexecdir}/openssh/sftp-server +%attr(0644,root,root) %{_mandir}/man8/sshd.8* +%attr(0644,root,root) %{_mandir}/man5/moduli.5* +%attr(0644,root,root) %{_mandir}/man5/sshd_config.5* +%attr(0644,root,root) %{_mandir}/man8/sftp-server.8* +%attr(0755,root,root) %dir %{_sysconfdir}/ssh +%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/sshd_config +%attr(0600,root,root) %config(noreplace) /etc/pam.d/sshd +%attr(0755,root,root) %config /etc/rc.d/init.d/sshd +%endif + +%if ! %{no_x11_askpass} +%files askpass +%defattr(-,root,root) +%doc x11-ssh-askpass-%{aversion}/README +%doc x11-ssh-askpass-%{aversion}/ChangeLog +%doc x11-ssh-askpass-%{aversion}/SshAskpass*.ad +%attr(0755,root,root) %{_libexecdir}/openssh/ssh-askpass +%attr(0755,root,root) %{_libexecdir}/openssh/x11-ssh-askpass +%endif + +%if ! %{no_gnome_askpass} +%files askpass-gnome +%defattr(-,root,root) +%attr(0755,root,root) %config %{_sysconfdir}/profile.d/gnome-ssh-askpass.* +%attr(0755,root,root) %{_libexecdir}/openssh/gnome-ssh-askpass +%endif + +%changelog +* Wed Jul 14 2010 Tim Rice +- test for skip_x11_askpass (line 77) should have been for no_x11_askpass + +* Mon Jun 2 2003 Damien Miller +- Remove noip6 option. This may be controlled at run-time in client config + file using new AddressFamily directive + +* Mon May 12 2003 Damien Miller +- Don't install profile.d scripts when not building with GNOME/GTK askpass + (patch from bet@rahul.net) + +* Wed Oct 01 2002 Damien Miller +- Install ssh-agent setgid nobody to prevent ptrace() key theft attacks + +* Mon Sep 30 2002 Damien Miller +- Use contrib/ Makefile for building askpass programs + +* Fri Jun 21 2002 Damien Miller +- Merge in spec changes from seba@iq.pl (Sebastian Pachuta) +- Add new {ssh,sshd}_config.5 manpages +- Add new ssh-keysign program and remove setuid from ssh client + +* Fri May 10 2002 Damien Miller +- Merge in spec changes from RedHat, reorgansie a little +- Add Privsep user, group and directory + +* Thu Mar 7 2002 Nalin Dahyabhai 3.1p1-2 +- bump and grind (through the build system) + +* Thu Mar 7 2002 Nalin Dahyabhai 3.1p1-1 +- require sharutils for building (mindrot #137) +- require db1-devel only when building for 6.x (#55105), which probably won't + work anyway (3.1 requires OpenSSL 0.9.6 to build), but what the heck +- require pam-devel by file (not by package name) again +- add Markus's patch to compile with OpenSSL 0.9.5a (from + http://bugzilla.mindrot.org/show_bug.cgi?id=141) and apply it if we're + building for 6.x + +* Thu Mar 7 2002 Nalin Dahyabhai 3.1p1-0 +- update to 3.1p1 + +* Tue Mar 5 2002 Nalin Dahyabhai SNAP-20020305 +- update to SNAP-20020305 +- drop debug patch, fixed upstream + +* Wed Feb 20 2002 Nalin Dahyabhai SNAP-20020220 +- update to SNAP-20020220 for testing purposes (you've been warned, if there's + anything to be warned about, gss patches won't apply, I don't mind) + +* Wed Feb 13 2002 Nalin Dahyabhai 3.0.2p1-3 +- add patches from Simon Wilkinson and Nicolas Williams for GSSAPI key + exchange, authentication, and named key support + +* Wed Jan 23 2002 Nalin Dahyabhai 3.0.2p1-2 +- remove dependency on db1-devel, which has just been swallowed up whole + by gnome-libs-devel + +* Sun Dec 29 2001 Nalin Dahyabhai +- adjust build dependencies so that build6x actually works right (fix + from Hugo van der Kooij) + +* Tue Dec 4 2001 Nalin Dahyabhai 3.0.2p1-1 +- update to 3.0.2p1 + +* Fri Nov 16 2001 Nalin Dahyabhai 3.0.1p1-1 +- update to 3.0.1p1 + +* Tue Nov 13 2001 Nalin Dahyabhai +- update to current CVS (not for use in distribution) + +* Thu Nov 8 2001 Nalin Dahyabhai 3.0p1-1 +- merge some of Damien Miller changes from the upstream + 3.0p1 spec file and init script + +* Wed Nov 7 2001 Nalin Dahyabhai +- update to 3.0p1 +- update to x11-ssh-askpass 1.2.4.1 +- change build dependency on a file from pam-devel to the pam-devel package +- replace primes with moduli + +* Thu Sep 27 2001 Nalin Dahyabhai 2.9p2-9 +- incorporate fix from Markus Friedl's advisory for IP-based authorization bugs + +* Thu Sep 13 2001 Bernhard Rosenkraenzer 2.9p2-8 +- Merge changes to rescue build from current sysadmin survival cd + +* Thu Sep 6 2001 Nalin Dahyabhai 2.9p2-7 +- fix scp's server's reporting of file sizes, and build with the proper + preprocessor define to get large-file capable open(), stat(), etc. + (sftp has been doing this correctly all along) (#51827) +- configure without --with-ipv4-default on RHL 7.x and newer (#45987,#52247) +- pull cvs patch to fix support for /etc/nologin for non-PAM logins (#47298) +- mark profile.d scriptlets as config files (#42337) +- refer to Jason Stone's mail for zsh workaround for exit-hanging quasi-bug +- change a couple of log() statements to debug() statements (#50751) +- pull cvs patch to add -t flag to sshd (#28611) +- clear fd_sets correctly (one bit per FD, not one byte per FD) (#43221) + +* Mon Aug 20 2001 Nalin Dahyabhai 2.9p2-6 +- add db1-devel as a BuildPrerequisite (noted by Hans Ecke) + +* Thu Aug 16 2001 Nalin Dahyabhai +- pull cvs patch to fix remote port forwarding with protocol 2 + +* Thu Aug 9 2001 Nalin Dahyabhai +- pull cvs patch to add session initialization to no-pty sessions +- pull cvs patch to not cut off challengeresponse auth needlessly +- refuse to do X11 forwarding if xauth isn't there, handy if you enable + it by default on a system that doesn't have X installed (#49263) + +* Wed Aug 8 2001 Nalin Dahyabhai +- don't apply patches to code we don't intend to build (spotted by Matt Galgoci) + +* Mon Aug 6 2001 Nalin Dahyabhai +- pass OPTIONS correctly to initlog (#50151) + +* Wed Jul 25 2001 Nalin Dahyabhai +- switch to x11-ssh-askpass 1.2.2 + +* Wed Jul 11 2001 Nalin Dahyabhai +- rebuild in new environment + +* Mon Jun 25 2001 Nalin Dahyabhai +- disable the gssapi patch + +* Mon Jun 18 2001 Nalin Dahyabhai +- update to 2.9p2 +- refresh to a new version of the gssapi patch + +* Thu Jun 7 2001 Nalin Dahyabhai +- change Copyright: BSD to License: BSD +- add Markus Friedl's unverified patch for the cookie file deletion problem + so that we can verify it +- drop patch to check if xauth is present (was folded into cookie patch) +- don't apply gssapi patches for the errata candidate +- clear supplemental groups list at startup + +* Fri May 25 2001 Nalin Dahyabhai +- fix an error parsing the new default sshd_config +- add a fix from Markus Friedl (via openssh-unix-dev) for ssh-keygen not + dealing with comments right + +* Thu May 24 2001 Nalin Dahyabhai +- add in Simon Wilkinson's GSSAPI patch to give it some testing in-house, + to be removed before the next beta cycle because it's a big departure + from the upstream version + +* Thu May 3 2001 Nalin Dahyabhai +- finish marking strings in the init script for translation +- modify init script to source /etc/sysconfig/sshd and pass $OPTIONS to sshd + at startup (change merged from openssh.com init script, originally by + Pekka Savola) +- refuse to do X11 forwarding if xauth isn't there, handy if you enable + it by default on a system that doesn't have X installed + +* Wed May 2 2001 Nalin Dahyabhai +- update to 2.9 +- drop various patches that came from or went upstream or to or from CVS + +* Wed Apr 18 2001 Nalin Dahyabhai +- only require initscripts 5.00 on 6.2 (reported by Peter Bieringer) + +* Sun Apr 8 2001 Preston Brown +- remove explicit openssl requirement, fixes builddistro issue +- make initscript stop() function wait until sshd really dead to avoid + races in condrestart + +* Mon Apr 2 2001 Nalin Dahyabhai +- mention that challengereponse supports PAM, so disabling password doesn't + limit users to pubkey and rsa auth (#34378) +- bypass the daemon() function in the init script and call initlog directly, + because daemon() won't start a daemon it detects is already running (like + open connections) +- require the version of openssl we had when we were built + +* Fri Mar 23 2001 Nalin Dahyabhai +- make do_pam_setcred() smart enough to know when to establish creds and + when to reinitialize them +- add in a couple of other fixes from Damien for inclusion in the errata + +* Thu Mar 22 2001 Nalin Dahyabhai +- update to 2.5.2p2 +- call setcred() again after initgroups, because the "creds" could actually + be group memberships + +* Tue Mar 20 2001 Nalin Dahyabhai +- update to 2.5.2p1 (includes endianness fixes in the rijndael implementation) +- don't enable challenge-response by default until we find a way to not + have too many userauth requests (we may make up to six pubkey and up to + three password attempts as it is) +- remove build dependency on rsh to match openssh.com's packages more closely + +* Sat Mar 3 2001 Nalin Dahyabhai +- remove dependency on openssl -- would need to be too precise + +* Fri Mar 2 2001 Nalin Dahyabhai +- rebuild in new environment + +* Mon Feb 26 2001 Nalin Dahyabhai +- Revert the patch to move pam_open_session. +- Init script and spec file changes from Pekka Savola. (#28750) +- Patch sftp to recognize '-o protocol' arguments. (#29540) + +* Thu Feb 22 2001 Nalin Dahyabhai +- Chuck the closing patch. +- Add a trigger to add host keys for protocol 2 to the config file, now that + configuration file syntax requires us to specify it with HostKey if we + specify any other HostKey values, which we do. + +* Tue Feb 20 2001 Nalin Dahyabhai +- Redo patch to move pam_open_session after the server setuid()s to the user. +- Rework the nopam patch to use be picked up by autoconf. + +* Mon Feb 19 2001 Nalin Dahyabhai +- Update for 2.5.1p1. +- Add init script mods from Pekka Savola. +- Tweak the init script to match the CVS contrib script more closely. +- Redo patch to ssh-add to try to adding both identity and id_dsa to also try + adding id_rsa. + +* Fri Feb 16 2001 Nalin Dahyabhai +- Update for 2.5.0p1. +- Use $RPM_OPT_FLAGS instead of -O when building gnome-ssh-askpass +- Resync with parts of Damien Miller's openssh.spec from CVS, including + update of x11 askpass to 1.2.0. +- Only require openssl (don't prereq) because we generate keys in the init + script now. + +* Tue Feb 13 2001 Nalin Dahyabhai +- Don't open a PAM session until we've forked and become the user (#25690). +- Apply Andrew Bartlett's patch for letting pam_authenticate() know which + host the user is attempting a login from. +- Resync with parts of Damien Miller's openssh.spec from CVS. +- Don't expose KbdInt responses in debug messages (from CVS). +- Detect and handle errors in rsa_{public,private}_decrypt (from CVS). + +* Wed Feb 7 2001 Trond Eivind Glomsrxd +- i18n-tweak to initscript. + +* Tue Jan 23 2001 Nalin Dahyabhai +- More gettextizing. +- Close all files after going into daemon mode (needs more testing). +- Extract patch from CVS to handle auth banners (in the client). +- Extract patch from CVS to handle compat weirdness. + +* Fri Jan 19 2001 Nalin Dahyabhai +- Finish with the gettextizing. + +* Thu Jan 18 2001 Nalin Dahyabhai +- Fix a bug in auth2-pam.c (#23877) +- Gettextize the init script. + +* Wed Dec 20 2000 Nalin Dahyabhai +- Incorporate a switch for using PAM configs for 6.x, just in case. + +* Tue Dec 5 2000 Nalin Dahyabhai +- Incorporate Bero's changes for a build specifically for rescue CDs. + +* Wed Nov 29 2000 Nalin Dahyabhai +- Don't treat pam_setcred() failure as fatal unless pam_authenticate() has + succeeded, to allow public-key authentication after a failure with "none" + authentication. (#21268) + +* Tue Nov 28 2000 Nalin Dahyabhai +- Update to x11-askpass 1.1.1. (#21301) +- Don't second-guess fixpaths, which causes paths to get fixed twice. (#21290) + +* Mon Nov 27 2000 Nalin Dahyabhai +- Merge multiple PAM text messages into subsequent prompts when possible when + doing keyboard-interactive authentication. + +* Sun Nov 26 2000 Nalin Dahyabhai +- Disable the built-in MD5 password support. We're using PAM. +- Take a crack at doing keyboard-interactive authentication with PAM, and + enable use of it in the default client configuration so that the client + will try it when the server disallows password authentication. +- Build with debugging flags. Build root policies strip all binaries anyway. + +* Tue Nov 21 2000 Nalin Dahyabhai +- Use DESTDIR instead of %%makeinstall. +- Remove /usr/X11R6/bin from the path-fixing patch. + +* Mon Nov 20 2000 Nalin Dahyabhai +- Add the primes file from the latest snapshot to the main package (#20884). +- Add the dev package to the prereq list (#19984). +- Remove the default path and mimic login's behavior in the server itself. + +* Fri Nov 17 2000 Nalin Dahyabhai +- Resync with conditional options in Damien Miller's .spec file for an errata. +- Change libexecdir from %%{_libexecdir}/ssh to %%{_libexecdir}/openssh. + +* Tue Nov 7 2000 Nalin Dahyabhai +- Update to OpenSSH 2.3.0p1. +- Update to x11-askpass 1.1.0. +- Enable keyboard-interactive authentication. + +* Mon Oct 30 2000 Nalin Dahyabhai +- Update to ssh-askpass-x11 1.0.3. +- Change authentication related messages to be private (#19966). + +* Tue Oct 10 2000 Nalin Dahyabhai +- Patch ssh-keygen to be able to list signatures for DSA public key files + it generates. + +* Thu Oct 5 2000 Nalin Dahyabhai +- Add BuildRequires on /usr/include/security/pam_appl.h to be sure we always + build PAM authentication in. +- Try setting SSH_ASKPASS if gnome-ssh-askpass is installed. +- Clean out no-longer-used patches. +- Patch ssh-add to try to add both identity and id_dsa, and to error only + when neither exists. + +* Mon Oct 2 2000 Nalin Dahyabhai +- Update x11-askpass to 1.0.2. (#17835) +- Add BuildRequiress for /bin/login and /usr/bin/rsh so that configure will + always find them in the right place. (#17909) +- Set the default path to be the same as the one supplied by /bin/login, but + add /usr/X11R6/bin. (#17909) +- Try to handle obsoletion of ssh-server more cleanly. Package names + are different, but init script name isn't. (#17865) + +* Wed Sep 6 2000 Nalin Dahyabhai +- Update to 2.2.0p1. (#17835) +- Tweak the init script to allow proper restarting. (#18023) + +* Wed Aug 23 2000 Nalin Dahyabhai +- Update to 20000823 snapshot. +- Change subpackage requirements from %%{version} to %%{version}-%%{release} +- Back out the pipe patch. + +* Mon Jul 17 2000 Nalin Dahyabhai +- Update to 2.1.1p4, which includes fixes for config file parsing problems. +- Move the init script back. +- Add Damien's quick fix for wackiness. + +* Wed Jul 12 2000 Nalin Dahyabhai +- Update to 2.1.1p3, which includes fixes for X11 forwarding and strtok(). + +* Thu Jul 6 2000 Nalin Dahyabhai +- Move condrestart to server postun. +- Move key generation to init script. +- Actually use the right patch for moving the key generation to the init script. +- Clean up the init script a bit. + +* Wed Jul 5 2000 Nalin Dahyabhai +- Fix X11 forwarding, from mail post by Chan Shih-Ping Richard. + +* Sun Jul 2 2000 Nalin Dahyabhai +- Update to 2.1.1p2. +- Use of strtok() considered harmful. + +* Sat Jul 1 2000 Nalin Dahyabhai +- Get the build root out of the man pages. + +* Thu Jun 29 2000 Nalin Dahyabhai +- Add and use condrestart support in the init script. +- Add newer initscripts as a prereq. + +* Tue Jun 27 2000 Nalin Dahyabhai +- Build in new environment (release 2) +- Move -clients subpackage to Applications/Internet group + +* Fri Jun 9 2000 Nalin Dahyabhai +- Update to 2.2.1p1 + +* Sat Jun 3 2000 Nalin Dahyabhai +- Patch to build with neither RSA nor RSAref. +- Miscellaneous FHS-compliance tweaks. +- Fix for possibly-compressed man pages. + +* Wed Mar 15 2000 Damien Miller +- Updated for new location +- Updated for new gnome-ssh-askpass build + +* Sun Dec 26 1999 Damien Miller +- Added Jim Knoble's askpass + +* Mon Nov 15 1999 Damien Miller +- Split subpackages further based on patch from jim knoble + +* Sat Nov 13 1999 Damien Miller +- Added 'Obsoletes' directives + +* Tue Nov 09 1999 Damien Miller +- Use make install +- Subpackages + +* Mon Nov 08 1999 Damien Miller +- Added links for slogin +- Fixed perms on manpages + +* Sat Oct 30 1999 Damien Miller +- Renamed init script + +* Fri Oct 29 1999 Damien Miller +- Back to old binary names + +* Thu Oct 28 1999 Damien Miller +- Use autoconf +- New binary names + +* Wed Oct 27 1999 Damien Miller +- Initial RPMification, based on Jan "Yenya" Kasprzak's spec. diff --git a/crypto/external/bsd/openssh/dist/contrib/redhat/sshd.init b/crypto/external/bsd/openssh/dist/contrib/redhat/sshd.init new file mode 100755 index 000000000..40c8dfd9f --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/redhat/sshd.init @@ -0,0 +1,106 @@ +#!/bin/bash +# +# Init file for OpenSSH server daemon +# +# chkconfig: 2345 55 25 +# description: OpenSSH server daemon +# +# processname: sshd +# config: /etc/ssh/ssh_host_key +# config: /etc/ssh/ssh_host_key.pub +# config: /etc/ssh/ssh_random_seed +# config: /etc/ssh/sshd_config +# pidfile: /var/run/sshd.pid + +# source function library +. /etc/rc.d/init.d/functions + +# pull in sysconfig settings +[ -f /etc/sysconfig/sshd ] && . /etc/sysconfig/sshd + +RETVAL=0 +prog="sshd" + +# Some functions to make the below more readable +SSHD=/usr/sbin/sshd +PID_FILE=/var/run/sshd.pid + +do_restart_sanity_check() +{ + $SSHD -t + RETVAL=$? + if [ $RETVAL -ne 0 ]; then + failure $"Configuration file or keys are invalid" + echo + fi +} + +start() +{ + # Create keys if necessary + /usr/bin/ssh-keygen -A + if [ -x /sbin/restorecon ]; then + /sbin/restorecon /etc/ssh/ssh_host_key.pub + /sbin/restorecon /etc/ssh/ssh_host_rsa_key.pub + /sbin/restorecon /etc/ssh/ssh_host_dsa_key.pub + /sbin/restorecon /etc/ssh/ssh_host_ecdsa_key.pub + fi + + echo -n $"Starting $prog:" + $SSHD $OPTIONS && success || failure + RETVAL=$? + [ $RETVAL -eq 0 ] && touch /var/lock/subsys/sshd + echo +} + +stop() +{ + echo -n $"Stopping $prog:" + killproc $SSHD -TERM + RETVAL=$? + [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/sshd + echo +} + +reload() +{ + echo -n $"Reloading $prog:" + killproc $SSHD -HUP + RETVAL=$? + echo +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + stop + start + ;; + reload) + reload + ;; + condrestart) + if [ -f /var/lock/subsys/sshd ] ; then + do_restart_sanity_check + if [ $RETVAL -eq 0 ] ; then + stop + # avoid race + sleep 3 + start + fi + fi + ;; + status) + status $SSHD + RETVAL=$? + ;; + *) + echo $"Usage: $0 {start|stop|restart|reload|condrestart|status}" + RETVAL=1 +esac +exit $RETVAL diff --git a/crypto/external/bsd/openssh/dist/contrib/redhat/sshd.init.old b/crypto/external/bsd/openssh/dist/contrib/redhat/sshd.init.old new file mode 100755 index 000000000..0deb6080e --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/redhat/sshd.init.old @@ -0,0 +1,172 @@ +#!/bin/bash +# +# Init file for OpenSSH server daemon +# +# chkconfig: 2345 55 25 +# description: OpenSSH server daemon +# +# processname: sshd +# config: /etc/ssh/ssh_host_key +# config: /etc/ssh/ssh_host_key.pub +# config: /etc/ssh/ssh_random_seed +# config: /etc/ssh/sshd_config +# pidfile: /var/run/sshd.pid + +# source function library +. /etc/rc.d/init.d/functions + +# pull in sysconfig settings +[ -f /etc/sysconfig/sshd ] && . /etc/sysconfig/sshd + +RETVAL=0 +prog="sshd" + +# Some functions to make the below more readable +KEYGEN=/usr/bin/ssh-keygen +SSHD=/usr/sbin/sshd +RSA1_KEY=/etc/ssh/ssh_host_key +RSA_KEY=/etc/ssh/ssh_host_rsa_key +DSA_KEY=/etc/ssh/ssh_host_dsa_key +PID_FILE=/var/run/sshd.pid + +my_success() { + local msg + if [ $# -gt 1 ]; then + msg="$2" + else + msg="done" + fi + case "`type -type success`" in + function) + success "$1" + ;; + *) + echo -n "${msg}" + ;; + esac +} +my_failure() { + local msg + if [ $# -gt 1 ]; then + msg="$2" + else + msg="FAILED" + fi + case "`type -type failure`" in + function) + failure "$1" + ;; + *) + echo -n "${msg}" + ;; + esac +} +do_rsa1_keygen() { + if [ ! -s $RSA1_KEY ]; then + echo -n "Generating SSH1 RSA host key: " + if $KEYGEN -q -t rsa1 -f $RSA1_KEY -C '' -N '' >&/dev/null; then + chmod 600 $RSA1_KEY + chmod 644 $RSA1_KEY.pub + my_success "RSA1 key generation" + echo + else + my_failure "RSA1 key generation" + echo + exit 1 + fi + fi +} +do_rsa_keygen() { + if [ ! -s $RSA_KEY ]; then + echo -n "Generating SSH2 RSA host key: " + if $KEYGEN -q -t rsa -f $RSA_KEY -C '' -N '' >&/dev/null; then + chmod 600 $RSA_KEY + chmod 644 $RSA_KEY.pub + my_success "RSA key generation" + echo + else + my_failure "RSA key generation" + echo + exit 1 + fi + fi +} +do_dsa_keygen() { + if [ ! -s $DSA_KEY ]; then + echo -n "Generating SSH2 DSA host key: " + if $KEYGEN -q -t dsa -f $DSA_KEY -C '' -N '' >&/dev/null; then + chmod 600 $DSA_KEY + chmod 644 $DSA_KEY.pub + my_success "DSA key generation" + echo + else + my_failure "DSA key generation" + echo + exit 1 + fi + fi +} +do_restart_sanity_check() { + $SSHD -t + RETVAL=$? + if [ ! "$RETVAL" = 0 ]; then + my_failure "Configuration file or keys" + echo + fi +} + + +case "$1" in + start) + # Create keys if necessary + do_rsa1_keygen; + do_rsa_keygen; + do_dsa_keygen; + + echo -n "Starting sshd: " + if [ ! -f $PID_FILE ] ; then + sshd $OPTIONS + RETVAL=$? + if [ "$RETVAL" = "0" ] ; then + my_success "sshd startup" "sshd" + touch /var/lock/subsys/sshd + else + my_failure "sshd startup" "" + fi + fi + echo + ;; + stop) + echo -n "Shutting down sshd: " + if [ -f $PID_FILE ] ; then + killproc sshd + RETVAL=$? + [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/sshd + fi + echo + ;; + restart) + do_restart_sanity_check + $0 stop + $0 start + RETVAL=$? + ;; + condrestart) + if [ -f /var/lock/subsys/sshd ] ; then + do_restart_sanity_check + $0 stop + $0 start + RETVAL=$? + fi + ;; + status) + status sshd + RETVAL=$? + ;; + *) + echo "Usage: sshd {start|stop|restart|status|condrestart}" + exit 1 + ;; +esac + +exit $RETVAL diff --git a/crypto/external/bsd/openssh/dist/contrib/redhat/sshd.pam b/crypto/external/bsd/openssh/dist/contrib/redhat/sshd.pam new file mode 100644 index 000000000..ffa5adbe5 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/redhat/sshd.pam @@ -0,0 +1,6 @@ +#%PAM-1.0 +auth required pam_stack.so service=system-auth +account required pam_nologin.so +account required pam_stack.so service=system-auth +password required pam_stack.so service=system-auth +session required pam_stack.so service=system-auth diff --git a/crypto/external/bsd/openssh/dist/contrib/redhat/sshd.pam.old b/crypto/external/bsd/openssh/dist/contrib/redhat/sshd.pam.old new file mode 100644 index 000000000..26dcb34d9 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/redhat/sshd.pam.old @@ -0,0 +1,8 @@ +#%PAM-1.0 +auth required /lib/security/pam_pwdb.so shadow nodelay +auth required /lib/security/pam_nologin.so +account required /lib/security/pam_pwdb.so +password required /lib/security/pam_cracklib.so +password required /lib/security/pam_pwdb.so shadow nullok use_authtok +session required /lib/security/pam_pwdb.so +session required /lib/security/pam_limits.so diff --git a/crypto/external/bsd/openssh/dist/contrib/solaris/README b/crypto/external/bsd/openssh/dist/contrib/solaris/README new file mode 100644 index 000000000..fefdd4b53 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/solaris/README @@ -0,0 +1,30 @@ +The following is a new package build script for Solaris. This is being +introduced into OpenSSH 3.0 and above in hopes of simplifying the build +process. As of 3.1p2 the script should work on all platforms that have +SVR4 style package tools. + +The build process is called a 'dummy install'.. Which means the software does +a "make install-nokeys DESTDIR=[fakeroot]". This way all manpages should +be handled correctly and key are defered until the first time the sshd +is started. + +Directions: + +1. make -F Makefile.in distprep (Only if you are getting from the CVS tree) +2. ./configure --with-pam [..any other options you want..] +3. look at the top of buildpkg.sh for the configurable options and put + any changes you want in openssh-config.local. Additional customizations + can be done to the build process by creating one or more of the following + scripts that will be sourced by buildpkg.sh. + pkg_post_make_install_fixes.sh pkg-post-prototype-edit.sh + pkg-preinstall.local pkg-postinstall.local pkg-preremove.local + pkg-postremove.local pkg-request.local +4. Run "make package" + +If all goes well you should have a solaris package ready to be installed. + +If you have any problems with this script please post them to +openssh-unix-dev@mindrot.org and I will try to assist you as best as I can. + +- Ben Lindstrom + diff --git a/crypto/external/bsd/openssh/dist/contrib/ssh-copy-id b/crypto/external/bsd/openssh/dist/contrib/ssh-copy-id new file mode 100644 index 000000000..ae88e9958 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/ssh-copy-id @@ -0,0 +1,300 @@ +#!/bin/sh + +# Copyright (c) 1999-2013 Philip Hands +# 2013 Martin Kletzander +# 2010 Adeodato =?iso-8859-1?Q?Sim=F3?= +# 2010 Eric Moret +# 2009 Xr +# 2007 Justin Pryzby +# 2004 Reini Urban +# 2003 Colin Watson +# 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. + +# Shell script to install your public key(s) on a remote machine +# See the ssh-copy-id(1) man page for details + +# check that we have something mildly sane as our shell, or try to find something better +if false ^ printf "%s: WARNING: ancient shell, hunting for a more modern one... " "$0" +then + SANE_SH=${SANE_SH:-/usr/bin/ksh} + if printf 'true ^ false\n' | "$SANE_SH" + then + printf "'%s' seems viable.\n" "$SANE_SH" + exec "$SANE_SH" "$0" "$@" + else + cat <<-EOF + oh dear. + + If you have a more recent shell available, that supports \$(...) etc. + please try setting the environment variable SANE_SH to the path of that + shell, and then retry running this script. If that works, please report + a bug describing your setup, and the shell you used to make it work. + + EOF + printf "%s: ERROR: Less dimwitted shell required.\n" "$0" + exit 1 + fi +fi + +DEFAULT_PUB_ID_FILE=$(ls -t ${HOME}/.ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1) + +usage () { + printf 'Usage: %s [-h|-?|-n] [-i [identity_file]] [-p port] [[-o ] ...] [user@]hostname\n' "$0" >&2 + exit 1 +} + +# escape any single quotes in an argument +quote() { + printf "%s\n" "$1" | sed -e "s/'/'\\\\''/g" +} + +use_id_file() { + local L_ID_FILE="$1" + + if expr "$L_ID_FILE" : ".*\.pub$" >/dev/null ; then + PUB_ID_FILE="$L_ID_FILE" + else + PUB_ID_FILE="$L_ID_FILE.pub" + fi + + PRIV_ID_FILE=$(dirname "$PUB_ID_FILE")/$(basename "$PUB_ID_FILE" .pub) + + # check that the files are readable + for f in $PUB_ID_FILE $PRIV_ID_FILE ; do + ErrMSG=$( { : < $f ; } 2>&1 ) || { + printf "\n%s: ERROR: failed to open ID file '%s': %s\n\n" "$0" "$f" "$(printf "%s\n" "$ErrMSG" | sed -e 's/.*: *//')" + exit 1 + } + done + GET_ID="cat \"$PUB_ID_FILE\"" +} + +if [ -n "$SSH_AUTH_SOCK" ] && ssh-add -L >/dev/null 2>&1 ; then + GET_ID="ssh-add -L" +fi + +while test "$#" -gt 0 +do + [ "${SEEN_OPT_I}" ] && expr "$1" : "[-]i" >/dev/null && { + printf "\n%s: ERROR: -i option must not be specified more than once\n\n" "$0" + usage + } + + OPT= OPTARG= + # implement something like getopt to avoid Solaris pain + case "$1" in + -i?*|-o?*|-p?*) + OPT="$(printf -- "$1"|cut -c1-2)" + OPTARG="$(printf -- "$1"|cut -c3-)" + shift + ;; + -o|-p) + OPT="$1" + OPTARG="$2" + shift 2 + ;; + -i) + OPT="$1" + test "$#" -le 2 || expr "$2" : "[-]" >/dev/null || { + OPTARG="$2" + shift + } + shift + ;; + -n|-h|-\?) + OPT="$1" + OPTARG= + shift + ;; + --) + shift + while test "$#" -gt 0 + do + SAVEARGS="${SAVEARGS:+$SAVEARGS }'$(quote "$1")'" + shift + done + break + ;; + -*) + printf "\n%s: ERROR: invalid option (%s)\n\n" "$0" "$1" + usage + ;; + *) + SAVEARGS="${SAVEARGS:+$SAVEARGS }'$(quote "$1")'" + shift + continue + ;; + esac + + case "$OPT" in + -i) + SEEN_OPT_I="yes" + use_id_file "${OPTARG:-$DEFAULT_PUB_ID_FILE}" + ;; + -o|-p) + SSH_OPTS="${SSH_OPTS:+$SSH_OPTS }$OPT '$(quote "$OPTARG")'" + ;; + -n) + DRY_RUN=1 + ;; + -h|-\?) + usage + ;; + esac +done + +eval set -- "$SAVEARGS" + +if [ $# = 0 ] ; then + usage +fi +if [ $# != 1 ] ; then + printf '%s: ERROR: Too many arguments. Expecting a target hostname, got: %s\n\n' "$0" "$SAVEARGS" >&2 + usage +fi + +# drop trailing colon +USER_HOST=$(printf "%s\n" "$1" | sed 's/:$//') +# tack the hostname onto SSH_OPTS +SSH_OPTS="${SSH_OPTS:+$SSH_OPTS }'$(quote "$USER_HOST")'" +# and populate "$@" for later use (only way to get proper quoting of options) +eval set -- "$SSH_OPTS" + +if [ -z "$(eval $GET_ID)" ] && [ -r "${PUB_ID_FILE:=$DEFAULT_PUB_ID_FILE}" ] ; then + use_id_file "$PUB_ID_FILE" +fi + +if [ -z "$(eval $GET_ID)" ] ; then + printf '%s: ERROR: No identities found\n' "$0" >&2 + exit 1 +fi + +# populate_new_ids() uses several global variables ($USER_HOST, $SSH_OPTS ...) +# and has the side effect of setting $NEW_IDS +populate_new_ids() { + local L_SUCCESS="$1" + + # repopulate "$@" inside this function + eval set -- "$SSH_OPTS" + + umask 0177 + local L_TMP_ID_FILE=$(mktemp ~/.ssh/ssh-copy-id_id.XXXXXXXXXX) + if test $? -ne 0 || test "x$L_TMP_ID_FILE" = "x" ; then + echo "mktemp failed" 1>&2 + exit 1 + fi + trap "rm -f $L_TMP_ID_FILE ${L_TMP_ID_FILE}.pub" EXIT TERM INT QUIT + printf '%s: INFO: attempting to log in with the new key(s), to filter out any that are already installed\n' "$0" >&2 + NEW_IDS=$( + eval $GET_ID | { + while read ID ; do + printf '%s\n' "$ID" > $L_TMP_ID_FILE + + # the next line assumes $PRIV_ID_FILE only set if using a single id file - this + # assumption will break if we implement the possibility of multiple -i options. + # The point being that if file based, ssh needs the private key, which it cannot + # find if only given the contents of the .pub file in an unrelated tmpfile + ssh -i "${PRIV_ID_FILE:-$L_TMP_ID_FILE}" \ + -o PreferredAuthentications=publickey \ + -o IdentitiesOnly=yes "$@" exit 2>$L_TMP_ID_FILE.stderr $L_TMP_ID_FILE + else + grep 'Permission denied' $L_TMP_ID_FILE.stderr >/dev/null || { + sed -e 's/^/ERROR: /' <$L_TMP_ID_FILE.stderr >$L_TMP_ID_FILE + cat >/dev/null #consume the other keys, causing loop to end + } + fi + + cat $L_TMP_ID_FILE + done + } + ) + rm -f $L_TMP_ID_FILE* && trap - EXIT TERM INT QUIT + + if expr "$NEW_IDS" : "^ERROR: " >/dev/null ; then + printf '\n%s: %s\n\n' "$0" "$NEW_IDS" >&2 + exit 1 + fi + if [ -z "$NEW_IDS" ] ; then + printf '\n%s: WARNING: All keys were skipped because they already exist on the remote system.\n\n' "$0" >&2 + exit 0 + fi + printf '%s: INFO: %d key(s) remain to be installed -- if you are prompted now it is to install the new keys\n' "$0" "$(printf '%s\n' "$NEW_IDS" | wc -l)" >&2 +} + +REMOTE_VERSION=$(ssh -v -o PreferredAuthentications=',' "$@" 2>&1 | + sed -ne 's/.*remote software version //p') + +case "$REMOTE_VERSION" in + NetScreen*) + populate_new_ids 1 + for KEY in $(printf "%s" "$NEW_IDS" | cut -d' ' -f2) ; do + KEY_NO=$(($KEY_NO + 1)) + printf "%s\n" "$KEY" | grep ssh-dss >/dev/null || { + printf '%s: WARNING: Non-dsa key (#%d) skipped (NetScreen only supports DSA keys)\n' "$0" "$KEY_NO" >&2 + continue + } + [ "$DRY_RUN" ] || printf 'set ssh pka-dsa key %s\nsave\nexit\n' "$KEY" | ssh -T "$@" >/dev/null 2>&1 + if [ $? = 255 ] ; then + printf '%s: ERROR: installation of key #%d failed (please report a bug describing what caused this, so that we can make this message useful)\n' "$0" "$KEY_NO" >&2 + else + ADDED=$(($ADDED + 1)) + fi + done + if [ -z "$ADDED" ] ; then + exit 1 + fi + ;; + *) + # Assuming that the remote host treats ~/.ssh/authorized_keys as one might expect + populate_new_ids 0 + [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | ssh "$@" " + umask 077 ; + mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; + if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi" \ + || exit 1 + ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l) + ;; +esac + +if [ "$DRY_RUN" ] ; then + cat <<-EOF + =-=-=-=-=-=-=-= + Would have added the following key(s): + + $NEW_IDS + =-=-=-=-=-=-=-= + EOF +else + cat <<-EOF + + Number of key(s) added: $ADDED + + Now try logging into the machine, with: "ssh $SSH_OPTS" + and check to make sure that only the key(s) you wanted were added. + + EOF +fi + +# =-=-=-= diff --git a/crypto/external/bsd/openssh/dist/contrib/ssh-copy-id.1 b/crypto/external/bsd/openssh/dist/contrib/ssh-copy-id.1 new file mode 100644 index 000000000..67a59e492 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/ssh-copy-id.1 @@ -0,0 +1,186 @@ +.ig \" -*- nroff -*- +Copyright (c) 1999-2013 hands.com Ltd. + +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. +.. +.Dd $Mdocdate: June 17 2010 $ +.Dt SSH-COPY-ID 1 +.Os +.Sh NAME +.Nm ssh-copy-id +.Nd use locally available keys to authorise logins on a remote machine +.Sh SYNOPSIS +.Nm +.Op Fl n +.Op Fl i Op Ar identity_file +.Op Fl p Ar port +.Op Fl o Ar ssh_option +.Op Ar user Ns @ Ns +.Ar hostname +.Nm +.Fl h | Fl ? +.br +.Sh DESCRIPTION +.Nm +is a script that uses +.Xr ssh 1 +to log into a remote machine (presumably using a login password, +so password authentication should be enabled, unless you've done some +clever use of multiple identities). It assembles a list of one or more +fingerprints (as described below) and tries to log in with each key, to +see if any of them are already installed (of course, if you are not using +.Xr ssh-agent 1 +this may result in you being repeatedly prompted for pass-phrases). +It then assembles a list of those that failed to log in, and using ssh, +enables logins with those keys on the remote server. By default it adds +the keys by appending them to the remote user's +.Pa ~/.ssh/authorized_keys +(creating the file, and directory, if necessary). It is also capable +of detecting if the remote system is a NetScreen, and using its +.Ql set ssh pka-dsa key ... +command instead. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl i Ar identity_file +Use only the key(s) contained in +.Ar identity_file +(rather than looking for identities via +.Xr ssh-add 1 +or in the +.Ic default_ID_file ) . +If the filename does not end in +.Pa .pub +this is added. If the filename is omitted, the +.Ic default_ID_file +is used. +.Pp +Note that this can be used to ensure that the keys copied have the +comment one prefers and/or extra options applied, by ensuring that the +key file has these set as preferred before the copy is attempted. +.It Fl n +do a dry-run. Instead of installing keys on the remote system simply +prints the key(s) that would have been installed. +.It Fl h , Fl ? +Print Usage summary +.It Fl p Ar port , Fl o Ar ssh_option +These two options are simply passed through untouched, along with their +argument, to allow one to set the port or other +.Xr ssh 1 +options, respectively. +.Pp +Rather than specifying these as command line options, it is often better to use (per-host) settings in +.Xr ssh 1 Ns 's +configuration file: +.Xr ssh_config 5 . +.El +.Pp +Default behaviour without +.Fl i , +is to check if +.Ql ssh-add -L +provides any output, and if so those keys are used. Note that this results in +the comment on the key being the filename that was given to +.Xr ssh-add 1 +when the key was loaded into your +.Xr ssh-agent 1 +rather than the comment contained in that file, which is a bit of a shame. +Otherwise, if +.Xr ssh-add 1 +provides no keys contents of the +.Ic default_ID_file +will be used. +.Pp +The +.Ic default_ID_file +is the most recent file that matches: +.Pa ~/.ssh/id*.pub , +(excluding those that match +.Pa ~/.ssh/*-cert.pub ) +so if you create a key that is not the one you want +.Nm +to use, just use +.Xr touch 1 +on your preferred key's +.Pa .pub +file to reinstate it as the most recent. +.Pp +.Sh EXAMPLES +If you have already installed keys from one system on a lot of remote +hosts, and you then create a new key, on a new client machine, say, +it can be difficult to keep track of which systems on which you've +installed the new key. One way of dealing with this is to load both +the new key and old key(s) into your +.Xr ssh-agent 1 . +Load the new key first, without the +.Fl c +option, then load one or more old keys into the agent, possibly by +ssh-ing to the client machine that has that old key, using the +.Fl A +option to allow agent forwarding: +.Pp +.D1 user@newclient$ ssh-add +.D1 user@newclient$ ssh -A old.client +.D1 user@oldl$ ssh-add -c +.D1 No ... prompt for pass-phrase ... +.D1 user@old$ logoff +.D1 user@newclient$ ssh someserver +.Pp +now, if the new key is installed on the server, you'll be allowed in +unprompted, whereas if you only have the old key(s) enabled, you'll be +asked for confirmation, which is your cue to log back out and run +.Pp +.D1 user@newclient$ ssh-copy-id -i someserver +.Pp +The reason you might want to specify the -i option in this case is to +ensure that the comment on the installed key is the one from the +.Pa .pub +file, rather than just the filename that was loaded into you agent. +It also ensures that only the id you intended is installed, rather than +all the keys that you have in your +.Xr ssh-agent 1 . +Of course, you can specify another id, or use the contents of the +.Xr ssh-agent 1 +as you prefer. +.Pp +Having mentioned +.Xr ssh-add 1 Ns 's +.Fl c +option, you might consider using this whenever using agent forwarding +to avoid your key being hijacked, but it is much better to instead use +.Xr ssh 1 Ns 's +.Ar ProxyCommand +and +.Fl W +option, +to bounce through remote servers while always doing direct end-to-end +authentication. This way the middle hop(s) don't get access to your +.Xr ssh-agent 1 . +A web search for +.Ql ssh proxycommand nc +should prove enlightening (N.B. the modern approach is to use the +.Fl W +option, rather than +.Xr nc 1 ) . +.Sh "SEE ALSO" +.Xr ssh 1 , +.Xr ssh-agent 1 , +.Xr sshd 8 diff --git a/crypto/external/bsd/openssh/dist/contrib/sshd.pam.freebsd b/crypto/external/bsd/openssh/dist/contrib/sshd.pam.freebsd new file mode 100644 index 000000000..c0bc36410 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/sshd.pam.freebsd @@ -0,0 +1,5 @@ +sshd auth required pam_unix.so try_first_pass +sshd account required pam_unix.so +sshd password required pam_permit.so +sshd session required pam_permit.so + diff --git a/crypto/external/bsd/openssh/dist/contrib/sshd.pam.generic b/crypto/external/bsd/openssh/dist/contrib/sshd.pam.generic new file mode 100644 index 000000000..215f0fe30 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/sshd.pam.generic @@ -0,0 +1,8 @@ +#%PAM-1.0 +auth required /lib/security/pam_unix.so shadow nodelay +account required /lib/security/pam_nologin.so +account required /lib/security/pam_unix.so +password required /lib/security/pam_cracklib.so +password required /lib/security/pam_unix.so shadow nullok use_authtok +session required /lib/security/pam_unix.so +session required /lib/security/pam_limits.so diff --git a/crypto/external/bsd/openssh/dist/contrib/suse/openssh.spec b/crypto/external/bsd/openssh/dist/contrib/suse/openssh.spec new file mode 100644 index 000000000..596895882 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/suse/openssh.spec @@ -0,0 +1,243 @@ +# Default values for additional components +%define build_x11_askpass 1 + +# Define the UID/GID to use for privilege separation +%define sshd_gid 65 +%define sshd_uid 71 + +# The version of x11-ssh-askpass to use +%define xversion 1.2.4.1 + +# Allow the ability to override defaults with -D skip_xxx=1 +%{?skip_x11_askpass:%define build_x11_askpass 0} + +Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation +Name: openssh +Version: 7.1p1 +URL: http://www.openssh.com/ +Release: 1 +Source0: openssh-%{version}.tar.gz +Source1: x11-ssh-askpass-%{xversion}.tar.gz +License: BSD +Group: Productivity/Networking/SSH +BuildRoot: %{_tmppath}/openssh-%{version}-buildroot +PreReq: openssl +Obsoletes: ssh +Provides: ssh +# +# (Build[ing] Prereq[uisites] only work for RPM 2.95 and newer.) +# building prerequisites -- stuff for +# OpenSSL (openssl-devel), +# and Gnome (glibdev, gtkdev, and gnlibsd) +# +BuildPrereq: openssl +BuildPrereq: zlib-devel +#BuildPrereq: glibdev +#BuildPrereq: gtkdev +#BuildPrereq: gnlibsd + +%package askpass +Summary: A passphrase dialog for OpenSSH and the X window System. +Group: Productivity/Networking/SSH +Requires: openssh = %{version} +Obsoletes: ssh-extras +Provides: openssh:${_libdir}/ssh/ssh-askpass + +%if %{build_x11_askpass} +BuildPrereq: XFree86-devel +%endif + +%description +Ssh (Secure Shell) is a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +This package includes all files necessary for both the OpenSSH +client and server. + +%description askpass +Ssh (Secure Shell) is a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +This package contains an X Window System passphrase dialog for OpenSSH. + +%changelog +* Wed Oct 26 2005 Iain Morgan +- Removed accidental inclusion of --without-zlib-version-check +* Tue Oct 25 2005 Iain Morgan +- Overhaul to deal with newer versions of SuSE and OpenSSH +* Mon Jun 12 2000 Damien Miller +- Glob manpages to catch compressed files +* Wed Mar 15 2000 Damien Miller +- Updated for new location +- Updated for new gnome-ssh-askpass build +* Sun Dec 26 1999 Chris Saia +- Made symlink to gnome-ssh-askpass called ssh-askpass +* Wed Nov 24 1999 Chris Saia +- Removed patches that included /etc/pam.d/sshd, /sbin/init.d/rc.sshd, and + /var/adm/fillup-templates/rc.config.sshd, since Damien merged these into + his released tarfile +- Changed permissions on ssh_config in the install procedure to 644 from 600 + even though it was correct in the %files section and thus right in the RPMs +- Postinstall script for the server now only prints "Generating SSH host + key..." if we need to actually do this, in order to eliminate a confusing + message if an SSH host key is already in place +- Marked all manual pages as %doc(umentation) +* Mon Nov 22 1999 Chris Saia +- Added flag to configure daemon with TCP Wrappers support +- Added building prerequisites (works in RPM 3.0 and newer) +* Thu Nov 18 1999 Chris Saia +- Made this package correct for SuSE. +- Changed instances of pam_pwdb.so to pam_unix.so, since it works more properly + with SuSE, and lib_pwdb.so isn't installed by default. +* Mon Nov 15 1999 Damien Miller +- Split subpackages further based on patch from jim knoble +* Sat Nov 13 1999 Damien Miller +- Added 'Obsoletes' directives +* Tue Nov 09 1999 Damien Miller +- Use make install +- Subpackages +* Mon Nov 08 1999 Damien Miller +- Added links for slogin +- Fixed perms on manpages +* Sat Oct 30 1999 Damien Miller +- Renamed init script +* Fri Oct 29 1999 Damien Miller +- Back to old binary names +* Thu Oct 28 1999 Damien Miller +- Use autoconf +- New binary names +* Wed Oct 27 1999 Damien Miller +- Initial RPMification, based on Jan "Yenya" Kasprzak's spec. + +%prep + +%if %{build_x11_askpass} +%setup -q -a 1 +%else +%setup -q +%endif + +%build +CFLAGS="$RPM_OPT_FLAGS" \ +%configure --prefix=/usr \ + --sysconfdir=%{_sysconfdir}/ssh \ + --mandir=%{_mandir} \ + --with-privsep-path=/var/lib/empty \ + --with-pam \ + --libexecdir=%{_libdir}/ssh +make + +%if %{build_x11_askpass} +cd x11-ssh-askpass-%{xversion} +%configure --mandir=/usr/X11R6/man \ + --libexecdir=%{_libdir}/ssh +xmkmf -a +make +cd .. +%endif + +%install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT/ +install -d $RPM_BUILD_ROOT/etc/pam.d/ +install -d $RPM_BUILD_ROOT/etc/init.d/ +install -d $RPM_BUILD_ROOT/var/adm/fillup-templates +install -m644 contrib/sshd.pam.generic $RPM_BUILD_ROOT/etc/pam.d/sshd +install -m744 contrib/suse/rc.sshd $RPM_BUILD_ROOT/etc/init.d/sshd +install -m744 contrib/suse/sysconfig.ssh \ + $RPM_BUILD_ROOT/var/adm/fillup-templates + +%if %{build_x11_askpass} +cd x11-ssh-askpass-%{xversion} +make install install.man BINDIR=%{_libdir}/ssh DESTDIR=$RPM_BUILD_ROOT/ +rm -f $RPM_BUILD_ROOT/usr/share/Ssh.bin +%endif + +%clean +rm -rf $RPM_BUILD_ROOT + +%pre +/usr/sbin/groupadd -g %{sshd_gid} -o -r sshd 2> /dev/null || : +/usr/sbin/useradd -r -o -g sshd -u %{sshd_uid} -s /bin/false -c "SSH Privilege Separation User" -d /var/lib/sshd sshd 2> /dev/null || : + +%post +/usr/bin/ssh-keygen -A +%{fillup_and_insserv -n -y ssh sshd} +%run_permissions + +%verifyscript +%verify_permissions -e /etc/ssh/sshd_config -e /etc/ssh/ssh_config -e /usr/bin/ssh + +%preun +%stop_on_removal sshd + +%postun +%restart_on_update sshd +%{insserv_cleanup} + +%files +%defattr(-,root,root) +%doc ChangeLog OVERVIEW README* PROTOCOL* +%doc TODO CREDITS LICENCE +%attr(0755,root,root) %dir %{_sysconfdir}/ssh +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ssh_config +%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/sshd_config +%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/moduli +%attr(0644,root,root) %config(noreplace) /etc/pam.d/sshd +%attr(0755,root,root) %config /etc/init.d/sshd +%attr(0755,root,root) %{_bindir}/ssh-keygen +%attr(0755,root,root) %{_bindir}/scp +%attr(0755,root,root) %{_bindir}/ssh +%attr(-,root,root) %{_bindir}/slogin +%attr(0755,root,root) %{_bindir}/ssh-agent +%attr(0755,root,root) %{_bindir}/ssh-add +%attr(0755,root,root) %{_bindir}/ssh-keyscan +%attr(0755,root,root) %{_bindir}/sftp +%attr(0755,root,root) %{_sbindir}/sshd +%attr(0755,root,root) %dir %{_libdir}/ssh +%attr(0755,root,root) %{_libdir}/ssh/sftp-server +%attr(4711,root,root) %{_libdir}/ssh/ssh-keysign +%attr(0755,root,root) %{_libdir}/ssh/ssh-pkcs11-helper +%attr(0644,root,root) %doc %{_mandir}/man1/scp.1* +%attr(0644,root,root) %doc %{_mandir}/man1/sftp.1* +%attr(-,root,root) %doc %{_mandir}/man1/slogin.1* +%attr(0644,root,root) %doc %{_mandir}/man1/ssh.1* +%attr(0644,root,root) %doc %{_mandir}/man1/ssh-add.1* +%attr(0644,root,root) %doc %{_mandir}/man1/ssh-agent.1* +%attr(0644,root,root) %doc %{_mandir}/man1/ssh-keygen.1* +%attr(0644,root,root) %doc %{_mandir}/man1/ssh-keyscan.1* +%attr(0644,root,root) %doc %{_mandir}/man5/moduli.5* +%attr(0644,root,root) %doc %{_mandir}/man5/ssh_config.5* +%attr(0644,root,root) %doc %{_mandir}/man5/sshd_config.5* +%attr(0644,root,root) %doc %{_mandir}/man8/sftp-server.8* +%attr(0644,root,root) %doc %{_mandir}/man8/ssh-keysign.8* +%attr(0644,root,root) %doc %{_mandir}/man8/ssh-pkcs11-helper.8* +%attr(0644,root,root) %doc %{_mandir}/man8/sshd.8* +%attr(0644,root,root) /var/adm/fillup-templates/sysconfig.ssh + +%if %{build_x11_askpass} +%files askpass +%defattr(-,root,root) +%doc x11-ssh-askpass-%{xversion}/README +%doc x11-ssh-askpass-%{xversion}/ChangeLog +%doc x11-ssh-askpass-%{xversion}/SshAskpass*.ad +%attr(0755,root,root) %{_libdir}/ssh/ssh-askpass +%attr(0755,root,root) %{_libdir}/ssh/x11-ssh-askpass +%attr(0644,root,root) %doc /usr/X11R6/man/man1/ssh-askpass.1x* +%attr(0644,root,root) %doc /usr/X11R6/man/man1/x11-ssh-askpass.1x* +%attr(0644,root,root) %config /usr/X11R6/lib/X11/app-defaults/SshAskpass +%endif diff --git a/crypto/external/bsd/openssh/dist/contrib/suse/rc.config.sshd b/crypto/external/bsd/openssh/dist/contrib/suse/rc.config.sshd new file mode 100644 index 000000000..baaa7a5a1 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/suse/rc.config.sshd @@ -0,0 +1,5 @@ +# +# Start the Secure Shell (SSH) Daemon? +# +START_SSHD="yes" + diff --git a/crypto/external/bsd/openssh/dist/contrib/suse/rc.sshd b/crypto/external/bsd/openssh/dist/contrib/suse/rc.sshd new file mode 100644 index 000000000..28f28e41d --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/suse/rc.sshd @@ -0,0 +1,121 @@ +#! /bin/sh +# Copyright (c) 1995-2000 SuSE GmbH Nuernberg, Germany. +# +# Author: Jiri Smid +# +# /etc/init.d/sshd +# +# and symbolic its link +# +# /usr/sbin/rcsshd +# +### BEGIN INIT INFO +# Provides: sshd +# Required-Start: $network $remote_fs +# Required-Stop: $network $remote_fs +# Default-Start: 3 5 +# Default-Stop: 0 1 2 6 +# Description: Start the sshd daemon +### END INIT INFO + +SSHD_BIN=/usr/sbin/sshd +test -x $SSHD_BIN || exit 5 + +SSHD_SYSCONFIG=/etc/sysconfig/ssh +test -r $SSHD_SYSCONFIG || exit 6 +. $SSHD_SYSCONFIG + +SSHD_PIDFILE=/var/run/sshd.init.pid + +. /etc/rc.status + +# Shell functions sourced from /etc/rc.status: +# rc_check check and set local and overall rc status +# rc_status check and set local and overall rc status +# rc_status -v ditto but be verbose in local rc status +# rc_status -v -r ditto and clear the local rc status +# rc_failed set local and overall rc status to failed +# rc_reset clear local rc status (overall remains) +# rc_exit exit appropriate to overall rc status + +# First reset status of this service +rc_reset + +case "$1" in + start) + # Generate any missing host keys + ssh-keygen -A + echo -n "Starting SSH daemon" + ## Start daemon with startproc(8). If this fails + ## the echo return value is set appropriate. + + startproc -f -p $SSHD_PIDFILE $SSHD_BIN $SSHD_OPTS -o "PidFile=$SSHD_PIDFILE" + + # Remember status and be verbose + rc_status -v + ;; + stop) + echo -n "Shutting down SSH daemon" + ## Stop daemon with killproc(8) and if this fails + ## set echo the echo return value. + + killproc -p $SSHD_PIDFILE -TERM $SSHD_BIN + + # Remember status and be verbose + rc_status -v + ;; + try-restart) + ## Stop the service and if this succeeds (i.e. the + ## service was running before), start it again. + $0 status >/dev/null && $0 restart + + # Remember status and be quiet + rc_status + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + $0 start + + # Remember status and be quiet + rc_status + ;; + force-reload|reload) + ## Signal the daemon to reload its config. Most daemons + ## do this on signal 1 (SIGHUP). + + echo -n "Reload service sshd" + + killproc -p $SSHD_PIDFILE -HUP $SSHD_BIN + + rc_status -v + + ;; + status) + echo -n "Checking for service sshd " + ## Check status with checkproc(8), if process is running + ## checkproc will return with exit status 0. + + # Status has a slightly different for the status command: + # 0 - service running + # 1 - service dead, but /var/run/ pid file exists + # 2 - service dead, but /var/lock/ lock file exists + # 3 - service not running + + checkproc -p $SSHD_PIDFILE $SSHD_BIN + + rc_status -v + ;; + probe) + ## Optional: Probe for the necessity of a reload, + ## give out the argument which is required for a reload. + + test /etc/ssh/sshd_config -nt $SSHD_PIDFILE && echo reload + ;; + *) + echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe}" + exit 1 + ;; +esac +rc_exit diff --git a/crypto/external/bsd/openssh/dist/contrib/suse/sysconfig.ssh b/crypto/external/bsd/openssh/dist/contrib/suse/sysconfig.ssh new file mode 100644 index 000000000..c6a37e5cb --- /dev/null +++ b/crypto/external/bsd/openssh/dist/contrib/suse/sysconfig.ssh @@ -0,0 +1,9 @@ +## Path: Network/Remote access/SSH +## Description: SSH server settings +## Type: string +## Default: "" +## ServiceRestart: sshd +# +# Options for sshd +# +SSHD_OPTS="" diff --git a/crypto/external/bsd/openssh/dist/defines.h b/crypto/external/bsd/openssh/dist/defines.h new file mode 100644 index 000000000..fa0ccba7c --- /dev/null +++ b/crypto/external/bsd/openssh/dist/defines.h @@ -0,0 +1,853 @@ +/* + * Copyright (c) 1999-2003 Damien Miller. 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. + */ + +#ifndef _DEFINES_H +#define _DEFINES_H + +/* $Id: defines.h,v 1.183 2014/09/02 19:33:26 djm Exp $ */ + + +/* Constants */ + +#if defined(HAVE_DECL_SHUT_RD) && HAVE_DECL_SHUT_RD == 0 +enum +{ + SHUT_RD = 0, /* No more receptions. */ + SHUT_WR, /* No more transmissions. */ + SHUT_RDWR /* No more receptions or transmissions. */ +}; +# define SHUT_RD SHUT_RD +# define SHUT_WR SHUT_WR +# define SHUT_RDWR SHUT_RDWR +#endif + +/* + * Definitions for IP type of service (ip_tos) + */ +#include +#include +#ifndef IPTOS_LOWDELAY +# define IPTOS_LOWDELAY 0x10 +# define IPTOS_THROUGHPUT 0x08 +# define IPTOS_RELIABILITY 0x04 +# define IPTOS_LOWCOST 0x02 +# define IPTOS_MINCOST IPTOS_LOWCOST +#endif /* IPTOS_LOWDELAY */ + +/* + * Definitions for DiffServ Codepoints as per RFC2474 + */ +#ifndef IPTOS_DSCP_AF11 +# define IPTOS_DSCP_AF11 0x28 +# define IPTOS_DSCP_AF12 0x30 +# define IPTOS_DSCP_AF13 0x38 +# define IPTOS_DSCP_AF21 0x48 +# define IPTOS_DSCP_AF22 0x50 +# define IPTOS_DSCP_AF23 0x58 +# define IPTOS_DSCP_AF31 0x68 +# define IPTOS_DSCP_AF32 0x70 +# define IPTOS_DSCP_AF33 0x78 +# define IPTOS_DSCP_AF41 0x88 +# define IPTOS_DSCP_AF42 0x90 +# define IPTOS_DSCP_AF43 0x98 +# define IPTOS_DSCP_EF 0xb8 +#endif /* IPTOS_DSCP_AF11 */ +#ifndef IPTOS_DSCP_CS0 +# define IPTOS_DSCP_CS0 0x00 +# define IPTOS_DSCP_CS1 0x20 +# define IPTOS_DSCP_CS2 0x40 +# define IPTOS_DSCP_CS3 0x60 +# define IPTOS_DSCP_CS4 0x80 +# define IPTOS_DSCP_CS5 0xa0 +# define IPTOS_DSCP_CS6 0xc0 +# define IPTOS_DSCP_CS7 0xe0 +#endif /* IPTOS_DSCP_CS0 */ +#ifndef IPTOS_DSCP_EF +# define IPTOS_DSCP_EF 0xb8 +#endif /* IPTOS_DSCP_EF */ + +#ifndef PATH_MAX +# ifdef _POSIX_PATH_MAX +# define PATH_MAX _POSIX_PATH_MAX +# endif +#endif + +#ifndef MAXPATHLEN +# ifdef PATH_MAX +# define MAXPATHLEN PATH_MAX +# else /* PATH_MAX */ +# define MAXPATHLEN 64 +/* realpath uses a fixed buffer of size MAXPATHLEN, so force use of ours */ +# ifndef BROKEN_REALPATH +# define BROKEN_REALPATH 1 +# endif /* BROKEN_REALPATH */ +# endif /* PATH_MAX */ +#endif /* MAXPATHLEN */ + +#ifndef HOST_NAME_MAX +# include "netdb.h" /* for MAXHOSTNAMELEN */ +# if defined(_POSIX_HOST_NAME_MAX) +# define HOST_NAME_MAX _POSIX_HOST_NAME_MAX +# elif defined(MAXHOSTNAMELEN) +# define HOST_NAME_MAX MAXHOSTNAMELEN +# else +# define HOST_NAME_MAX 255 +# endif +#endif /* HOST_NAME_MAX */ + +#if defined(HAVE_DECL_MAXSYMLINKS) && HAVE_DECL_MAXSYMLINKS == 0 +# define MAXSYMLINKS 5 +#endif + +#ifndef STDIN_FILENO +# define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO +# define STDOUT_FILENO 1 +#endif +#ifndef STDERR_FILENO +# define STDERR_FILENO 2 +#endif + +#ifndef NGROUPS_MAX /* Disable groupaccess if NGROUP_MAX is not set */ +#ifdef NGROUPS +#define NGROUPS_MAX NGROUPS +#else +#define NGROUPS_MAX 0 +#endif +#endif + +#if defined(HAVE_DECL_O_NONBLOCK) && HAVE_DECL_O_NONBLOCK == 0 +# define O_NONBLOCK 00004 /* Non Blocking Open */ +#endif + +#ifndef S_IFSOCK +# define S_IFSOCK 0 +#endif /* S_IFSOCK */ + +#ifndef S_ISDIR +# define S_ISDIR(mode) (((mode) & (_S_IFMT)) == (_S_IFDIR)) +#endif /* S_ISDIR */ + +#ifndef S_ISREG +# define S_ISREG(mode) (((mode) & (_S_IFMT)) == (_S_IFREG)) +#endif /* S_ISREG */ + +#ifndef S_ISLNK +# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) +#endif /* S_ISLNK */ + +#ifndef S_IXUSR +# define S_IXUSR 0000100 /* execute/search permission, */ +# define S_IXGRP 0000010 /* execute/search permission, */ +# define S_IXOTH 0000001 /* execute/search permission, */ +# define _S_IWUSR 0000200 /* write permission, */ +# define S_IWUSR _S_IWUSR /* write permission, owner */ +# define S_IWGRP 0000020 /* write permission, group */ +# define S_IWOTH 0000002 /* write permission, other */ +# define S_IRUSR 0000400 /* read permission, owner */ +# define S_IRGRP 0000040 /* read permission, group */ +# define S_IROTH 0000004 /* read permission, other */ +# define S_IRWXU 0000700 /* read, write, execute */ +# define S_IRWXG 0000070 /* read, write, execute */ +# define S_IRWXO 0000007 /* read, write, execute */ +#endif /* S_IXUSR */ + +#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS) +#define MAP_ANON MAP_ANONYMOUS +#endif + +#ifndef MAP_FAILED +# define MAP_FAILED ((void *)-1) +#endif + +/* +SCO Open Server 3 has INADDR_LOOPBACK defined in rpc/rpc.h but +including rpc/rpc.h breaks Solaris 6 +*/ +#ifndef INADDR_LOOPBACK +#define INADDR_LOOPBACK ((u_long)0x7f000001) +#endif + +/* Types */ + +/* If sys/types.h does not supply intXX_t, supply them ourselves */ +/* (or die trying) */ + +#ifndef HAVE_U_INT +typedef unsigned int u_int; +#endif + +#ifndef HAVE_INTXX_T +typedef signed char int8_t; +# if (SIZEOF_SHORT_INT == 2) +typedef short int int16_t; +# else +# ifdef _UNICOS +# if (SIZEOF_SHORT_INT == 4) +typedef short int16_t; +# else +typedef long int16_t; +# endif +# else +# error "16 bit int type not found." +# endif /* _UNICOS */ +# endif +# if (SIZEOF_INT == 4) +typedef int int32_t; +# else +# ifdef _UNICOS +typedef long int32_t; +# else +# error "32 bit int type not found." +# endif /* _UNICOS */ +# endif +#endif + +/* If sys/types.h does not supply u_intXX_t, supply them ourselves */ +#ifndef HAVE_U_INTXX_T +# ifdef HAVE_UINTXX_T +typedef uint8_t u_int8_t; +typedef uint16_t u_int16_t; +typedef uint32_t u_int32_t; +# define HAVE_U_INTXX_T 1 +# else +typedef unsigned char u_int8_t; +# if (SIZEOF_SHORT_INT == 2) +typedef unsigned short int u_int16_t; +# else +# ifdef _UNICOS +# if (SIZEOF_SHORT_INT == 4) +typedef unsigned short u_int16_t; +# else +typedef unsigned long u_int16_t; +# endif +# else +# error "16 bit int type not found." +# endif +# endif +# if (SIZEOF_INT == 4) +typedef unsigned int u_int32_t; +# else +# ifdef _UNICOS +typedef unsigned long u_int32_t; +# else +# error "32 bit int type not found." +# endif +# endif +# endif +#define __BIT_TYPES_DEFINED__ +#endif + +/* 64-bit types */ +#ifndef HAVE_INT64_T +# if (SIZEOF_LONG_INT == 8) +typedef long int int64_t; +# else +# if (SIZEOF_LONG_LONG_INT == 8) +typedef long long int int64_t; +# endif +# endif +#endif +#ifndef HAVE_U_INT64_T +# if (SIZEOF_LONG_INT == 8) +typedef unsigned long int u_int64_t; +# else +# if (SIZEOF_LONG_LONG_INT == 8) +typedef unsigned long long int u_int64_t; +# endif +# endif +#endif + +#ifndef HAVE_UINTXX_T +typedef u_int8_t uint8_t; +typedef u_int16_t uint16_t; +typedef u_int32_t uint32_t; +typedef u_int64_t uint64_t; +#endif + +#ifndef HAVE_INTMAX_T +typedef long long intmax_t; +#endif + +#ifndef HAVE_UINTMAX_T +typedef unsigned long long uintmax_t; +#endif + +#ifndef HAVE_U_CHAR +typedef unsigned char u_char; +# define HAVE_U_CHAR +#endif /* HAVE_U_CHAR */ + +#ifndef ULLONG_MAX +# define ULLONG_MAX ((unsigned long long)-1) +#endif + +#ifndef SIZE_T_MAX +#define SIZE_T_MAX ULONG_MAX +#endif /* SIZE_T_MAX */ + +#ifndef HAVE_SIZE_T +typedef unsigned int size_t; +# define HAVE_SIZE_T +# define SIZE_T_MAX UINT_MAX +#endif /* HAVE_SIZE_T */ + +#ifndef SIZE_MAX +#define SIZE_MAX SIZE_T_MAX +#endif + +#ifndef HAVE_SSIZE_T +typedef int ssize_t; +# define HAVE_SSIZE_T +#endif /* HAVE_SSIZE_T */ + +#ifndef HAVE_CLOCK_T +typedef long clock_t; +# define HAVE_CLOCK_T +#endif /* HAVE_CLOCK_T */ + +#ifndef HAVE_SA_FAMILY_T +typedef int sa_family_t; +# define HAVE_SA_FAMILY_T +#endif /* HAVE_SA_FAMILY_T */ + +#ifndef HAVE_PID_T +typedef int pid_t; +# define HAVE_PID_T +#endif /* HAVE_PID_T */ + +#ifndef HAVE_SIG_ATOMIC_T +typedef int sig_atomic_t; +# define HAVE_SIG_ATOMIC_T +#endif /* HAVE_SIG_ATOMIC_T */ + +#ifndef HAVE_MODE_T +typedef int mode_t; +# define HAVE_MODE_T +#endif /* HAVE_MODE_T */ + +#if !defined(HAVE_SS_FAMILY_IN_SS) && defined(HAVE___SS_FAMILY_IN_SS) +# define ss_family __ss_family +#endif /* !defined(HAVE_SS_FAMILY_IN_SS) && defined(HAVE_SA_FAMILY_IN_SS) */ + +#ifndef HAVE_SYS_UN_H +struct sockaddr_un { + short sun_family; /* AF_UNIX */ + char sun_path[108]; /* path name (gag) */ +}; +#endif /* HAVE_SYS_UN_H */ + +#ifndef HAVE_IN_ADDR_T +typedef u_int32_t in_addr_t; +#endif +#ifndef HAVE_IN_PORT_T +typedef u_int16_t in_port_t; +#endif + +#if defined(BROKEN_SYS_TERMIO_H) && !defined(_STRUCT_WINSIZE) +#define _STRUCT_WINSIZE +struct winsize { + unsigned short ws_row; /* rows, in characters */ + unsigned short ws_col; /* columns, in character */ + unsigned short ws_xpixel; /* horizontal size, pixels */ + unsigned short ws_ypixel; /* vertical size, pixels */ +}; +#endif + +/* bits needed for select that may not be in the system headers */ +#ifndef HAVE_FD_MASK + typedef unsigned long int fd_mask; +#endif + +#if defined(HAVE_DECL_NFDBITS) && HAVE_DECL_NFDBITS == 0 +# define NFDBITS (8 * sizeof(unsigned long)) +#endif + +#if defined(HAVE_DECL_HOWMANY) && HAVE_DECL_HOWMANY == 0 +# define howmany(x,y) (((x)+((y)-1))/(y)) +#endif + +/* Paths */ + +#ifndef _PATH_BSHELL +# define _PATH_BSHELL "/bin/sh" +#endif + +#ifdef USER_PATH +# ifdef _PATH_STDPATH +# undef _PATH_STDPATH +# endif +# define _PATH_STDPATH USER_PATH +#endif + +#ifndef _PATH_STDPATH +# define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin" +#endif + +#ifndef SUPERUSER_PATH +# define SUPERUSER_PATH _PATH_STDPATH +#endif + +#ifndef _PATH_DEVNULL +# define _PATH_DEVNULL "/dev/null" +#endif + +/* user may have set a different path */ +#if defined(_PATH_MAILDIR) && defined(MAIL_DIRECTORY) +# undef _PATH_MAILDIR +#endif /* defined(_PATH_MAILDIR) && defined(MAIL_DIRECTORY) */ + +#ifdef MAIL_DIRECTORY +# define _PATH_MAILDIR MAIL_DIRECTORY +#endif + +#ifndef _PATH_NOLOGIN +# define _PATH_NOLOGIN "/etc/nologin" +#endif + +/* Define this to be the path of the xauth program. */ +#ifdef XAUTH_PATH +#define _PATH_XAUTH XAUTH_PATH +#endif /* XAUTH_PATH */ + +/* derived from XF4/xc/lib/dps/Xlibnet.h */ +#ifndef X_UNIX_PATH +# ifdef __hpux +# define X_UNIX_PATH "/var/spool/sockets/X11/%u" +# else +# define X_UNIX_PATH "/tmp/.X11-unix/X%u" +# endif +#endif /* X_UNIX_PATH */ +#define _PATH_UNIX_X X_UNIX_PATH + +#ifndef _PATH_TTY +# define _PATH_TTY "/dev/tty" +#endif + +/* Macros */ + +#if defined(HAVE_LOGIN_GETCAPBOOL) && defined(HAVE_LOGIN_CAP_H) +# define HAVE_LOGIN_CAP +#endif + +#ifndef MAX +# define MAX(a,b) (((a)>(b))?(a):(b)) +# define MIN(a,b) (((a)<(b))?(a):(b)) +#endif + +#ifndef roundup +# define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) +#endif + +#ifndef timersub +#define timersub(a, b, result) \ + do { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000; \ + } \ + } while (0) +#endif + +#ifndef TIMEVAL_TO_TIMESPEC +#define TIMEVAL_TO_TIMESPEC(tv, ts) { \ + (ts)->tv_sec = (tv)->tv_sec; \ + (ts)->tv_nsec = (tv)->tv_usec * 1000; \ +} +#endif + +#ifndef TIMESPEC_TO_TIMEVAL +#define TIMESPEC_TO_TIMEVAL(tv, ts) { \ + (tv)->tv_sec = (ts)->tv_sec; \ + (tv)->tv_usec = (ts)->tv_nsec / 1000; \ +} +#endif + +#ifndef __P +# define __P(x) x +#endif + +#if !defined(IN6_IS_ADDR_V4MAPPED) +# define IN6_IS_ADDR_V4MAPPED(a) \ + ((((u_int32_t *) (a))[0] == 0) && (((u_int32_t *) (a))[1] == 0) && \ + (((u_int32_t *) (a))[2] == htonl (0xffff))) +#endif /* !defined(IN6_IS_ADDR_V4MAPPED) */ + +#if !defined(__GNUC__) || (__GNUC__ < 2) +# define __attribute__(x) +#endif /* !defined(__GNUC__) || (__GNUC__ < 2) */ + +#if !defined(HAVE_ATTRIBUTE__SENTINEL__) && !defined(__sentinel__) +# define __sentinel__ +#endif + +#if !defined(HAVE_ATTRIBUTE__BOUNDED__) && !defined(__bounded__) +# define __bounded__(x, y, z) +#endif + +#if !defined(HAVE_ATTRIBUTE__NONNULL__) && !defined(__nonnull__) +# define __nonnull__(x) +#endif + +#ifndef OSSH_ALIGNBYTES +#define OSSH_ALIGNBYTES (sizeof(int) - 1) +#endif +#ifndef __CMSG_ALIGN +#define __CMSG_ALIGN(p) (((u_int)(p) + OSSH_ALIGNBYTES) &~ OSSH_ALIGNBYTES) +#endif + +/* Length of the contents of a control message of length len */ +#ifndef CMSG_LEN +#define CMSG_LEN(len) (__CMSG_ALIGN(sizeof(struct cmsghdr)) + (len)) +#endif + +/* Length of the space taken up by a padded control message of length len */ +#ifndef CMSG_SPACE +#define CMSG_SPACE(len) (__CMSG_ALIGN(sizeof(struct cmsghdr)) + __CMSG_ALIGN(len)) +#endif + +/* given pointer to struct cmsghdr, return pointer to data */ +#ifndef CMSG_DATA +#define CMSG_DATA(cmsg) ((u_char *)(cmsg) + __CMSG_ALIGN(sizeof(struct cmsghdr))) +#endif /* CMSG_DATA */ + +/* + * RFC 2292 requires to check msg_controllen, in case that the kernel returns + * an empty list for some reasons. + */ +#ifndef CMSG_FIRSTHDR +#define CMSG_FIRSTHDR(mhdr) \ + ((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \ + (struct cmsghdr *)(mhdr)->msg_control : \ + (struct cmsghdr *)NULL) +#endif /* CMSG_FIRSTHDR */ + +#if defined(HAVE_DECL_OFFSETOF) && HAVE_DECL_OFFSETOF == 0 +# define offsetof(type, member) ((size_t) &((type *)0)->member) +#endif + +/* Set up BSD-style BYTE_ORDER definition if it isn't there already */ +/* XXX: doesn't try to cope with strange byte orders (PDP_ENDIAN) */ +#ifndef BYTE_ORDER +# ifndef LITTLE_ENDIAN +# define LITTLE_ENDIAN 1234 +# endif /* LITTLE_ENDIAN */ +# ifndef BIG_ENDIAN +# define BIG_ENDIAN 4321 +# endif /* BIG_ENDIAN */ +# ifdef WORDS_BIGENDIAN +# define BYTE_ORDER BIG_ENDIAN +# else /* WORDS_BIGENDIAN */ +# define BYTE_ORDER LITTLE_ENDIAN +# endif /* WORDS_BIGENDIAN */ +#endif /* BYTE_ORDER */ + +/* Function replacement / compatibility hacks */ + +#if !defined(HAVE_GETADDRINFO) && (defined(HAVE_OGETADDRINFO) || defined(HAVE_NGETADDRINFO)) +# define HAVE_GETADDRINFO +#endif + +#ifndef HAVE_GETOPT_OPTRESET +# undef getopt +# undef opterr +# undef optind +# undef optopt +# undef optreset +# undef optarg +# define getopt(ac, av, o) BSDgetopt(ac, av, o) +# define opterr BSDopterr +# define optind BSDoptind +# define optopt BSDoptopt +# define optreset BSDoptreset +# define optarg BSDoptarg +#endif + +#if defined(BROKEN_GETADDRINFO) && defined(HAVE_GETADDRINFO) +# undef HAVE_GETADDRINFO +#endif +#if defined(BROKEN_GETADDRINFO) && defined(HAVE_FREEADDRINFO) +# undef HAVE_FREEADDRINFO +#endif +#if defined(BROKEN_GETADDRINFO) && defined(HAVE_GAI_STRERROR) +# undef HAVE_GAI_STRERROR +#endif + +#if defined(HAVE_GETADDRINFO) +# if defined(HAVE_DECL_AI_NUMERICSERV) && HAVE_DECL_AI_NUMERICSERV == 0 +# define AI_NUMERICSERV 0 +# endif +#endif + +#if defined(BROKEN_UPDWTMPX) && defined(HAVE_UPDWTMPX) +# undef HAVE_UPDWTMPX +#endif + +#if defined(BROKEN_SHADOW_EXPIRE) && defined(HAS_SHADOW_EXPIRE) +# undef HAS_SHADOW_EXPIRE +#endif + +#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) && \ + defined(SYSLOG_R_SAFE_IN_SIGHAND) +# define DO_LOG_SAFE_IN_SIGHAND +#endif + +#if !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY) +# define memmove(s1, s2, n) bcopy((s2), (s1), (n)) +#endif /* !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY) */ + +#ifndef GETPGRP_VOID +# include +# define getpgrp() getpgrp(0) +#endif + +#ifdef USE_BSM_AUDIT +# define SSH_AUDIT_EVENTS +# define CUSTOM_SSH_AUDIT_EVENTS +#endif + +#ifdef USE_LINUX_AUDIT +# define SSH_AUDIT_EVENTS +# define CUSTOM_SSH_AUDIT_EVENTS +#endif + +#if !defined(HAVE___func__) && defined(HAVE___FUNCTION__) +# define __func__ __FUNCTION__ +#elif !defined(HAVE___func__) +# define __func__ "" +#endif + +#if defined(KRB5) && !defined(HEIMDAL) +# define krb5_get_err_text(context,code) error_message(code) +#endif + +#if defined(SKEYCHALLENGE_4ARG) +# define _compat_skeychallenge(a,b,c,d) skeychallenge(a,b,c,d) +#else +# define _compat_skeychallenge(a,b,c,d) skeychallenge(a,b,c) +#endif + +/* Maximum number of file descriptors available */ +#ifdef HAVE_SYSCONF +# define SSH_SYSFDMAX sysconf(_SC_OPEN_MAX) +#else +# define SSH_SYSFDMAX 10000 +#endif + +#ifdef FSID_HAS_VAL +/* encode f_fsid into a 64 bit value */ +#define FSID_TO_ULONG(f) \ + ((((u_int64_t)(f).val[0] & 0xffffffffUL) << 32) | \ + ((f).val[1] & 0xffffffffUL)) +#elif defined(FSID_HAS___VAL) +#define FSID_TO_ULONG(f) \ + ((((u_int64_t)(f).__val[0] & 0xffffffffUL) << 32) | \ + ((f).__val[1] & 0xffffffffUL)) +#else +# define FSID_TO_ULONG(f) ((f)) +#endif + +#if defined(__Lynx__) + /* + * LynxOS defines these in param.h which we do not want to include since + * it will also pull in a bunch of kernel definitions. + */ +# define ALIGNBYTES (sizeof(int) - 1) +# define ALIGN(p) (((unsigned)p + ALIGNBYTES) & ~ALIGNBYTES) + /* Missing prototypes on LynxOS */ + int snprintf (char *, size_t, const char *, ...); + int mkstemp (char *); + char *crypt (const char *, const char *); + int seteuid (uid_t); + int setegid (gid_t); + char *mkdtemp (char *); + int rresvport_af (int *, sa_family_t); + int innetgr (const char *, const char *, const char *, const char *); +#endif + +/* + * Define this to use pipes instead of socketpairs for communicating with the + * client program. Socketpairs do not seem to work on all systems. + * + * configure.ac sets this for a few OS's which are known to have problems + * but you may need to set it yourself + */ +/* #define USE_PIPES 1 */ + +/** + ** login recorder definitions + **/ + +/* FIXME: put default paths back in */ +#ifndef UTMP_FILE +# ifdef _PATH_UTMP +# define UTMP_FILE _PATH_UTMP +# else +# ifdef CONF_UTMP_FILE +# define UTMP_FILE CONF_UTMP_FILE +# endif +# endif +#endif +#ifndef WTMP_FILE +# ifdef _PATH_WTMP +# define WTMP_FILE _PATH_WTMP +# else +# ifdef CONF_WTMP_FILE +# define WTMP_FILE CONF_WTMP_FILE +# endif +# endif +#endif +/* pick up the user's location for lastlog if given */ +#ifndef LASTLOG_FILE +# ifdef _PATH_LASTLOG +# define LASTLOG_FILE _PATH_LASTLOG +# else +# ifdef CONF_LASTLOG_FILE +# define LASTLOG_FILE CONF_LASTLOG_FILE +# endif +# endif +#endif + +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) +# define USE_SHADOW +#endif + +/* The login() library function in libutil is first choice */ +#if defined(HAVE_LOGIN) && !defined(DISABLE_LOGIN) +# define USE_LOGIN + +#else +/* Simply select your favourite login types. */ +/* Can't do if-else because some systems use several... */ +# if !defined(DISABLE_UTMPX) +# define USE_UTMPX +# endif +# if defined(UTMP_FILE) && !defined(DISABLE_UTMP) +# define USE_UTMP +# endif +# if defined(WTMPX_FILE) && !defined(DISABLE_WTMPX) +# define USE_WTMPX +# endif +# if defined(WTMP_FILE) && !defined(DISABLE_WTMP) +# define USE_WTMP +# endif + +#endif + +#ifndef UT_LINESIZE +# define UT_LINESIZE 8 +#endif + +/* I hope that the presence of LASTLOG_FILE is enough to detect this */ +#if defined(LASTLOG_FILE) && !defined(DISABLE_LASTLOG) +# define USE_LASTLOG +#endif + +#ifdef HAVE_OSF_SIA +# ifdef USE_SHADOW +# undef USE_SHADOW +# endif +# define CUSTOM_SYS_AUTH_PASSWD 1 +#endif + +#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) && !defined(HAVE_SECUREWARE) +# define CUSTOM_SYS_AUTH_PASSWD 1 +#endif +#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) && !defined(BROKEN_LIBIAF) +# define USE_LIBIAF +#endif + +/* HP-UX 11.11 */ +#ifdef BTMP_FILE +# define _PATH_BTMP BTMP_FILE +#endif + +#if defined(USE_BTMP) && defined(_PATH_BTMP) +# define CUSTOM_FAILED_LOGIN +#endif + +/** end of login recorder definitions */ + +#ifdef BROKEN_GETGROUPS +# define getgroups(a,b) ((a)==0 && (b)==NULL ? NGROUPS_MAX : getgroups((a),(b))) +#endif + +#if defined(HAVE_MMAP) && defined(BROKEN_MMAP) +# undef HAVE_MMAP +#endif + +#ifndef IOV_MAX +# if defined(_XOPEN_IOV_MAX) +# define IOV_MAX _XOPEN_IOV_MAX +# elif defined(DEF_IOV_MAX) +# define IOV_MAX DEF_IOV_MAX +# else +# define IOV_MAX 16 +# endif +#endif + +#ifndef EWOULDBLOCK +# define EWOULDBLOCK EAGAIN +#endif + +#ifndef INET6_ADDRSTRLEN /* for non IPv6 machines */ +#define INET6_ADDRSTRLEN 46 +#endif + +#ifndef SSH_IOBUFSZ +# define SSH_IOBUFSZ 8192 +#endif + +/* + * Platforms that have arc4random_uniform() and not arc4random_stir() + * shouldn't need the latter. + */ +#if defined(HAVE_ARC4RANDOM) && defined(HAVE_ARC4RANDOM_UNIFORM) && \ + !defined(HAVE_ARC4RANDOM_STIR) +# define arc4random_stir() +#endif + +#ifndef HAVE_VA_COPY +# ifdef HAVE___VA_COPY +# define va_copy(dest, src) __va_copy(dest, src) +# else +# define va_copy(dest, src) (dest) = (src) +# endif +#endif + +#ifndef __predict_true +# if defined(__GNUC__) && \ + ((__GNUC__ > (2)) || (__GNUC__ == (2) && __GNUC_MINOR__ >= (96))) +# define __predict_true(exp) __builtin_expect(((exp) != 0), 1) +# define __predict_false(exp) __builtin_expect(((exp) != 0), 0) +# else +# define __predict_true(exp) ((exp) != 0) +# define __predict_false(exp) ((exp) != 0) +# endif /* gcc version */ +#endif /* __predict_true */ + +#endif /* _DEFINES_H */ diff --git a/crypto/external/bsd/openssh/dist/entropy.c b/crypto/external/bsd/openssh/dist/entropy.c new file mode 100644 index 000000000..9305f89ae --- /dev/null +++ b/crypto/external/bsd/openssh/dist/entropy.c @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2001 Damien Miller. 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" + +#ifdef WITH_OPENSSL + +#include +#include +#ifdef HAVE_SYS_UN_H +# include +#endif + +#include +#include + +#include +#include +#include +#include +#include /* for offsetof */ + +#include +#include +#include + +#include "openbsd-compat/openssl-compat.h" + +#include "ssh.h" +#include "misc.h" +#include "xmalloc.h" +#include "atomicio.h" +#include "pathnames.h" +#include "log.h" +#include "buffer.h" + +/* + * Portable OpenSSH PRNG seeding: + * If OpenSSL has not "internally seeded" itself (e.g. pulled data from + * /dev/random), then collect RANDOM_SEED_SIZE bytes of randomness from + * PRNGd. + */ +#ifndef OPENSSL_PRNG_ONLY + +#define RANDOM_SEED_SIZE 48 + +/* + * Collect 'len' bytes of entropy into 'buf' from PRNGD/EGD daemon + * listening either on 'tcp_port', or via Unix domain socket at * + * 'socket_path'. + * Either a non-zero tcp_port or a non-null socket_path must be + * supplied. + * Returns 0 on success, -1 on error + */ +int +get_random_bytes_prngd(unsigned char *buf, int len, + unsigned short tcp_port, char *socket_path) +{ + int fd, addr_len, rval, errors; + u_char msg[2]; + struct sockaddr_storage addr; + struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr; + struct sockaddr_un *addr_un = (struct sockaddr_un *)&addr; + mysig_t old_sigpipe; + + /* Sanity checks */ + if (socket_path == NULL && tcp_port == 0) + fatal("You must specify a port or a socket"); + if (socket_path != NULL && + strlen(socket_path) >= sizeof(addr_un->sun_path)) + fatal("Random pool path is too long"); + if (len <= 0 || len > 255) + fatal("Too many bytes (%d) to read from PRNGD", len); + + memset(&addr, '\0', sizeof(addr)); + + if (tcp_port != 0) { + addr_in->sin_family = AF_INET; + addr_in->sin_addr.s_addr = htonl(INADDR_LOOPBACK); + addr_in->sin_port = htons(tcp_port); + addr_len = sizeof(*addr_in); + } else { + addr_un->sun_family = AF_UNIX; + strlcpy(addr_un->sun_path, socket_path, + sizeof(addr_un->sun_path)); + addr_len = offsetof(struct sockaddr_un, sun_path) + + strlen(socket_path) + 1; + } + + old_sigpipe = mysignal(SIGPIPE, SIG_IGN); + + errors = 0; + rval = -1; +reopen: + fd = socket(addr.ss_family, SOCK_STREAM, 0); + if (fd == -1) { + error("Couldn't create socket: %s", strerror(errno)); + goto done; + } + + if (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) { + if (tcp_port != 0) { + error("Couldn't connect to PRNGD port %d: %s", + tcp_port, strerror(errno)); + } else { + error("Couldn't connect to PRNGD socket \"%s\": %s", + addr_un->sun_path, strerror(errno)); + } + goto done; + } + + /* Send blocking read request to PRNGD */ + msg[0] = 0x02; + msg[1] = len; + + if (atomicio(vwrite, fd, msg, sizeof(msg)) != sizeof(msg)) { + if (errno == EPIPE && errors < 10) { + close(fd); + errors++; + goto reopen; + } + error("Couldn't write to PRNGD socket: %s", + strerror(errno)); + goto done; + } + + if (atomicio(read, fd, buf, len) != (size_t)len) { + if (errno == EPIPE && errors < 10) { + close(fd); + errors++; + goto reopen; + } + error("Couldn't read from PRNGD socket: %s", + strerror(errno)); + goto done; + } + + rval = 0; +done: + mysignal(SIGPIPE, old_sigpipe); + if (fd != -1) + close(fd); + return rval; +} + +static int +seed_from_prngd(unsigned char *buf, size_t bytes) +{ +#ifdef PRNGD_PORT + debug("trying egd/prngd port %d", PRNGD_PORT); + if (get_random_bytes_prngd(buf, bytes, PRNGD_PORT, NULL) == 0) + return 0; +#endif +#ifdef PRNGD_SOCKET + debug("trying egd/prngd socket %s", PRNGD_SOCKET); + if (get_random_bytes_prngd(buf, bytes, 0, PRNGD_SOCKET) == 0) + return 0; +#endif + return -1; +} + +void +rexec_send_rng_seed(Buffer *m) +{ + u_char buf[RANDOM_SEED_SIZE]; + + if (RAND_bytes(buf, sizeof(buf)) <= 0) { + error("Couldn't obtain random bytes (error %ld)", + ERR_get_error()); + buffer_put_string(m, "", 0); + } else + buffer_put_string(m, buf, sizeof(buf)); +} + +void +rexec_recv_rng_seed(Buffer *m) +{ + u_char *buf; + u_int len; + + buf = buffer_get_string_ret(m, &len); + if (buf != NULL) { + debug3("rexec_recv_rng_seed: seeding rng with %u bytes", len); + RAND_add(buf, len, len); + } +} +#endif /* OPENSSL_PRNG_ONLY */ + +void +seed_rng(void) +{ +#ifndef OPENSSL_PRNG_ONLY + unsigned char buf[RANDOM_SEED_SIZE]; +#endif + if (!ssh_compatible_openssl(OPENSSL_VERSION_NUMBER, SSLeay())) + fatal("OpenSSL version mismatch. Built against %lx, you " + "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); + +#ifndef OPENSSL_PRNG_ONLY + if (RAND_status() == 1) { + debug3("RNG is ready, skipping seeding"); + return; + } + + if (seed_from_prngd(buf, sizeof(buf)) == -1) + fatal("Could not obtain seed from PRNGd"); + RAND_add(buf, sizeof(buf), sizeof(buf)); + memset(buf, '\0', sizeof(buf)); + +#endif /* OPENSSL_PRNG_ONLY */ + if (RAND_status() != 1) + fatal("PRNG is not seeded"); +} + +#else /* WITH_OPENSSL */ + +/* Handled in arc4random() */ +void +seed_rng(void) +{ +} + +#endif /* WITH_OPENSSL */ diff --git a/crypto/external/bsd/openssh/dist/entropy.h b/crypto/external/bsd/openssh/dist/entropy.h new file mode 100644 index 000000000..c3d78dbad --- /dev/null +++ b/crypto/external/bsd/openssh/dist/entropy.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 1999-2000 Damien Miller. 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. + */ + +/* $Id: entropy.h,v 1.6 2011/09/09 01:29:41 dtucker Exp $ */ + +#ifndef _RANDOMS_H +#define _RANDOMS_H + +#include "buffer.h" + +void seed_rng(void); + +void rexec_send_rng_seed(Buffer *); +void rexec_recv_rng_seed(Buffer *); + +#endif /* _RANDOMS_H */ diff --git a/crypto/external/bsd/openssh/dist/explicit_bzero.c b/crypto/external/bsd/openssh/dist/explicit_bzero.c new file mode 120000 index 000000000..5efce3f43 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/explicit_bzero.c @@ -0,0 +1 @@ +openbsd-compat/explicit_bzero.c \ No newline at end of file diff --git a/crypto/external/bsd/openssh/dist/loginrec.c b/crypto/external/bsd/openssh/dist/loginrec.c new file mode 100644 index 000000000..94ae81dc6 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/loginrec.c @@ -0,0 +1,1726 @@ +/* + * Copyright (c) 2000 Andre Lucas. All rights reserved. + * Portions copyright (c) 1998 Todd C. Miller + * Portions copyright (c) 1996 Jason Downs + * Portions copyright (c) 1996 Theo de Raadt + * + * 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. + */ + +/* + * The btmp logging code is derived from login.c from util-linux and is under + * the the following license: + * + * Copyright (c) 1980, 1987, 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University 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 WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +/** + ** loginrec.c: platform-independent login recording and lastlog retrieval + **/ + +/* + * The new login code explained + * ============================ + * + * This code attempts to provide a common interface to login recording + * (utmp and friends) and last login time retrieval. + * + * Its primary means of achieving this is to use 'struct logininfo', a + * union of all the useful fields in the various different types of + * system login record structures one finds on UNIX variants. + * + * We depend on autoconf to define which recording methods are to be + * used, and which fields are contained in the relevant data structures + * on the local system. Many C preprocessor symbols affect which code + * gets compiled here. + * + * The code is designed to make it easy to modify a particular + * recording method, without affecting other methods nor requiring so + * many nested conditional compilation blocks as were commonplace in + * the old code. + * + * For login recording, we try to use the local system's libraries as + * these are clearly most likely to work correctly. For utmp systems + * this usually means login() and logout() or setutent() etc., probably + * in libutil, along with logwtmp() etc. On these systems, we fall back + * to writing the files directly if we have to, though this method + * requires very thorough testing so we do not corrupt local auditing + * information. These files and their access methods are very system + * specific indeed. + * + * For utmpx systems, the corresponding library functions are + * setutxent() etc. To the author's knowledge, all utmpx systems have + * these library functions and so no direct write is attempted. If such + * a system exists and needs support, direct analogues of the [uw]tmp + * code should suffice. + * + * Retrieving the time of last login ('lastlog') is in some ways even + * more problemmatic than login recording. Some systems provide a + * simple table of all users which we seek based on uid and retrieve a + * relatively standard structure. Others record the same information in + * a directory with a separate file, and others don't record the + * information separately at all. For systems in the latter category, + * we look backwards in the wtmp or wtmpx file for the last login entry + * for our user. Naturally this is slower and on busy systems could + * incur a significant performance penalty. + * + * Calling the new code + * -------------------- + * + * In OpenSSH all login recording and retrieval is performed in + * login.c. Here you'll find working examples. Also, in the logintest.c + * program there are more examples. + * + * Internal handler calling method + * ------------------------------- + * + * When a call is made to login_login() or login_logout(), both + * routines set a struct logininfo flag defining which action (log in, + * or log out) is to be taken. They both then call login_write(), which + * calls whichever of the many structure-specific handlers autoconf + * selects for the local system. + * + * The handlers themselves handle system data structure specifics. Both + * struct utmp and struct utmpx have utility functions (see + * construct_utmp*()) to try to make it simpler to add extra systems + * that introduce new features to either structure. + * + * While it may seem terribly wasteful to replicate so much similar + * code for each method, experience has shown that maintaining code to + * write both struct utmp and utmpx in one function, whilst maintaining + * support for all systems whether they have library support or not, is + * a difficult and time-consuming task. + * + * Lastlog support proceeds similarly. Functions login_get_lastlog() + * (and its OpenSSH-tuned friend login_get_lastlog_time()) call + * getlast_entry(), which tries one of three methods to find the last + * login time. It uses local system lastlog support if it can, + * otherwise it tries wtmp or wtmpx before giving up and returning 0, + * meaning "tilt". + * + * Maintenance + * ----------- + * + * In many cases it's possible to tweak autoconf to select the correct + * methods for a particular platform, either by improving the detection + * code (best), or by presetting DISABLE_ or CONF__FILE + * symbols for the platform. + * + * Use logintest to check which symbols are defined before modifying + * configure.ac and loginrec.c. (You have to build logintest yourself + * with 'make logintest' as it's not built by default.) + * + * Otherwise, patches to the specific method(s) are very helpful! + */ + +#include "includes.h" + +#include +#include +#include + +#include + +#include +#include +#ifdef HAVE_PATHS_H +# include +#endif +#include +#include +#include +#include +#include + +#include "xmalloc.h" +#include "key.h" +#include "hostfile.h" +#include "ssh.h" +#include "loginrec.h" +#include "log.h" +#include "atomicio.h" +#include "packet.h" +#include "canohost.h" +#include "auth.h" +#include "buffer.h" + +#ifdef HAVE_UTIL_H +# include +#endif + +/** + ** prototypes for helper functions in this file + **/ + +#if HAVE_UTMP_H +void set_utmp_time(struct logininfo *li, struct utmp *ut); +void construct_utmp(struct logininfo *li, struct utmp *ut); +#endif + +#ifdef HAVE_UTMPX_H +void set_utmpx_time(struct logininfo *li, struct utmpx *ut); +void construct_utmpx(struct logininfo *li, struct utmpx *ut); +#endif + +int utmp_write_entry(struct logininfo *li); +int utmpx_write_entry(struct logininfo *li); +int wtmp_write_entry(struct logininfo *li); +int wtmpx_write_entry(struct logininfo *li); +int lastlog_write_entry(struct logininfo *li); +int syslogin_write_entry(struct logininfo *li); + +int getlast_entry(struct logininfo *li); +int lastlog_get_entry(struct logininfo *li); +int utmpx_get_entry(struct logininfo *li); +int wtmp_get_entry(struct logininfo *li); +int wtmpx_get_entry(struct logininfo *li); + +extern Buffer loginmsg; + +/* pick the shortest string */ +#define MIN_SIZEOF(s1,s2) (sizeof(s1) < sizeof(s2) ? sizeof(s1) : sizeof(s2)) + +/** + ** platform-independent login functions + **/ + +/* + * login_login(struct logininfo *) - Record a login + * + * Call with a pointer to a struct logininfo initialised with + * login_init_entry() or login_alloc_entry() + * + * Returns: + * >0 if successful + * 0 on failure (will use OpenSSH's logging facilities for diagnostics) + */ +int +login_login(struct logininfo *li) +{ + li->type = LTYPE_LOGIN; + return (login_write(li)); +} + + +/* + * login_logout(struct logininfo *) - Record a logout + * + * Call as with login_login() + * + * Returns: + * >0 if successful + * 0 on failure (will use OpenSSH's logging facilities for diagnostics) + */ +int +login_logout(struct logininfo *li) +{ + li->type = LTYPE_LOGOUT; + return (login_write(li)); +} + +/* + * login_get_lastlog_time(int) - Retrieve the last login time + * + * Retrieve the last login time for the given uid. Will try to use the + * system lastlog facilities if they are available, but will fall back + * to looking in wtmp/wtmpx if necessary + * + * Returns: + * 0 on failure, or if user has never logged in + * Time in seconds from the epoch if successful + * + * Useful preprocessor symbols: + * DISABLE_LASTLOG: If set, *never* even try to retrieve lastlog + * info + * USE_LASTLOG: If set, indicates the presence of system lastlog + * facilities. If this and DISABLE_LASTLOG are not set, + * try to retrieve lastlog information from wtmp/wtmpx. + */ +unsigned int +login_get_lastlog_time(const uid_t uid) +{ + struct logininfo li; + + if (login_get_lastlog(&li, uid)) + return (li.tv_sec); + else + return (0); +} + +/* + * login_get_lastlog(struct logininfo *, int) - Retrieve a lastlog entry + * + * Retrieve a logininfo structure populated (only partially) with + * information from the system lastlog data, or from wtmp/wtmpx if no + * system lastlog information exists. + * + * Note this routine must be given a pre-allocated logininfo. + * + * Returns: + * >0: A pointer to your struct logininfo if successful + * 0 on failure (will use OpenSSH's logging facilities for diagnostics) + */ +struct logininfo * +login_get_lastlog(struct logininfo *li, const uid_t uid) +{ + struct passwd *pw; + + memset(li, '\0', sizeof(*li)); + li->uid = uid; + + /* + * If we don't have a 'real' lastlog, we need the username to + * reliably search wtmp(x) for the last login (see + * wtmp_get_entry().) + */ + pw = getpwuid(uid); + if (pw == NULL) + fatal("%s: Cannot find account for uid %ld", __func__, + (long)uid); + + if (strlcpy(li->username, pw->pw_name, sizeof(li->username)) >= + sizeof(li->username)) { + error("%s: username too long (%lu > max %lu)", __func__, + (unsigned long)strlen(pw->pw_name), + (unsigned long)sizeof(li->username) - 1); + return NULL; + } + + if (getlast_entry(li)) + return (li); + else + return (NULL); +} + +/* + * login_alloc_entry(int, char*, char*, char*) - Allocate and initialise + * a logininfo structure + * + * This function creates a new struct logininfo, a data structure + * meant to carry the information required to portably record login info. + * + * Returns a pointer to a newly created struct logininfo. If memory + * allocation fails, the program halts. + */ +struct +logininfo *login_alloc_entry(pid_t pid, const char *username, + const char *hostname, const char *line) +{ + struct logininfo *newli; + + newli = xmalloc(sizeof(*newli)); + login_init_entry(newli, pid, username, hostname, line); + return (newli); +} + + +/* login_free_entry(struct logininfo *) - free struct memory */ +void +login_free_entry(struct logininfo *li) +{ + free(li); +} + + +/* login_init_entry(struct logininfo *, int, char*, char*, char*) + * - initialise a struct logininfo + * + * Populates a new struct logininfo, a data structure meant to carry + * the information required to portably record login info. + * + * Returns: 1 + */ +int +login_init_entry(struct logininfo *li, pid_t pid, const char *username, + const char *hostname, const char *line) +{ + struct passwd *pw; + + memset(li, 0, sizeof(*li)); + + li->pid = pid; + + /* set the line information */ + if (line) + line_fullname(li->line, line, sizeof(li->line)); + + if (username) { + strlcpy(li->username, username, sizeof(li->username)); + pw = getpwnam(li->username); + if (pw == NULL) { + fatal("%s: Cannot find user \"%s\"", __func__, + li->username); + } + li->uid = pw->pw_uid; + } + + if (hostname) + strlcpy(li->hostname, hostname, sizeof(li->hostname)); + + return (1); +} + +/* + * login_set_current_time(struct logininfo *) - set the current time + * + * Set the current time in a logininfo structure. This function is + * meant to eliminate the need to deal with system dependencies for + * time handling. + */ +void +login_set_current_time(struct logininfo *li) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + + li->tv_sec = tv.tv_sec; + li->tv_usec = tv.tv_usec; +} + +/* copy a sockaddr_* into our logininfo */ +void +login_set_addr(struct logininfo *li, const struct sockaddr *sa, + const unsigned int sa_size) +{ + unsigned int bufsize = sa_size; + + /* make sure we don't overrun our union */ + if (sizeof(li->hostaddr) < sa_size) + bufsize = sizeof(li->hostaddr); + + memcpy(&li->hostaddr.sa, sa, bufsize); +} + + +/** + ** login_write: Call low-level recording functions based on autoconf + ** results + **/ +int +login_write(struct logininfo *li) +{ +#ifndef HAVE_CYGWIN + if (geteuid() != 0) { + logit("Attempt to write login records by non-root user (aborting)"); + return (1); + } +#endif + + /* set the timestamp */ + login_set_current_time(li); +#ifdef USE_LOGIN + syslogin_write_entry(li); +#endif +#ifdef USE_LASTLOG + if (li->type == LTYPE_LOGIN) + lastlog_write_entry(li); +#endif +#ifdef USE_UTMP + utmp_write_entry(li); +#endif +#ifdef USE_WTMP + wtmp_write_entry(li); +#endif +#ifdef USE_UTMPX + utmpx_write_entry(li); +#endif +#ifdef USE_WTMPX + wtmpx_write_entry(li); +#endif +#ifdef CUSTOM_SYS_AUTH_RECORD_LOGIN + if (li->type == LTYPE_LOGIN && + !sys_auth_record_login(li->username,li->hostname,li->line, + &loginmsg)) + logit("Writing login record failed for %s", li->username); +#endif +#ifdef SSH_AUDIT_EVENTS + if (li->type == LTYPE_LOGIN) + audit_session_open(li); + else if (li->type == LTYPE_LOGOUT) + audit_session_close(li); +#endif + return (0); +} + +#ifdef LOGIN_NEEDS_UTMPX +int +login_utmp_only(struct logininfo *li) +{ + li->type = LTYPE_LOGIN; + login_set_current_time(li); +# ifdef USE_UTMP + utmp_write_entry(li); +# endif +# ifdef USE_WTMP + wtmp_write_entry(li); +# endif +# ifdef USE_UTMPX + utmpx_write_entry(li); +# endif +# ifdef USE_WTMPX + wtmpx_write_entry(li); +# endif + return (0); +} +#endif + +/** + ** getlast_entry: Call low-level functions to retrieve the last login + ** time. + **/ + +/* take the uid in li and return the last login time */ +int +getlast_entry(struct logininfo *li) +{ +#ifdef USE_LASTLOG + return(lastlog_get_entry(li)); +#else /* !USE_LASTLOG */ +#if defined(USE_UTMPX) && defined(HAVE_SETUTXDB) && \ + defined(UTXDB_LASTLOGIN) && defined(HAVE_GETUTXUSER) + return (utmpx_get_entry(li)); +#endif + +#if defined(DISABLE_LASTLOG) + /* On some systems we shouldn't even try to obtain last login + * time, e.g. AIX */ + return (0); +# elif defined(USE_WTMP) && \ + (defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP)) + /* retrieve last login time from utmp */ + return (wtmp_get_entry(li)); +# elif defined(USE_WTMPX) && \ + (defined(HAVE_TIME_IN_UTMPX) || defined(HAVE_TV_IN_UTMPX)) + /* If wtmp isn't available, try wtmpx */ + return (wtmpx_get_entry(li)); +# else + /* Give up: No means of retrieving last login time */ + return (0); +# endif /* DISABLE_LASTLOG */ +#endif /* USE_LASTLOG */ +} + + + +/* + * 'line' string utility functions + * + * These functions process the 'line' string into one of three forms: + * + * 1. The full filename (including '/dev') + * 2. The stripped name (excluding '/dev') + * 3. The abbreviated name (e.g. /dev/ttyp00 -> yp00 + * /dev/pts/1 -> ts/1 ) + * + * Form 3 is used on some systems to identify a .tmp.? entry when + * attempting to remove it. Typically both addition and removal is + * performed by one application - say, sshd - so as long as the choice + * uniquely identifies a terminal it's ok. + */ + + +/* + * line_fullname(): add the leading '/dev/' if it doesn't exist make + * sure dst has enough space, if not just copy src (ugh) + */ +char * +line_fullname(char *dst, const char *src, u_int dstsize) +{ + memset(dst, '\0', dstsize); + if ((strncmp(src, "/dev/", 5) == 0) || (dstsize < (strlen(src) + 5))) + strlcpy(dst, src, dstsize); + else { + strlcpy(dst, "/dev/", dstsize); + strlcat(dst, src, dstsize); + } + return (dst); +} + +/* line_stripname(): strip the leading '/dev' if it exists, return dst */ +char * +line_stripname(char *dst, const char *src, int dstsize) +{ + memset(dst, '\0', dstsize); + if (strncmp(src, "/dev/", 5) == 0) + strlcpy(dst, src + 5, dstsize); + else + strlcpy(dst, src, dstsize); + return (dst); +} + +/* + * line_abbrevname(): Return the abbreviated (usually four-character) + * form of the line (Just use the last characters of the + * full name.) + * + * NOTE: use strncpy because we do NOT necessarily want zero + * termination + */ +char * +line_abbrevname(char *dst, const char *src, int dstsize) +{ + size_t len; + + memset(dst, '\0', dstsize); + + /* Always skip prefix if present */ + if (strncmp(src, "/dev/", 5) == 0) + src += 5; + +#ifdef WITH_ABBREV_NO_TTY + if (strncmp(src, "tty", 3) == 0) + src += 3; +#endif + + len = strlen(src); + + if (len > 0) { + if (((int)len - dstsize) > 0) + src += ((int)len - dstsize); + + /* note: _don't_ change this to strlcpy */ + strncpy(dst, src, (size_t)dstsize); + } + + return (dst); +} + +/** + ** utmp utility functions + ** + ** These functions manipulate struct utmp, taking system differences + ** into account. + **/ + +#if defined(USE_UTMP) || defined (USE_WTMP) || defined (USE_LOGIN) + +/* build the utmp structure */ +void +set_utmp_time(struct logininfo *li, struct utmp *ut) +{ +# if defined(HAVE_TV_IN_UTMP) + ut->ut_tv.tv_sec = li->tv_sec; + ut->ut_tv.tv_usec = li->tv_usec; +# elif defined(HAVE_TIME_IN_UTMP) + ut->ut_time = li->tv_sec; +# endif +} + +void +construct_utmp(struct logininfo *li, + struct utmp *ut) +{ +# ifdef HAVE_ADDR_V6_IN_UTMP + struct sockaddr_in6 *sa6; +# endif + + memset(ut, '\0', sizeof(*ut)); + + /* First fill out fields used for both logins and logouts */ + +# ifdef HAVE_ID_IN_UTMP + line_abbrevname(ut->ut_id, li->line, sizeof(ut->ut_id)); +# endif + +# ifdef HAVE_TYPE_IN_UTMP + /* This is done here to keep utmp constants out of struct logininfo */ + switch (li->type) { + case LTYPE_LOGIN: + ut->ut_type = USER_PROCESS; +#ifdef _UNICOS + cray_set_tmpdir(ut); +#endif + break; + case LTYPE_LOGOUT: + ut->ut_type = DEAD_PROCESS; +#ifdef _UNICOS + cray_retain_utmp(ut, li->pid); +#endif + break; + } +# endif + set_utmp_time(li, ut); + + line_stripname(ut->ut_line, li->line, sizeof(ut->ut_line)); + +# ifdef HAVE_PID_IN_UTMP + ut->ut_pid = li->pid; +# endif + + /* If we're logging out, leave all other fields blank */ + if (li->type == LTYPE_LOGOUT) + return; + + /* + * These fields are only used when logging in, and are blank + * for logouts. + */ + + /* Use strncpy because we don't necessarily want null termination */ + strncpy(ut->ut_name, li->username, + MIN_SIZEOF(ut->ut_name, li->username)); +# ifdef HAVE_HOST_IN_UTMP + strncpy(ut->ut_host, li->hostname, + MIN_SIZEOF(ut->ut_host, li->hostname)); +# endif +# ifdef HAVE_ADDR_IN_UTMP + /* this is just a 32-bit IP address */ + if (li->hostaddr.sa.sa_family == AF_INET) + ut->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr; +# endif +# ifdef HAVE_ADDR_V6_IN_UTMP + /* this is just a 128-bit IPv6 address */ + if (li->hostaddr.sa.sa_family == AF_INET6) { + sa6 = ((struct sockaddr_in6 *)&li->hostaddr.sa); + memcpy(ut->ut_addr_v6, sa6->sin6_addr.s6_addr, 16); + if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr)) { + ut->ut_addr_v6[0] = ut->ut_addr_v6[3]; + ut->ut_addr_v6[1] = 0; + ut->ut_addr_v6[2] = 0; + ut->ut_addr_v6[3] = 0; + } + } +# endif +} +#endif /* USE_UTMP || USE_WTMP || USE_LOGIN */ + +/** + ** utmpx utility functions + ** + ** These functions manipulate struct utmpx, accounting for system + ** variations. + **/ + +#if defined(USE_UTMPX) || defined (USE_WTMPX) +/* build the utmpx structure */ +void +set_utmpx_time(struct logininfo *li, struct utmpx *utx) +{ +# if defined(HAVE_TV_IN_UTMPX) + utx->ut_tv.tv_sec = li->tv_sec; + utx->ut_tv.tv_usec = li->tv_usec; +# elif defined(HAVE_TIME_IN_UTMPX) + utx->ut_time = li->tv_sec; +# endif +} + +void +construct_utmpx(struct logininfo *li, struct utmpx *utx) +{ +# ifdef HAVE_ADDR_V6_IN_UTMP + struct sockaddr_in6 *sa6; +# endif + memset(utx, '\0', sizeof(*utx)); + +# ifdef HAVE_ID_IN_UTMPX + line_abbrevname(utx->ut_id, li->line, sizeof(utx->ut_id)); +# endif + + /* this is done here to keep utmp constants out of loginrec.h */ + switch (li->type) { + case LTYPE_LOGIN: + utx->ut_type = USER_PROCESS; + break; + case LTYPE_LOGOUT: + utx->ut_type = DEAD_PROCESS; + break; + } + line_stripname(utx->ut_line, li->line, sizeof(utx->ut_line)); + set_utmpx_time(li, utx); + utx->ut_pid = li->pid; + + /* strncpy(): Don't necessarily want null termination */ + strncpy(utx->ut_user, li->username, + MIN_SIZEOF(utx->ut_user, li->username)); + + if (li->type == LTYPE_LOGOUT) + return; + + /* + * These fields are only used when logging in, and are blank + * for logouts. + */ + +# ifdef HAVE_HOST_IN_UTMPX + strncpy(utx->ut_host, li->hostname, + MIN_SIZEOF(utx->ut_host, li->hostname)); +# endif +# ifdef HAVE_ADDR_IN_UTMPX + /* this is just a 32-bit IP address */ + if (li->hostaddr.sa.sa_family == AF_INET) + utx->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr; +# endif +# ifdef HAVE_ADDR_V6_IN_UTMP + /* this is just a 128-bit IPv6 address */ + if (li->hostaddr.sa.sa_family == AF_INET6) { + sa6 = ((struct sockaddr_in6 *)&li->hostaddr.sa); + memcpy(utx->ut_addr_v6, sa6->sin6_addr.s6_addr, 16); + if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr)) { + utx->ut_addr_v6[0] = utx->ut_addr_v6[3]; + utx->ut_addr_v6[1] = 0; + utx->ut_addr_v6[2] = 0; + utx->ut_addr_v6[3] = 0; + } + } +# endif +# ifdef HAVE_SYSLEN_IN_UTMPX + /* ut_syslen is the length of the utx_host string */ + utx->ut_syslen = MIN(strlen(li->hostname), sizeof(utx->ut_host)); +# endif +} +#endif /* USE_UTMPX || USE_WTMPX */ + +/** + ** Low-level utmp functions + **/ + +/* FIXME: (ATL) utmp_write_direct needs testing */ +#ifdef USE_UTMP + +/* if we can, use pututline() etc. */ +# if !defined(DISABLE_PUTUTLINE) && defined(HAVE_SETUTENT) && \ + defined(HAVE_PUTUTLINE) +# define UTMP_USE_LIBRARY +# endif + + +/* write a utmp entry with the system's help (pututline() and pals) */ +# ifdef UTMP_USE_LIBRARY +static int +utmp_write_library(struct logininfo *li, struct utmp *ut) +{ + setutent(); + pututline(ut); +# ifdef HAVE_ENDUTENT + endutent(); +# endif + return (1); +} +# else /* UTMP_USE_LIBRARY */ + +/* + * Write a utmp entry direct to the file + * This is a slightly modification of code in OpenBSD's login.c + */ +static int +utmp_write_direct(struct logininfo *li, struct utmp *ut) +{ + struct utmp old_ut; + register int fd; + int tty; + + /* FIXME: (ATL) ttyslot() needs local implementation */ + +#if defined(HAVE_GETTTYENT) + struct ttyent *ty; + + tty=0; + setttyent(); + while (NULL != (ty = getttyent())) { + tty++; + if (!strncmp(ty->ty_name, ut->ut_line, sizeof(ut->ut_line))) + break; + } + endttyent(); + + if (NULL == ty) { + logit("%s: tty not found", __func__); + return (0); + } +#else /* FIXME */ + + tty = ttyslot(); /* seems only to work for /dev/ttyp? style names */ + +#endif /* HAVE_GETTTYENT */ + + if (tty > 0 && (fd = open(UTMP_FILE, O_RDWR|O_CREAT, 0644)) >= 0) { + off_t pos, ret; + + pos = (off_t)tty * sizeof(struct utmp); + if ((ret = lseek(fd, pos, SEEK_SET)) == -1) { + logit("%s: lseek: %s", __func__, strerror(errno)); + close(fd); + return (0); + } + if (ret != pos) { + logit("%s: Couldn't seek to tty %d slot in %s", + __func__, tty, UTMP_FILE); + close(fd); + return (0); + } + /* + * Prevent luser from zero'ing out ut_host. + * If the new ut_line is empty but the old one is not + * and ut_line and ut_name match, preserve the old ut_line. + */ + if (atomicio(read, fd, &old_ut, sizeof(old_ut)) == sizeof(old_ut) && + (ut->ut_host[0] == '\0') && (old_ut.ut_host[0] != '\0') && + (strncmp(old_ut.ut_line, ut->ut_line, sizeof(ut->ut_line)) == 0) && + (strncmp(old_ut.ut_name, ut->ut_name, sizeof(ut->ut_name)) == 0)) + memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host)); + + if ((ret = lseek(fd, pos, SEEK_SET)) == -1) { + logit("%s: lseek: %s", __func__, strerror(errno)); + close(fd); + return (0); + } + if (ret != pos) { + logit("%s: Couldn't seek to tty %d slot in %s", + __func__, tty, UTMP_FILE); + close(fd); + return (0); + } + if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) { + logit("%s: error writing %s: %s", __func__, + UTMP_FILE, strerror(errno)); + close(fd); + return (0); + } + + close(fd); + return (1); + } else { + return (0); + } +} +# endif /* UTMP_USE_LIBRARY */ + +static int +utmp_perform_login(struct logininfo *li) +{ + struct utmp ut; + + construct_utmp(li, &ut); +# ifdef UTMP_USE_LIBRARY + if (!utmp_write_library(li, &ut)) { + logit("%s: utmp_write_library() failed", __func__); + return (0); + } +# else + if (!utmp_write_direct(li, &ut)) { + logit("%s: utmp_write_direct() failed", __func__); + return (0); + } +# endif + return (1); +} + + +static int +utmp_perform_logout(struct logininfo *li) +{ + struct utmp ut; + + construct_utmp(li, &ut); +# ifdef UTMP_USE_LIBRARY + if (!utmp_write_library(li, &ut)) { + logit("%s: utmp_write_library() failed", __func__); + return (0); + } +# else + if (!utmp_write_direct(li, &ut)) { + logit("%s: utmp_write_direct() failed", __func__); + return (0); + } +# endif + return (1); +} + + +int +utmp_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return (utmp_perform_login(li)); + + case LTYPE_LOGOUT: + return (utmp_perform_logout(li)); + + default: + logit("%s: invalid type field", __func__); + return (0); + } +} +#endif /* USE_UTMP */ + + +/** + ** Low-level utmpx functions + **/ + +/* not much point if we don't want utmpx entries */ +#ifdef USE_UTMPX + +/* if we have the wherewithall, use pututxline etc. */ +# if !defined(DISABLE_PUTUTXLINE) && defined(HAVE_SETUTXENT) && \ + defined(HAVE_PUTUTXLINE) +# define UTMPX_USE_LIBRARY +# endif + + +/* write a utmpx entry with the system's help (pututxline() and pals) */ +# ifdef UTMPX_USE_LIBRARY +static int +utmpx_write_library(struct logininfo *li, struct utmpx *utx) +{ + setutxent(); + pututxline(utx); + +# ifdef HAVE_ENDUTXENT + endutxent(); +# endif + return (1); +} + +# else /* UTMPX_USE_LIBRARY */ + +/* write a utmp entry direct to the file */ +static int +utmpx_write_direct(struct logininfo *li, struct utmpx *utx) +{ + logit("%s: not implemented!", __func__); + return (0); +} +# endif /* UTMPX_USE_LIBRARY */ + +static int +utmpx_perform_login(struct logininfo *li) +{ + struct utmpx utx; + + construct_utmpx(li, &utx); +# ifdef UTMPX_USE_LIBRARY + if (!utmpx_write_library(li, &utx)) { + logit("%s: utmp_write_library() failed", __func__); + return (0); + } +# else + if (!utmpx_write_direct(li, &ut)) { + logit("%s: utmp_write_direct() failed", __func__); + return (0); + } +# endif + return (1); +} + + +static int +utmpx_perform_logout(struct logininfo *li) +{ + struct utmpx utx; + + construct_utmpx(li, &utx); +# ifdef HAVE_ID_IN_UTMPX + line_abbrevname(utx.ut_id, li->line, sizeof(utx.ut_id)); +# endif +# ifdef HAVE_TYPE_IN_UTMPX + utx.ut_type = DEAD_PROCESS; +# endif + +# ifdef UTMPX_USE_LIBRARY + utmpx_write_library(li, &utx); +# else + utmpx_write_direct(li, &utx); +# endif + return (1); +} + +int +utmpx_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return (utmpx_perform_login(li)); + case LTYPE_LOGOUT: + return (utmpx_perform_logout(li)); + default: + logit("%s: invalid type field", __func__); + return (0); + } +} +#endif /* USE_UTMPX */ + + +/** + ** Low-level wtmp functions + **/ + +#ifdef USE_WTMP + +/* + * Write a wtmp entry direct to the end of the file + * This is a slight modification of code in OpenBSD's logwtmp.c + */ +static int +wtmp_write(struct logininfo *li, struct utmp *ut) +{ + struct stat buf; + int fd, ret = 1; + + if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) < 0) { + logit("%s: problem writing %s: %s", __func__, + WTMP_FILE, strerror(errno)); + return (0); + } + if (fstat(fd, &buf) == 0) + if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) { + ftruncate(fd, buf.st_size); + logit("%s: problem writing %s: %s", __func__, + WTMP_FILE, strerror(errno)); + ret = 0; + } + close(fd); + return (ret); +} + +static int +wtmp_perform_login(struct logininfo *li) +{ + struct utmp ut; + + construct_utmp(li, &ut); + return (wtmp_write(li, &ut)); +} + + +static int +wtmp_perform_logout(struct logininfo *li) +{ + struct utmp ut; + + construct_utmp(li, &ut); + return (wtmp_write(li, &ut)); +} + + +int +wtmp_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return (wtmp_perform_login(li)); + case LTYPE_LOGOUT: + return (wtmp_perform_logout(li)); + default: + logit("%s: invalid type field", __func__); + return (0); + } +} + + +/* + * Notes on fetching login data from wtmp/wtmpx + * + * Logouts are usually recorded with (amongst other things) a blank + * username on a given tty line. However, some systems (HP-UX is one) + * leave all fields set, but change the ut_type field to DEAD_PROCESS. + * + * Since we're only looking for logins here, we know that the username + * must be set correctly. On systems that leave it in, we check for + * ut_type==USER_PROCESS (indicating a login.) + * + * Portability: Some systems may set something other than USER_PROCESS + * to indicate a login process. I don't know of any as I write. Also, + * it's possible that some systems may both leave the username in + * place and not have ut_type. + */ + +/* return true if this wtmp entry indicates a login */ +static int +wtmp_islogin(struct logininfo *li, struct utmp *ut) +{ + if (strncmp(li->username, ut->ut_name, + MIN_SIZEOF(li->username, ut->ut_name)) == 0) { +# ifdef HAVE_TYPE_IN_UTMP + if (ut->ut_type & USER_PROCESS) + return (1); +# else + return (1); +# endif + } + return (0); +} + +int +wtmp_get_entry(struct logininfo *li) +{ + struct stat st; + struct utmp ut; + int fd, found = 0; + + /* Clear the time entries in our logininfo */ + li->tv_sec = li->tv_usec = 0; + + if ((fd = open(WTMP_FILE, O_RDONLY)) < 0) { + logit("%s: problem opening %s: %s", __func__, + WTMP_FILE, strerror(errno)); + return (0); + } + if (fstat(fd, &st) != 0) { + logit("%s: couldn't stat %s: %s", __func__, + WTMP_FILE, strerror(errno)); + close(fd); + return (0); + } + + /* Seek to the start of the last struct utmp */ + if (lseek(fd, -(off_t)sizeof(struct utmp), SEEK_END) == -1) { + /* Looks like we've got a fresh wtmp file */ + close(fd); + return (0); + } + + while (!found) { + if (atomicio(read, fd, &ut, sizeof(ut)) != sizeof(ut)) { + logit("%s: read of %s failed: %s", __func__, + WTMP_FILE, strerror(errno)); + close (fd); + return (0); + } + if (wtmp_islogin(li, &ut) ) { + found = 1; + /* + * We've already checked for a time in struct + * utmp, in login_getlast() + */ +# ifdef HAVE_TIME_IN_UTMP + li->tv_sec = ut.ut_time; +# else +# if HAVE_TV_IN_UTMP + li->tv_sec = ut.ut_tv.tv_sec; +# endif +# endif + line_fullname(li->line, ut.ut_line, + MIN_SIZEOF(li->line, ut.ut_line)); +# ifdef HAVE_HOST_IN_UTMP + strlcpy(li->hostname, ut.ut_host, + MIN_SIZEOF(li->hostname, ut.ut_host)); +# endif + continue; + } + /* Seek back 2 x struct utmp */ + if (lseek(fd, -(off_t)(2 * sizeof(struct utmp)), SEEK_CUR) == -1) { + /* We've found the start of the file, so quit */ + close(fd); + return (0); + } + } + + /* We found an entry. Tidy up and return */ + close(fd); + return (1); +} +# endif /* USE_WTMP */ + + +/** + ** Low-level wtmpx functions + **/ + +#ifdef USE_WTMPX +/* + * Write a wtmpx entry direct to the end of the file + * This is a slight modification of code in OpenBSD's logwtmp.c + */ +static int +wtmpx_write(struct logininfo *li, struct utmpx *utx) +{ +#ifndef HAVE_UPDWTMPX + struct stat buf; + int fd, ret = 1; + + if ((fd = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0)) < 0) { + logit("%s: problem opening %s: %s", __func__, + WTMPX_FILE, strerror(errno)); + return (0); + } + + if (fstat(fd, &buf) == 0) + if (atomicio(vwrite, fd, utx, sizeof(*utx)) != sizeof(*utx)) { + ftruncate(fd, buf.st_size); + logit("%s: problem writing %s: %s", __func__, + WTMPX_FILE, strerror(errno)); + ret = 0; + } + close(fd); + + return (ret); +#else + updwtmpx(WTMPX_FILE, utx); + return (1); +#endif +} + + +static int +wtmpx_perform_login(struct logininfo *li) +{ + struct utmpx utx; + + construct_utmpx(li, &utx); + return (wtmpx_write(li, &utx)); +} + + +static int +wtmpx_perform_logout(struct logininfo *li) +{ + struct utmpx utx; + + construct_utmpx(li, &utx); + return (wtmpx_write(li, &utx)); +} + + +int +wtmpx_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return (wtmpx_perform_login(li)); + case LTYPE_LOGOUT: + return (wtmpx_perform_logout(li)); + default: + logit("%s: invalid type field", __func__); + return (0); + } +} + +/* Please see the notes above wtmp_islogin() for information about the + next two functions */ + +/* Return true if this wtmpx entry indicates a login */ +static int +wtmpx_islogin(struct logininfo *li, struct utmpx *utx) +{ + if (strncmp(li->username, utx->ut_user, + MIN_SIZEOF(li->username, utx->ut_user)) == 0 ) { +# ifdef HAVE_TYPE_IN_UTMPX + if (utx->ut_type == USER_PROCESS) + return (1); +# else + return (1); +# endif + } + return (0); +} + + +int +wtmpx_get_entry(struct logininfo *li) +{ + struct stat st; + struct utmpx utx; + int fd, found=0; + + /* Clear the time entries */ + li->tv_sec = li->tv_usec = 0; + + if ((fd = open(WTMPX_FILE, O_RDONLY)) < 0) { + logit("%s: problem opening %s: %s", __func__, + WTMPX_FILE, strerror(errno)); + return (0); + } + if (fstat(fd, &st) != 0) { + logit("%s: couldn't stat %s: %s", __func__, + WTMPX_FILE, strerror(errno)); + close(fd); + return (0); + } + + /* Seek to the start of the last struct utmpx */ + if (lseek(fd, -(off_t)sizeof(struct utmpx), SEEK_END) == -1 ) { + /* probably a newly rotated wtmpx file */ + close(fd); + return (0); + } + + while (!found) { + if (atomicio(read, fd, &utx, sizeof(utx)) != sizeof(utx)) { + logit("%s: read of %s failed: %s", __func__, + WTMPX_FILE, strerror(errno)); + close (fd); + return (0); + } + /* + * Logouts are recorded as a blank username on a particular + * line. So, we just need to find the username in struct utmpx + */ + if (wtmpx_islogin(li, &utx)) { + found = 1; +# if defined(HAVE_TV_IN_UTMPX) + li->tv_sec = utx.ut_tv.tv_sec; +# elif defined(HAVE_TIME_IN_UTMPX) + li->tv_sec = utx.ut_time; +# endif + line_fullname(li->line, utx.ut_line, sizeof(li->line)); +# if defined(HAVE_HOST_IN_UTMPX) + strlcpy(li->hostname, utx.ut_host, + MIN_SIZEOF(li->hostname, utx.ut_host)); +# endif + continue; + } + if (lseek(fd, -(off_t)(2 * sizeof(struct utmpx)), SEEK_CUR) == -1) { + close(fd); + return (0); + } + } + + close(fd); + return (1); +} +#endif /* USE_WTMPX */ + +/** + ** Low-level libutil login() functions + **/ + +#ifdef USE_LOGIN +static int +syslogin_perform_login(struct logininfo *li) +{ + struct utmp *ut; + + ut = xmalloc(sizeof(*ut)); + construct_utmp(li, ut); + login(ut); + free(ut); + + return (1); +} + +static int +syslogin_perform_logout(struct logininfo *li) +{ +# ifdef HAVE_LOGOUT + char line[UT_LINESIZE]; + + (void)line_stripname(line, li->line, sizeof(line)); + + if (!logout(line)) + logit("%s: logout() returned an error", __func__); +# ifdef HAVE_LOGWTMP + else + logwtmp(line, "", ""); +# endif + /* FIXME: (ATL - if the need arises) What to do if we have + * login, but no logout? what if logout but no logwtmp? All + * routines are in libutil so they should all be there, + * but... */ +# endif + return (1); +} + +int +syslogin_write_entry(struct logininfo *li) +{ + switch (li->type) { + case LTYPE_LOGIN: + return (syslogin_perform_login(li)); + case LTYPE_LOGOUT: + return (syslogin_perform_logout(li)); + default: + logit("%s: Invalid type field", __func__); + return (0); + } +} +#endif /* USE_LOGIN */ + +/* end of file log-syslogin.c */ + +/** + ** Low-level lastlog functions + **/ + +#ifdef USE_LASTLOG + +#if !defined(LASTLOG_WRITE_PUTUTXLINE) || !defined(HAVE_GETLASTLOGXBYNAME) +/* open the file (using filemode) and seek to the login entry */ +static int +lastlog_openseek(struct logininfo *li, int *fd, int filemode) +{ + off_t offset; + char lastlog_file[1024]; + struct stat st; + + if (stat(LASTLOG_FILE, &st) != 0) { + logit("%s: Couldn't stat %s: %s", __func__, + LASTLOG_FILE, strerror(errno)); + return (0); + } + if (S_ISDIR(st.st_mode)) { + snprintf(lastlog_file, sizeof(lastlog_file), "%s/%s", + LASTLOG_FILE, li->username); + } else if (S_ISREG(st.st_mode)) { + strlcpy(lastlog_file, LASTLOG_FILE, sizeof(lastlog_file)); + } else { + logit("%s: %.100s is not a file or directory!", __func__, + LASTLOG_FILE); + return (0); + } + + *fd = open(lastlog_file, filemode, 0600); + if (*fd < 0) { + debug("%s: Couldn't open %s: %s", __func__, + lastlog_file, strerror(errno)); + return (0); + } + + if (S_ISREG(st.st_mode)) { + /* find this uid's offset in the lastlog file */ + offset = (off_t) ((u_long)li->uid * sizeof(struct lastlog)); + + if (lseek(*fd, offset, SEEK_SET) != offset) { + logit("%s: %s->lseek(): %s", __func__, + lastlog_file, strerror(errno)); + close(*fd); + return (0); + } + } + + return (1); +} +#endif /* !LASTLOG_WRITE_PUTUTXLINE || !HAVE_GETLASTLOGXBYNAME */ + +#ifdef LASTLOG_WRITE_PUTUTXLINE +int +lastlog_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return 1; /* lastlog written by pututxline */ + default: + logit("lastlog_write_entry: Invalid type field"); + return 0; + } +} +#else /* LASTLOG_WRITE_PUTUTXLINE */ +int +lastlog_write_entry(struct logininfo *li) +{ + struct lastlog last; + int fd; + + switch(li->type) { + case LTYPE_LOGIN: + /* create our struct lastlog */ + memset(&last, '\0', sizeof(last)); + line_stripname(last.ll_line, li->line, sizeof(last.ll_line)); + strlcpy(last.ll_host, li->hostname, + MIN_SIZEOF(last.ll_host, li->hostname)); + last.ll_time = li->tv_sec; + + if (!lastlog_openseek(li, &fd, O_RDWR|O_CREAT)) + return (0); + + /* write the entry */ + if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) { + close(fd); + logit("%s: Error writing to %s: %s", __func__, + LASTLOG_FILE, strerror(errno)); + return (0); + } + + close(fd); + return (1); + default: + logit("%s: Invalid type field", __func__); + return (0); + } +} +#endif /* LASTLOG_WRITE_PUTUTXLINE */ + +#ifdef HAVE_GETLASTLOGXBYNAME +int +lastlog_get_entry(struct logininfo *li) +{ + struct lastlogx l, *ll; + + if ((ll = getlastlogxbyname(li->username, &l)) == NULL) { + memset(&l, '\0', sizeof(l)); + ll = &l; + } + line_fullname(li->line, ll->ll_line, sizeof(li->line)); + strlcpy(li->hostname, ll->ll_host, + MIN_SIZEOF(li->hostname, ll->ll_host)); + li->tv_sec = ll->ll_tv.tv_sec; + li->tv_usec = ll->ll_tv.tv_usec; + return (1); +} +#else /* HAVE_GETLASTLOGXBYNAME */ +int +lastlog_get_entry(struct logininfo *li) +{ + struct lastlog last; + int fd, ret; + + if (!lastlog_openseek(li, &fd, O_RDONLY)) + return (0); + + ret = atomicio(read, fd, &last, sizeof(last)); + close(fd); + + switch (ret) { + case 0: + memset(&last, '\0', sizeof(last)); + /* FALLTHRU */ + case sizeof(last): + line_fullname(li->line, last.ll_line, sizeof(li->line)); + strlcpy(li->hostname, last.ll_host, + MIN_SIZEOF(li->hostname, last.ll_host)); + li->tv_sec = last.ll_time; + return (1); + case -1: + error("%s: Error reading from %s: %s", __func__, + LASTLOG_FILE, strerror(errno)); + return (0); + default: + error("%s: Error reading from %s: Expecting %d, got %d", + __func__, LASTLOG_FILE, (int)sizeof(last), ret); + return (0); + } + + /* NOTREACHED */ + return (0); +} +#endif /* HAVE_GETLASTLOGXBYNAME */ +#endif /* USE_LASTLOG */ + +#if defined(USE_UTMPX) && defined(HAVE_SETUTXDB) && \ + defined(UTXDB_LASTLOGIN) && defined(HAVE_GETUTXUSER) +int +utmpx_get_entry(struct logininfo *li) +{ + struct utmpx *utx; + + if (setutxdb(UTXDB_LASTLOGIN, NULL) != 0) + return (0); + utx = getutxuser(li->username); + if (utx == NULL) { + endutxent(); + return (0); + } + + line_fullname(li->line, utx->ut_line, + MIN_SIZEOF(li->line, utx->ut_line)); + strlcpy(li->hostname, utx->ut_host, + MIN_SIZEOF(li->hostname, utx->ut_host)); + li->tv_sec = utx->ut_tv.tv_sec; + li->tv_usec = utx->ut_tv.tv_usec; + endutxent(); + return (1); +} +#endif /* USE_UTMPX && HAVE_SETUTXDB && UTXDB_LASTLOGIN && HAVE_GETUTXUSER */ + +#ifdef USE_BTMP + /* + * Logs failed login attempts in _PATH_BTMP if that exists. + * The most common login failure is to give password instead of username. + * So the _PATH_BTMP file checked for the correct permission, so that + * only root can read it. + */ + +void +record_failed_login(const char *username, const char *hostname, + const char *ttyn) +{ + int fd; + struct utmp ut; + struct sockaddr_storage from; + socklen_t fromlen = sizeof(from); + struct sockaddr_in *a4; + struct sockaddr_in6 *a6; + time_t t; + struct stat fst; + + if (geteuid() != 0) + return; + if ((fd = open(_PATH_BTMP, O_WRONLY | O_APPEND)) < 0) { + debug("Unable to open the btmp file %s: %s", _PATH_BTMP, + strerror(errno)); + return; + } + if (fstat(fd, &fst) < 0) { + logit("%s: fstat of %s failed: %s", __func__, _PATH_BTMP, + strerror(errno)); + goto out; + } + if((fst.st_mode & (S_IXGRP | S_IRWXO)) || (fst.st_uid != 0)){ + logit("Excess permission or bad ownership on file %s", + _PATH_BTMP); + goto out; + } + + memset(&ut, 0, sizeof(ut)); + /* strncpy because we don't necessarily want nul termination */ + strncpy(ut.ut_user, username, sizeof(ut.ut_user)); + strlcpy(ut.ut_line, "ssh:notty", sizeof(ut.ut_line)); + + time(&t); + ut.ut_time = t; /* ut_time is not always a time_t */ + ut.ut_type = LOGIN_PROCESS; + ut.ut_pid = getpid(); + + /* strncpy because we don't necessarily want nul termination */ + strncpy(ut.ut_host, hostname, sizeof(ut.ut_host)); + + if (packet_connection_is_on_socket() && + getpeername(packet_get_connection_in(), + (struct sockaddr *)&from, &fromlen) == 0) { + ipv64_normalise_mapped(&from, &fromlen); + if (from.ss_family == AF_INET) { + a4 = (struct sockaddr_in *)&from; + memcpy(&ut.ut_addr, &(a4->sin_addr), + MIN_SIZEOF(ut.ut_addr, a4->sin_addr)); + } +#ifdef HAVE_ADDR_V6_IN_UTMP + if (from.ss_family == AF_INET6) { + a6 = (struct sockaddr_in6 *)&from; + memcpy(&ut.ut_addr_v6, &(a6->sin6_addr), + MIN_SIZEOF(ut.ut_addr_v6, a6->sin6_addr)); + } +#endif + } + + if (atomicio(vwrite, fd, &ut, sizeof(ut)) != sizeof(ut)) + error("Failed to write to %s: %s", _PATH_BTMP, + strerror(errno)); + +out: + close(fd); +} +#endif /* USE_BTMP */ diff --git a/crypto/external/bsd/openssh/dist/loginrec.h b/crypto/external/bsd/openssh/dist/loginrec.h new file mode 100644 index 000000000..28923e781 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/loginrec.h @@ -0,0 +1,131 @@ +#ifndef _HAVE_LOGINREC_H_ +#define _HAVE_LOGINREC_H_ + +/* + * Copyright (c) 2000 Andre Lucas. 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. + */ + +/** + ** loginrec.h: platform-independent login recording and lastlog retrieval + **/ + +#include "includes.h" + +/** + ** you should use the login_* calls to work around platform dependencies + **/ + +/* + * login_netinfo structure + */ + +union login_netinfo { + struct sockaddr sa; + struct sockaddr_in sa_in; + struct sockaddr_storage sa_storage; +}; + +/* + * * logininfo structure * + */ +/* types - different to utmp.h 'type' macros */ +/* (though set to the same value as linux, openbsd and others...) */ +#define LTYPE_LOGIN 7 +#define LTYPE_LOGOUT 8 + +/* string lengths - set very long */ +#define LINFO_PROGSIZE 64 +#define LINFO_LINESIZE 64 +#define LINFO_NAMESIZE 512 +#define LINFO_HOSTSIZE 256 + +struct logininfo { + char progname[LINFO_PROGSIZE]; /* name of program (for PAM) */ + int progname_null; + short int type; /* type of login (LTYPE_*) */ + pid_t pid; /* PID of login process */ + uid_t uid; /* UID of this user */ + char line[LINFO_LINESIZE]; /* tty/pty name */ + char username[LINFO_NAMESIZE]; /* login username */ + char hostname[LINFO_HOSTSIZE]; /* remote hostname */ + /* 'exit_status' structure components */ + int exit; /* process exit status */ + int termination; /* process termination status */ + /* struct timeval (sys/time.h) isn't always available, if it isn't we'll + * use time_t's value as tv_sec and set tv_usec to 0 + */ + unsigned int tv_sec; + unsigned int tv_usec; + union login_netinfo hostaddr; /* caller's host address(es) */ +}; /* struct logininfo */ + +/* + * login recording functions + */ + +/** 'public' functions */ + +/* construct a new login entry */ +struct logininfo *login_alloc_entry(pid_t pid, const char *username, + const char *hostname, const char *line); +/* free a structure */ +void login_free_entry(struct logininfo *li); +/* fill out a pre-allocated structure with useful information */ +int login_init_entry(struct logininfo *li, pid_t pid, const char *username, + const char *hostname, const char *line); +/* place the current time in a logininfo struct */ +void login_set_current_time(struct logininfo *li); + +/* record the entry */ +int login_login (struct logininfo *li); +int login_logout(struct logininfo *li); +#ifdef LOGIN_NEEDS_UTMPX +int login_utmp_only(struct logininfo *li); +#endif + +/** End of public functions */ + +/* record the entry */ +int login_write (struct logininfo *li); +int login_log_entry(struct logininfo *li); + +/* set the network address based on network address type */ +void login_set_addr(struct logininfo *li, const struct sockaddr *sa, + const unsigned int sa_size); + +/* + * lastlog retrieval functions + */ +/* lastlog *entry* functions fill out a logininfo */ +struct logininfo *login_get_lastlog(struct logininfo *li, const uid_t uid); +/* lastlog *time* functions return time_t equivalent (uint) */ +unsigned int login_get_lastlog_time(const uid_t uid); + +/* produce various forms of the line filename */ +char *line_fullname(char *dst, const char *src, u_int dstsize); +char *line_stripname(char *dst, const char *src, int dstsize); +char *line_abbrevname(char *dst, const char *src, int dstsize); + +void record_failed_login(const char *, const char *, const char *); + +#endif /* _HAVE_LOGINREC_H_ */ diff --git a/crypto/external/bsd/openssh/dist/logintest.c b/crypto/external/bsd/openssh/dist/logintest.c new file mode 100644 index 000000000..4897ae0f9 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/logintest.c @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2000 Andre Lucas. 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. + */ + +/** + ** logintest.c: simple test driver for platform-independent login recording + ** and lastlog retrieval + **/ + +#include "includes.h" + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#ifdef HAVE_TIME_H +#include +#endif + +#include "loginrec.h" + +extern char *__progname; + +#define PAUSE_BEFORE_LOGOUT 3 + +int nologtest = 0; +int compile_opts_only = 0; +int be_verbose = 0; + + +/* Dump a logininfo to stdout. Assumes a tab size of 8 chars. */ +void +dump_logininfo(struct logininfo *li, char *descname) +{ + /* yes I know how nasty this is */ + printf("struct logininfo %s = {\n\t" + "progname\t'%s'\n\ttype\t\t%d\n\t" + "pid\t\t%d\n\tuid\t\t%d\n\t" + "line\t\t'%s'\n\tusername\t'%s'\n\t" + "hostname\t'%s'\n\texit\t\t%d\n\ttermination\t%d\n\t" + "tv_sec\t%d\n\ttv_usec\t%d\n\t" + "struct login_netinfo hostaddr {\n\t\t" + "struct sockaddr sa {\n" + "\t\t\tfamily\t%d\n\t\t}\n" + "\t}\n" + "}\n", + descname, li->progname, li->type, + li->pid, li->uid, li->line, + li->username, li->hostname, li->exit, + li->termination, li->tv_sec, li->tv_usec, + li->hostaddr.sa.sa_family); +} + + +int +testAPI() +{ + struct logininfo *li1; + struct passwd *pw; + struct hostent *he; + struct sockaddr_in sa_in4; + char cmdstring[256], stripline[8]; + char username[32]; +#ifdef HAVE_TIME_H + time_t t0, t1, t2, logintime, logouttime; + char s_t0[64],s_t1[64],s_t2[64]; + char s_logintime[64], s_logouttime[64]; /* ctime() strings */ +#endif + + printf("**\n** Testing the API...\n**\n"); + + pw = getpwuid(getuid()); + strlcpy(username, pw->pw_name, sizeof(username)); + + /* gethostname(hostname, sizeof(hostname)); */ + + printf("login_alloc_entry test (no host info):\n"); + + /* FIXME fake tty more effectively - this could upset some platforms */ + li1 = login_alloc_entry((int)getpid(), username, NULL, ttyname(0)); + strlcpy(li1->progname, "OpenSSH-logintest", sizeof(li1->progname)); + + if (be_verbose) + dump_logininfo(li1, "li1"); + + printf("Setting host address info for 'localhost' (may call out):\n"); + if (! (he = gethostbyname("localhost"))) { + printf("Couldn't set hostname(lookup failed)\n"); + } else { + /* NOTE: this is messy, but typically a program wouldn't have to set + * any of this, a sockaddr_in* would be already prepared */ + memcpy((void *)&(sa_in4.sin_addr), (void *)&(he->h_addr_list[0][0]), + sizeof(struct in_addr)); + login_set_addr(li1, (struct sockaddr *) &sa_in4, sizeof(sa_in4)); + strlcpy(li1->hostname, "localhost", sizeof(li1->hostname)); + } + if (be_verbose) + dump_logininfo(li1, "li1"); + + if ((int)geteuid() != 0) { + printf("NOT RUNNING LOGIN TESTS - you are not root!\n"); + return 1; + } + + if (nologtest) + return 1; + + line_stripname(stripline, li1->line, sizeof(stripline)); + + printf("Performing an invalid login attempt (no type field)\n--\n"); + login_write(li1); + printf("--\n(Should have written errors to stderr)\n"); + +#ifdef HAVE_TIME_H + (void)time(&t0); + strlcpy(s_t0, ctime(&t0), sizeof(s_t0)); + t1 = login_get_lastlog_time(getuid()); + strlcpy(s_t1, ctime(&t1), sizeof(s_t1)); + printf("Before logging in:\n\tcurrent time is %d - %s\t" + "lastlog time is %d - %s\n", + (int)t0, s_t0, (int)t1, s_t1); +#endif + + printf("Performing a login on line %s ", stripline); +#ifdef HAVE_TIME_H + (void)time(&logintime); + strlcpy(s_logintime, ctime(&logintime), sizeof(s_logintime)); + printf("at %d - %s", (int)logintime, s_logintime); +#endif + printf("--\n"); + login_login(li1); + + snprintf(cmdstring, sizeof(cmdstring), "who | grep '%s '", + stripline); + system(cmdstring); + + printf("--\nPausing for %d second(s)...\n", PAUSE_BEFORE_LOGOUT); + sleep(PAUSE_BEFORE_LOGOUT); + + printf("Performing a logout "); +#ifdef HAVE_TIME_H + (void)time(&logouttime); + strlcpy(s_logouttime, ctime(&logouttime), sizeof(s_logouttime)); + printf("at %d - %s", (int)logouttime, s_logouttime); +#endif + printf("\nThe root login shown above should be gone.\n" + "If the root login hasn't gone, but another user on the same\n" + "pty has, this is OK - we're hacking it here, and there\n" + "shouldn't be two users on one pty in reality...\n" + "-- ('who' output follows)\n"); + login_logout(li1); + + system(cmdstring); + printf("-- ('who' output ends)\n"); + +#ifdef HAVE_TIME_H + t2 = login_get_lastlog_time(getuid()); + strlcpy(s_t2, ctime(&t2), sizeof(s_t2)); + printf("After logging in, lastlog time is %d - %s\n", (int)t2, s_t2); + if (t1 == t2) + printf("The lastlog times before and after logging in are the " + "same.\nThis indicates that lastlog is ** NOT WORKING " + "CORRECTLY **\n"); + else if (t0 != t2) + /* We can be off by a second or so, even when recording works fine. + * I'm not 100% sure why, but it's true. */ + printf("** The login time and the lastlog time differ.\n" + "** This indicates that lastlog is either recording the " + "wrong time,\n** or retrieving the wrong entry.\n" + "If it's off by less than %d second(s) " + "run the test again.\n", PAUSE_BEFORE_LOGOUT); + else + printf("lastlog agrees with the login time. This is a good thing.\n"); + +#endif + + printf("--\nThe output of 'last' shown next should have " + "an entry for root \n on %s for the time shown above:\n--\n", + stripline); + snprintf(cmdstring, sizeof(cmdstring), "last | grep '%s ' | head -3", + stripline); + system(cmdstring); + + printf("--\nEnd of login test.\n"); + + login_free_entry(li1); + + return 1; +} /* testAPI() */ + + +void +testLineName(char *line) +{ + /* have to null-terminate - these functions are designed for + * structures with fixed-length char arrays, and don't null-term.*/ + char full[17], strip[9], abbrev[5]; + + memset(full, '\0', sizeof(full)); + memset(strip, '\0', sizeof(strip)); + memset(abbrev, '\0', sizeof(abbrev)); + + line_fullname(full, line, sizeof(full)-1); + line_stripname(strip, full, sizeof(strip)-1); + line_abbrevname(abbrev, full, sizeof(abbrev)-1); + printf("%s: %s, %s, %s\n", line, full, strip, abbrev); + +} /* testLineName() */ + + +int +testOutput() +{ + printf("**\n** Testing linename functions\n**\n"); + testLineName("/dev/pts/1"); + testLineName("pts/1"); + testLineName("pts/999"); + testLineName("/dev/ttyp00"); + testLineName("ttyp00"); + + return 1; +} /* testOutput() */ + + +/* show which options got compiled in */ +void +showOptions(void) +{ + printf("**\n** Compile-time options\n**\n"); + + printf("login recording methods selected:\n"); +#ifdef USE_LOGIN + printf("\tUSE_LOGIN\n"); +#endif +#ifdef USE_UTMP + printf("\tUSE_UTMP (UTMP_FILE=%s)\n", UTMP_FILE); +#endif +#ifdef USE_UTMPX + printf("\tUSE_UTMPX\n"); +#endif +#ifdef USE_WTMP + printf("\tUSE_WTMP (WTMP_FILE=%s)\n", WTMP_FILE); +#endif +#ifdef USE_WTMPX + printf("\tUSE_WTMPX (WTMPX_FILE=%s)\n", WTMPX_FILE); +#endif +#ifdef USE_LASTLOG + printf("\tUSE_LASTLOG (LASTLOG_FILE=%s)\n", LASTLOG_FILE); +#endif + printf("\n"); + +} /* showOptions() */ + + +int +main(int argc, char *argv[]) +{ + printf("Platform-independent login recording test driver\n"); + + __progname = ssh_get_progname(argv[0]); + if (argc == 2) { + if (strncmp(argv[1], "-i", 3) == 0) + compile_opts_only = 1; + else if (strncmp(argv[1], "-v", 3) == 0) + be_verbose=1; + } + + if (!compile_opts_only) { + if (be_verbose && !testOutput()) + return 1; + + if (!testAPI()) + return 1; + } + + showOptions(); + + return 0; +} /* main() */ + diff --git a/crypto/external/bsd/openssh/dist/md5crypt.c b/crypto/external/bsd/openssh/dist/md5crypt.c new file mode 100644 index 000000000..22ef98933 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/md5crypt.c @@ -0,0 +1,167 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this + * notice you can do whatever you want with this stuff. If we meet some + * day, and you think this stuff is worth it, you can buy me a beer in + * return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + */ + +#include "includes.h" + +#if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) +#include + +#include + +#include + +/* 0 ... 63 => ascii - 64 */ +static unsigned char itoa64[] = + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +static char *magic = "$1$"; + +static char * +to64(unsigned long v, int n) +{ + static char buf[5]; + char *s = buf; + + if (n > 4) + return (NULL); + + memset(buf, '\0', sizeof(buf)); + while (--n >= 0) { + *s++ = itoa64[v&0x3f]; + v >>= 6; + } + + return (buf); +} + +int +is_md5_salt(const char *salt) +{ + return (strncmp(salt, magic, strlen(magic)) == 0); +} + +char * +md5_crypt(const char *pw, const char *salt) +{ + static char passwd[120], salt_copy[9], *p; + static const char *sp, *ep; + unsigned char final[16]; + int sl, pl, i, j; + MD5_CTX ctx, ctx1; + unsigned long l; + + /* Refine the Salt first */ + sp = salt; + + /* If it starts with the magic string, then skip that */ + if(strncmp(sp, magic, strlen(magic)) == 0) + sp += strlen(magic); + + /* It stops at the first '$', max 8 chars */ + for (ep = sp; *ep != '$'; ep++) { + if (*ep == '\0' || ep >= (sp + 8)) + return (NULL); + } + + /* get the length of the true salt */ + sl = ep - sp; + + /* Stash the salt */ + memcpy(salt_copy, sp, sl); + salt_copy[sl] = '\0'; + + MD5_Init(&ctx); + + /* The password first, since that is what is most unknown */ + MD5_Update(&ctx, pw, strlen(pw)); + + /* Then our magic string */ + MD5_Update(&ctx, magic, strlen(magic)); + + /* Then the raw salt */ + MD5_Update(&ctx, sp, sl); + + /* Then just as many characters of the MD5(pw, salt, pw) */ + MD5_Init(&ctx1); + MD5_Update(&ctx1, pw, strlen(pw)); + MD5_Update(&ctx1, sp, sl); + MD5_Update(&ctx1, pw, strlen(pw)); + MD5_Final(final, &ctx1); + + for(pl = strlen(pw); pl > 0; pl -= 16) + MD5_Update(&ctx, final, pl > 16 ? 16 : pl); + + /* Don't leave anything around in vm they could use. */ + memset(final, '\0', sizeof final); + + /* Then something really weird... */ + for (j = 0, i = strlen(pw); i != 0; i >>= 1) + if (i & 1) + MD5_Update(&ctx, final + j, 1); + else + MD5_Update(&ctx, pw + j, 1); + + /* Now make the output string */ + snprintf(passwd, sizeof(passwd), "%s%s$", magic, salt_copy); + + MD5_Final(final, &ctx); + + /* + * and now, just to make sure things don't run too fast + * On a 60 Mhz Pentium this takes 34 msec, so you would + * need 30 seconds to build a 1000 entry dictionary... + */ + for(i = 0; i < 1000; i++) { + MD5_Init(&ctx1); + if (i & 1) + MD5_Update(&ctx1, pw, strlen(pw)); + else + MD5_Update(&ctx1, final, 16); + + if (i % 3) + MD5_Update(&ctx1, sp, sl); + + if (i % 7) + MD5_Update(&ctx1, pw, strlen(pw)); + + if (i & 1) + MD5_Update(&ctx1, final, 16); + else + MD5_Update(&ctx1, pw, strlen(pw)); + + MD5_Final(final, &ctx1); + } + + p = passwd + strlen(passwd); + + l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; + strlcat(passwd, to64(l, 4), sizeof(passwd)); + l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; + strlcat(passwd, to64(l, 4), sizeof(passwd)); + l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; + strlcat(passwd, to64(l, 4), sizeof(passwd)); + l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; + strlcat(passwd, to64(l, 4), sizeof(passwd)); + l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; + strlcat(passwd, to64(l, 4), sizeof(passwd)); + l = final[11] ; + strlcat(passwd, to64(l, 2), sizeof(passwd)); + + /* Don't leave anything around in vm they could use. */ + memset(final, 0, sizeof(final)); + memset(salt_copy, 0, sizeof(salt_copy)); + memset(&ctx, 0, sizeof(ctx)); + memset(&ctx1, 0, sizeof(ctx1)); + (void)to64(0, 4); + + return (passwd); +} + +#endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ diff --git a/crypto/external/bsd/openssh/dist/md5crypt.h b/crypto/external/bsd/openssh/dist/md5crypt.h new file mode 100644 index 000000000..2341e2c12 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/md5crypt.h @@ -0,0 +1,24 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + */ + +/* $Id: md5crypt.h,v 1.4 2003/05/18 14:46:46 djm Exp $ */ + +#ifndef _MD5CRYPT_H +#define _MD5CRYPT_H + +#include "config.h" + +#if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) + +int is_md5_salt(const char *); +char *md5_crypt(const char *, const char *); + +#endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ + +#endif /* MD5CRYPT_H */ diff --git a/crypto/external/bsd/openssh/dist/moduli.0 b/crypto/external/bsd/openssh/dist/moduli.0 new file mode 100644 index 000000000..087e5963e --- /dev/null +++ b/crypto/external/bsd/openssh/dist/moduli.0 @@ -0,0 +1,74 @@ +MODULI(5) File Formats Manual MODULI(5) + +NAME + moduli M-bM-^@M-^S Diffie-Hellman moduli + +DESCRIPTION + The /etc/moduli file contains prime numbers and generators for use by + sshd(8) in the Diffie-Hellman Group Exchange key exchange method. + + New moduli may be generated with ssh-keygen(1) using a two-step process. + An initial candidate generation pass, using ssh-keygen -G, calculates + numbers that are likely to be useful. A second primality testing pass, + using ssh-keygen -T, provides a high degree of assurance that the numbers + are prime and are safe for use in Diffie-Hellman operations by sshd(8). + This moduli format is used as the output from each pass. + + The file consists of newline-separated records, one per modulus, + containing seven space-separated fields. These fields are as follows: + + timestamp The time that the modulus was last processed as + YYYYMMDDHHMMSS. + + type Decimal number specifying the internal structure of + the prime modulus. Supported types are: + + 0 Unknown, not tested. + 2 "Safe" prime; (p-1)/2 is also prime. + 4 Sophie Germain; 2p+1 is also prime. + + Moduli candidates initially produced by ssh-keygen(1) + are Sophie Germain primes (type 4). Further primality + testing with ssh-keygen(1) produces safe prime moduli + (type 2) that are ready for use in sshd(8). Other + types are not used by OpenSSH. + + tests Decimal number indicating the type of primality tests + that the number has been subjected to represented as a + bitmask of the following values: + + 0x00 Not tested. + 0x01 Composite number M-bM-^@M-^S not prime. + 0x02 Sieve of Eratosthenes. + 0x04 Probabilistic Miller-Rabin primality tests. + + The ssh-keygen(1) moduli candidate generation uses the + Sieve of Eratosthenes (flag 0x02). Subsequent + ssh-keygen(1) primality tests are Miller-Rabin tests + (flag 0x04). + + trials Decimal number indicating the number of primality + trials that have been performed on the modulus. + + size Decimal number indicating the size of the prime in + bits. + + generator The recommended generator for use with this modulus + (hexadecimal). + + modulus The modulus itself in hexadecimal. + + When performing Diffie-Hellman Group Exchange, sshd(8) first estimates + the size of the modulus required to produce enough Diffie-Hellman output + to sufficiently key the selected symmetric cipher. sshd(8) then randomly + selects a modulus from /etc/moduli that best meets the size requirement. + +SEE ALSO + ssh-keygen(1), sshd(8) + +STANDARDS + M. Friedl, N. Provos, and W. Simpson, Diffie-Hellman Group Exchange for + the Secure Shell (SSH) Transport Layer Protocol, RFC 4419, March 2006, + 2006. + +OpenBSD 5.8 September 26, 2012 OpenBSD 5.8 diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/.cvsignore b/crypto/external/bsd/openssh/dist/openbsd-compat/.cvsignore new file mode 100644 index 000000000..f3c7a7c5d --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/Makefile b/crypto/external/bsd/openssh/dist/openbsd-compat/Makefile new file mode 100644 index 000000000..32c4cf8d5 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/Makefile @@ -0,0 +1,42 @@ +# $Id: Makefile.in,v 1.56 2014/09/30 23:43:08 djm Exp $ + +sysconfdir=${prefix}/etc +piddir=/var/run +srcdir=. +top_srcdir=.. + + +CC=cc +LD=cc +CFLAGS=-g -O2 -Qunused-arguments -Wunknown-warning-option -Wall -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-result -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -ftrapv -fno-builtin-memset -fstack-protector-strong +CPPFLAGS=-I. -I.. -I$(srcdir) -I$(srcdir)/.. -DHAVE_CONFIG_H +LIBS=-lcrypto -lutil -lz +AR=ar +RANLIB=ranlib +INSTALL=/usr/bin/install -c +LDFLAGS=-L. -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -fstack-protector-strong + +OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o reallocarray.o realpath.o rresvport.o setenv.o setproctitle.o sha1.o sha2.o rmd160.o md5.o sigact.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o explicit_bzero.o + +COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o kludge-fd_set.o + +PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o + +.c.o: + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< + +all: libopenbsd-compat.a + +$(COMPAT): ../config.h +$(OPENBSD): ../config.h +$(PORTS): ../config.h + +libopenbsd-compat.a: $(COMPAT) $(OPENBSD) $(PORTS) + $(AR) rv $@ $(COMPAT) $(OPENBSD) $(PORTS) + $(RANLIB) $@ + +clean: + rm -f *.o *.a core + +distclean: clean + rm -f Makefile *~ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/Makefile.in b/crypto/external/bsd/openssh/dist/openbsd-compat/Makefile.in new file mode 100644 index 000000000..3c5e3b7f7 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/Makefile.in @@ -0,0 +1,42 @@ +# $Id: Makefile.in,v 1.56 2014/09/30 23:43:08 djm Exp $ + +sysconfdir=@sysconfdir@ +piddir=@piddir@ +srcdir=@srcdir@ +top_srcdir=@top_srcdir@ + +VPATH=@srcdir@ +CC=@CC@ +LD=@LD@ +CFLAGS=@CFLAGS@ +CPPFLAGS=-I. -I.. -I$(srcdir) -I$(srcdir)/.. @CPPFLAGS@ @DEFS@ +LIBS=@LIBS@ +AR=@AR@ +RANLIB=@RANLIB@ +INSTALL=@INSTALL@ +LDFLAGS=-L. @LDFLAGS@ + +OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o reallocarray.o realpath.o rresvport.o setenv.o setproctitle.o sha1.o sha2.o rmd160.o md5.o sigact.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o explicit_bzero.o + +COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o kludge-fd_set.o + +PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o + +.c.o: + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< + +all: libopenbsd-compat.a + +$(COMPAT): ../config.h +$(OPENBSD): ../config.h +$(PORTS): ../config.h + +libopenbsd-compat.a: $(COMPAT) $(OPENBSD) $(PORTS) + $(AR) rv $@ $(COMPAT) $(OPENBSD) $(PORTS) + $(RANLIB) $@ + +clean: + rm -f *.o *.a core + +distclean: clean + rm -f Makefile *~ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/arc4random.c b/crypto/external/bsd/openssh/dist/openbsd-compat/arc4random.c new file mode 100644 index 000000000..046f57e61 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/arc4random.c @@ -0,0 +1,328 @@ +/* OPENBSD ORIGINAL: lib/libc/crypto/arc4random.c */ + +/* $OpenBSD: arc4random.c,v 1.25 2013/10/01 18:34:57 markus Exp $ */ + +/* + * Copyright (c) 1996, David Mazieres + * Copyright (c) 2008, Damien Miller + * Copyright (c) 2013, Markus Friedl + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * ChaCha based random number generator for OpenBSD. + */ + +#include "includes.h" + +#include + +#include +#include +#include +#include + +#ifndef HAVE_ARC4RANDOM + +#ifdef WITH_OPENSSL +#include +#include +#endif + +#include "log.h" + +#define KEYSTREAM_ONLY +#include "chacha_private.h" + +#ifdef __GNUC__ +#define inline __inline +#else /* !__GNUC__ */ +#define inline +#endif /* !__GNUC__ */ + +/* OpenSSH isn't multithreaded */ +#define _ARC4_LOCK() +#define _ARC4_UNLOCK() + +#define KEYSZ 32 +#define IVSZ 8 +#define BLOCKSZ 64 +#define RSBUFSZ (16*BLOCKSZ) +static int rs_initialized; +static pid_t rs_stir_pid; +static chacha_ctx rs; /* chacha context for random keystream */ +static u_char rs_buf[RSBUFSZ]; /* keystream blocks */ +static size_t rs_have; /* valid bytes at end of rs_buf */ +static size_t rs_count; /* bytes till reseed */ + +static inline void _rs_rekey(u_char *dat, size_t datlen); + +static inline void +_rs_init(u_char *buf, size_t n) +{ + if (n < KEYSZ + IVSZ) + return; + chacha_keysetup(&rs, buf, KEYSZ * 8, 0); + chacha_ivsetup(&rs, buf + KEYSZ); +} + +#ifndef WITH_OPENSSL +#define SSH_RANDOM_DEV "/dev/urandom" +/* XXX use getrandom() if supported on Linux */ +static void +getrnd(u_char *s, size_t len) +{ + int fd; + ssize_t r; + size_t o = 0; + + if ((fd = open(SSH_RANDOM_DEV, O_RDONLY)) == -1) + fatal("Couldn't open %s: %s", SSH_RANDOM_DEV, strerror(errno)); + while (o < len) { + r = read(fd, s + o, len - o); + if (r < 0) { + if (errno == EAGAIN || errno == EINTR || + errno == EWOULDBLOCK) + continue; + fatal("read %s: %s", SSH_RANDOM_DEV, strerror(errno)); + } + o += r; + } + close(fd); +} +#endif + +static void +_rs_stir(void) +{ + u_char rnd[KEYSZ + IVSZ]; + +#ifdef WITH_OPENSSL + if (RAND_bytes(rnd, sizeof(rnd)) <= 0) + fatal("Couldn't obtain random bytes (error %ld)", + ERR_get_error()); +#else + getrnd(rnd, sizeof(rnd)); +#endif + + if (!rs_initialized) { + rs_initialized = 1; + _rs_init(rnd, sizeof(rnd)); + } else + _rs_rekey(rnd, sizeof(rnd)); + explicit_bzero(rnd, sizeof(rnd)); + + /* invalidate rs_buf */ + rs_have = 0; + memset(rs_buf, 0, RSBUFSZ); + + rs_count = 1600000; +} + +static inline void +_rs_stir_if_needed(size_t len) +{ + pid_t pid = getpid(); + + if (rs_count <= len || !rs_initialized || rs_stir_pid != pid) { + rs_stir_pid = pid; + _rs_stir(); + } else + rs_count -= len; +} + +static inline void +_rs_rekey(u_char *dat, size_t datlen) +{ +#ifndef KEYSTREAM_ONLY + memset(rs_buf, 0,RSBUFSZ); +#endif + /* fill rs_buf with the keystream */ + chacha_encrypt_bytes(&rs, rs_buf, rs_buf, RSBUFSZ); + /* mix in optional user provided data */ + if (dat) { + size_t i, m; + + m = MIN(datlen, KEYSZ + IVSZ); + for (i = 0; i < m; i++) + rs_buf[i] ^= dat[i]; + } + /* immediately reinit for backtracking resistance */ + _rs_init(rs_buf, KEYSZ + IVSZ); + memset(rs_buf, 0, KEYSZ + IVSZ); + rs_have = RSBUFSZ - KEYSZ - IVSZ; +} + +static inline void +_rs_random_buf(void *_buf, size_t n) +{ + u_char *buf = (u_char *)_buf; + size_t m; + + _rs_stir_if_needed(n); + while (n > 0) { + if (rs_have > 0) { + m = MIN(n, rs_have); + memcpy(buf, rs_buf + RSBUFSZ - rs_have, m); + memset(rs_buf + RSBUFSZ - rs_have, 0, m); + buf += m; + n -= m; + rs_have -= m; + } + if (rs_have == 0) + _rs_rekey(NULL, 0); + } +} + +static inline void +_rs_random_u32(u_int32_t *val) +{ + _rs_stir_if_needed(sizeof(*val)); + if (rs_have < sizeof(*val)) + _rs_rekey(NULL, 0); + memcpy(val, rs_buf + RSBUFSZ - rs_have, sizeof(*val)); + memset(rs_buf + RSBUFSZ - rs_have, 0, sizeof(*val)); + rs_have -= sizeof(*val); + return; +} + +void +arc4random_stir(void) +{ + _ARC4_LOCK(); + _rs_stir(); + _ARC4_UNLOCK(); +} + +void +arc4random_addrandom(u_char *dat, int datlen) +{ + int m; + + _ARC4_LOCK(); + if (!rs_initialized) + _rs_stir(); + while (datlen > 0) { + m = MIN(datlen, KEYSZ + IVSZ); + _rs_rekey(dat, m); + dat += m; + datlen -= m; + } + _ARC4_UNLOCK(); +} + +u_int32_t +arc4random(void) +{ + u_int32_t val; + + _ARC4_LOCK(); + _rs_random_u32(&val); + _ARC4_UNLOCK(); + return val; +} + +/* + * If we are providing arc4random, then we can provide a more efficient + * arc4random_buf(). + */ +# ifndef HAVE_ARC4RANDOM_BUF +void +arc4random_buf(void *buf, size_t n) +{ + _ARC4_LOCK(); + _rs_random_buf(buf, n); + _ARC4_UNLOCK(); +} +# endif /* !HAVE_ARC4RANDOM_BUF */ +#endif /* !HAVE_ARC4RANDOM */ + +/* arc4random_buf() that uses platform arc4random() */ +#if !defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_ARC4RANDOM) +void +arc4random_buf(void *_buf, size_t n) +{ + size_t i; + u_int32_t r = 0; + char *buf = (char *)_buf; + + for (i = 0; i < n; i++) { + if (i % 4 == 0) + r = arc4random(); + buf[i] = r & 0xff; + r >>= 8; + } + explicit_bzero(&r, sizeof(r)); +} +#endif /* !defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_ARC4RANDOM) */ + +#ifndef HAVE_ARC4RANDOM_UNIFORM +/* + * Calculate a uniformly distributed random number less than upper_bound + * avoiding "modulo bias". + * + * Uniformity is achieved by generating new random numbers until the one + * returned is outside the range [0, 2**32 % upper_bound). This + * guarantees the selected random number will be inside + * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) + * after reduction modulo upper_bound. + */ +u_int32_t +arc4random_uniform(u_int32_t upper_bound) +{ + u_int32_t r, min; + + if (upper_bound < 2) + return 0; + + /* 2**32 % x == (2**32 - x) % x */ + min = -upper_bound % upper_bound; + + /* + * This could theoretically loop forever but each retry has + * p > 0.5 (worst case, usually far better) of selecting a + * number inside the range we need, so it should rarely need + * to re-roll. + */ + for (;;) { + r = arc4random(); + if (r >= min) + break; + } + + return r % upper_bound; +} +#endif /* !HAVE_ARC4RANDOM_UNIFORM */ + +#if 0 +/*-------- Test code for i386 --------*/ +#include +#include +int +main(int argc, char **argv) +{ + const int iter = 1000000; + int i; + pctrval v; + + v = rdtsc(); + for (i = 0; i < iter; i++) + arc4random(); + v = rdtsc() - v; + v /= iter; + + printf("%qd cycles\n", v); + exit(0); +} +#endif diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/base64.c b/crypto/external/bsd/openssh/dist/openbsd-compat/base64.c new file mode 100644 index 000000000..9e7466716 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/base64.c @@ -0,0 +1,315 @@ +/* $OpenBSD: base64.c,v 1.5 2006/10/21 09:55:03 otto Exp $ */ + +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +/* OPENBSD ORIGINAL: lib/libc/net/base64.c */ + +#include "includes.h" + +#if (!defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP)) || (!defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON)) + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "base64.h" + +static const char Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char Pad64 = '='; + +/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) + The following encoding technique is taken from RFC 1521 by Borenstein + and Freed. It is reproduced here in a slightly edited form for + convenience. + + A 65-character subset of US-ASCII is used, enabling 6 bits to be + represented per printable character. (The extra 65th character, "=", + is used to signify a special processing function.) + + The encoding process represents 24-bit groups of input bits as output + strings of 4 encoded characters. Proceeding from left to right, a + 24-bit input group is formed by concatenating 3 8-bit input groups. + These 24 bits are then treated as 4 concatenated 6-bit groups, each + of which is translated into a single digit in the base64 alphabet. + + Each 6-bit group is used as an index into an array of 64 printable + characters. The character referenced by the index is placed in the + output string. + + Table 1: The Base64 Alphabet + + Value Encoding Value Encoding Value Encoding Value Encoding + 0 A 17 R 34 i 51 z + 1 B 18 S 35 j 52 0 + 2 C 19 T 36 k 53 1 + 3 D 20 U 37 l 54 2 + 4 E 21 V 38 m 55 3 + 5 F 22 W 39 n 56 4 + 6 G 23 X 40 o 57 5 + 7 H 24 Y 41 p 58 6 + 8 I 25 Z 42 q 59 7 + 9 J 26 a 43 r 60 8 + 10 K 27 b 44 s 61 9 + 11 L 28 c 45 t 62 + + 12 M 29 d 46 u 63 / + 13 N 30 e 47 v + 14 O 31 f 48 w (pad) = + 15 P 32 g 49 x + 16 Q 33 h 50 y + + Special processing is performed if fewer than 24 bits are available + at the end of the data being encoded. A full encoding quantum is + always completed at the end of a quantity. When fewer than 24 input + bits are available in an input group, zero bits are added (on the + right) to form an integral number of 6-bit groups. Padding at the + end of the data is performed using the '=' character. + + Since all base64 input is an integral number of octets, only the + ------------------------------------------------- + following cases can arise: + + (1) the final quantum of encoding input is an integral + multiple of 24 bits; here, the final unit of encoded + output will be an integral multiple of 4 characters + with no "=" padding, + (2) the final quantum of encoding input is exactly 8 bits; + here, the final unit of encoded output will be two + characters followed by two "=" padding characters, or + (3) the final quantum of encoding input is exactly 16 bits; + here, the final unit of encoded output will be three + characters followed by one "=" padding character. + */ + +#if !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) +int +b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) +{ + size_t datalength = 0; + u_char input[3]; + u_char output[4]; + u_int i; + + while (2 < srclength) { + input[0] = *src++; + input[1] = *src++; + input[2] = *src++; + srclength -= 3; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + output[3] = input[2] & 0x3f; + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + target[datalength++] = Base64[output[2]]; + target[datalength++] = Base64[output[3]]; + } + + /* Now we worry about padding. */ + if (0 != srclength) { + /* Get what's left. */ + input[0] = input[1] = input[2] = '\0'; + for (i = 0; i < srclength; i++) + input[i] = *src++; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + if (srclength == 1) + target[datalength++] = Pad64; + else + target[datalength++] = Base64[output[2]]; + target[datalength++] = Pad64; + } + if (datalength >= targsize) + return (-1); + target[datalength] = '\0'; /* Returned value doesn't count \0. */ + return (datalength); +} +#endif /* !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) */ + +#if !defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON) + +/* skips all whitespace anywhere. + converts characters, four at a time, starting at (or after) + src from base - 64 numbers into three 8 bit bytes in the target area. + it returns the number of data bytes stored at the target, or -1 on error. + */ + +int +b64_pton(char const *src, u_char *target, size_t targsize) +{ + u_int tarindex, state; + int ch; + char *pos; + + state = 0; + tarindex = 0; + + while ((ch = *src++) != '\0') { + if (isspace(ch)) /* Skip whitespace anywhere. */ + continue; + + if (ch == Pad64) + break; + + pos = strchr(Base64, ch); + if (pos == 0) /* A non-base64 character. */ + return (-1); + + switch (state) { + case 0: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] = (pos - Base64) << 2; + } + state = 1; + break; + case 1: + if (target) { + if (tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 4; + target[tarindex+1] = ((pos - Base64) & 0x0f) + << 4 ; + } + tarindex++; + state = 2; + break; + case 2: + if (target) { + if (tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 2; + target[tarindex+1] = ((pos - Base64) & 0x03) + << 6; + } + tarindex++; + state = 3; + break; + case 3: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64); + } + tarindex++; + state = 0; + break; + } + } + + /* + * We are done decoding Base-64 chars. Let's see if we ended + * on a byte boundary, and/or with erroneous trailing characters. + */ + + if (ch == Pad64) { /* We got a pad char. */ + ch = *src++; /* Skip it, get next. */ + switch (state) { + case 0: /* Invalid = in first position */ + case 1: /* Invalid = in second position */ + return (-1); + + case 2: /* Valid, means one byte of info */ + /* Skip any number of spaces. */ + for (; ch != '\0'; ch = *src++) + if (!isspace(ch)) + break; + /* Make sure there is another trailing = sign. */ + if (ch != Pad64) + return (-1); + ch = *src++; /* Skip the = */ + /* Fall through to "single trailing =" case. */ + /* FALLTHROUGH */ + + case 3: /* Valid, means two bytes of info */ + /* + * We know this char is an =. Is there anything but + * whitespace after it? + */ + for (; ch != '\0'; ch = *src++) + if (!isspace(ch)) + return (-1); + + /* + * Now make sure for cases 2 and 3 that the "extra" + * bits that slopped past the last full byte were + * zeros. If we don't check them, they become a + * subliminal channel. + */ + if (target && target[tarindex] != 0) + return (-1); + } + } else { + /* + * We ended by seeing the end of the string. Make sure we + * have no partial bytes lying around. + */ + if (state != 0) + return (-1); + } + + return (tarindex); +} + +#endif /* !defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON) */ +#endif diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/base64.h b/crypto/external/bsd/openssh/dist/openbsd-compat/base64.h new file mode 100644 index 000000000..732c6b3f8 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/base64.h @@ -0,0 +1,65 @@ +/* $Id: base64.h,v 1.6 2003/08/29 16:59:52 mouring Exp $ */ + +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +#ifndef _BSD_BASE64_H +#define _BSD_BASE64_H + +#include "includes.h" + +#ifndef HAVE___B64_NTOP +# ifndef HAVE_B64_NTOP +int b64_ntop(u_char const *src, size_t srclength, char *target, + size_t targsize); +# endif /* !HAVE_B64_NTOP */ +# define __b64_ntop(a,b,c,d) b64_ntop(a,b,c,d) +#endif /* HAVE___B64_NTOP */ + +#ifndef HAVE___B64_PTON +# ifndef HAVE_B64_PTON +int b64_pton(char const *src, u_char *target, size_t targsize); +# endif /* !HAVE_B64_PTON */ +# define __b64_pton(a,b,c) b64_pton(a,b,c) +#endif /* HAVE___B64_PTON */ + +#endif /* _BSD_BASE64_H */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/basename.c b/crypto/external/bsd/openssh/dist/openbsd-compat/basename.c new file mode 100644 index 000000000..ffa5c8984 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/basename.c @@ -0,0 +1,67 @@ +/* $OpenBSD: basename.c,v 1.14 2005/08/08 08:05:33 espie Exp $ */ + +/* + * Copyright (c) 1997, 2004 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/gen/basename.c */ + +#include "includes.h" +#ifndef HAVE_BASENAME +#include +#include + +char * +basename(const char *path) +{ + static char bname[MAXPATHLEN]; + size_t len; + const char *endp, *startp; + + /* Empty or NULL string gets treated as "." */ + if (path == NULL || *path == '\0') { + bname[0] = '.'; + bname[1] = '\0'; + return (bname); + } + + /* Strip any trailing slashes */ + endp = path + strlen(path) - 1; + while (endp > path && *endp == '/') + endp--; + + /* All slashes becomes "/" */ + if (endp == path && *endp == '/') { + bname[0] = '/'; + bname[1] = '\0'; + return (bname); + } + + /* Find the start of the base */ + startp = endp; + while (startp > path && *(startp - 1) != '/') + startp--; + + len = endp - startp + 1; + if (len >= sizeof(bname)) { + errno = ENAMETOOLONG; + return (NULL); + } + memcpy(bname, startp, len); + bname[len] = '\0'; + return (bname); +} + +#endif /* !defined(HAVE_BASENAME) */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bcrypt_pbkdf.c b/crypto/external/bsd/openssh/dist/openbsd-compat/bcrypt_pbkdf.c new file mode 100644 index 000000000..0a07f9a0f --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bcrypt_pbkdf.c @@ -0,0 +1,179 @@ +/* $OpenBSD: bcrypt_pbkdf.c,v 1.13 2015/01/12 03:20:04 tedu Exp $ */ +/* + * Copyright (c) 2013 Ted Unangst + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#ifndef HAVE_BCRYPT_PBKDF + +#include +#include + +#ifdef HAVE_STDLIB_H +# include +#endif +#include + +#ifdef HAVE_BLF_H +# include +#endif + +#include "crypto_api.h" +#ifdef SHA512_DIGEST_LENGTH +# undef SHA512_DIGEST_LENGTH +#endif +#define SHA512_DIGEST_LENGTH crypto_hash_sha512_BYTES + +#define MINIMUM(a,b) (((a) < (b)) ? (a) : (b)) + +/* + * pkcs #5 pbkdf2 implementation using the "bcrypt" hash + * + * The bcrypt hash function is derived from the bcrypt password hashing + * function with the following modifications: + * 1. The input password and salt are preprocessed with SHA512. + * 2. The output length is expanded to 256 bits. + * 3. Subsequently the magic string to be encrypted is lengthened and modifed + * to "OxychromaticBlowfishSwatDynamite" + * 4. The hash function is defined to perform 64 rounds of initial state + * expansion. (More rounds are performed by iterating the hash.) + * + * Note that this implementation pulls the SHA512 operations into the caller + * as a performance optimization. + * + * One modification from official pbkdf2. Instead of outputting key material + * linearly, we mix it. pbkdf2 has a known weakness where if one uses it to + * generate (e.g.) 512 bits of key material for use as two 256 bit keys, an + * attacker can merely run once through the outer loop, but the user + * always runs it twice. Shuffling output bytes requires computing the + * entirety of the key material to assemble any subkey. This is something a + * wise caller could do; we just do it for you. + */ + +#define BCRYPT_WORDS 8 +#define BCRYPT_HASHSIZE (BCRYPT_WORDS * 4) + +static void +bcrypt_hash(u_int8_t *sha2pass, u_int8_t *sha2salt, u_int8_t *out) +{ + blf_ctx state; + u_int8_t ciphertext[BCRYPT_HASHSIZE] = + "OxychromaticBlowfishSwatDynamite"; + uint32_t cdata[BCRYPT_WORDS]; + int i; + uint16_t j; + size_t shalen = SHA512_DIGEST_LENGTH; + + /* key expansion */ + Blowfish_initstate(&state); + Blowfish_expandstate(&state, sha2salt, shalen, sha2pass, shalen); + for (i = 0; i < 64; i++) { + Blowfish_expand0state(&state, sha2salt, shalen); + Blowfish_expand0state(&state, sha2pass, shalen); + } + + /* encryption */ + j = 0; + for (i = 0; i < BCRYPT_WORDS; i++) + cdata[i] = Blowfish_stream2word(ciphertext, sizeof(ciphertext), + &j); + for (i = 0; i < 64; i++) + blf_enc(&state, cdata, sizeof(cdata) / sizeof(uint64_t)); + + /* copy out */ + for (i = 0; i < BCRYPT_WORDS; i++) { + out[4 * i + 3] = (cdata[i] >> 24) & 0xff; + out[4 * i + 2] = (cdata[i] >> 16) & 0xff; + out[4 * i + 1] = (cdata[i] >> 8) & 0xff; + out[4 * i + 0] = cdata[i] & 0xff; + } + + /* zap */ + explicit_bzero(ciphertext, sizeof(ciphertext)); + explicit_bzero(cdata, sizeof(cdata)); + explicit_bzero(&state, sizeof(state)); +} + +int +bcrypt_pbkdf(const char *pass, size_t passlen, const u_int8_t *salt, size_t saltlen, + u_int8_t *key, size_t keylen, unsigned int rounds) +{ + u_int8_t sha2pass[SHA512_DIGEST_LENGTH]; + u_int8_t sha2salt[SHA512_DIGEST_LENGTH]; + u_int8_t out[BCRYPT_HASHSIZE]; + u_int8_t tmpout[BCRYPT_HASHSIZE]; + u_int8_t *countsalt; + size_t i, j, amt, stride; + uint32_t count; + size_t origkeylen = keylen; + + /* nothing crazy */ + if (rounds < 1) + return -1; + if (passlen == 0 || saltlen == 0 || keylen == 0 || + keylen > sizeof(out) * sizeof(out) || saltlen > 1<<20) + return -1; + if ((countsalt = calloc(1, saltlen + 4)) == NULL) + return -1; + stride = (keylen + sizeof(out) - 1) / sizeof(out); + amt = (keylen + stride - 1) / stride; + + memcpy(countsalt, salt, saltlen); + + /* collapse password */ + crypto_hash_sha512(sha2pass, pass, passlen); + + /* generate key, sizeof(out) at a time */ + for (count = 1; keylen > 0; count++) { + countsalt[saltlen + 0] = (count >> 24) & 0xff; + countsalt[saltlen + 1] = (count >> 16) & 0xff; + countsalt[saltlen + 2] = (count >> 8) & 0xff; + countsalt[saltlen + 3] = count & 0xff; + + /* first round, salt is salt */ + crypto_hash_sha512(sha2salt, countsalt, saltlen + 4); + + bcrypt_hash(sha2pass, sha2salt, tmpout); + memcpy(out, tmpout, sizeof(out)); + + for (i = 1; i < rounds; i++) { + /* subsequent rounds, salt is previous output */ + crypto_hash_sha512(sha2salt, tmpout, sizeof(tmpout)); + bcrypt_hash(sha2pass, sha2salt, tmpout); + for (j = 0; j < sizeof(out); j++) + out[j] ^= tmpout[j]; + } + + /* + * pbkdf2 deviation: output the key material non-linearly. + */ + amt = MINIMUM(amt, keylen); + for (i = 0; i < amt; i++) { + size_t dest = i * stride + (count - 1); + if (dest >= origkeylen) + break; + key[dest] = out[i]; + } + keylen -= i; + } + + /* zap */ + explicit_bzero(out, sizeof(out)); + free(countsalt); + + return 0; +} +#endif /* HAVE_BCRYPT_PBKDF */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bindresvport.c b/crypto/external/bsd/openssh/dist/openbsd-compat/bindresvport.c new file mode 100644 index 000000000..c89f21403 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bindresvport.c @@ -0,0 +1,118 @@ +/* This file has be substantially modified from the original OpenBSD source */ + +/* $OpenBSD: bindresvport.c,v 1.17 2005/12/21 01:40:22 millert Exp $ */ + +/* + * Copyright 1996, Jason Downs. All rights reserved. + * Copyright 1998, Theo de Raadt. All rights reserved. + * Copyright 2000, Damien Miller. 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. + */ + +/* OPENBSD ORIGINAL: lib/libc/rpc/bindresvport.c */ + +#include "includes.h" + +#ifndef HAVE_BINDRESVPORT_SA +#include +#include + +#include +#include + +#include +#include + +#define STARTPORT 600 +#define ENDPORT (IPPORT_RESERVED - 1) +#define NPORTS (ENDPORT - STARTPORT + 1) + +/* + * Bind a socket to a privileged IP port + */ +int +bindresvport_sa(int sd, struct sockaddr *sa) +{ + int error, af; + struct sockaddr_storage myaddr; + struct sockaddr_in *in; + struct sockaddr_in6 *in6; + u_int16_t *portp; + u_int16_t port; + socklen_t salen; + int i; + + if (sa == NULL) { + memset(&myaddr, 0, sizeof(myaddr)); + sa = (struct sockaddr *)&myaddr; + + if (getsockname(sd, sa, &salen) == -1) + return -1; /* errno is correctly set */ + + af = sa->sa_family; + memset(&myaddr, 0, salen); + } else + af = sa->sa_family; + + if (af == AF_INET) { + in = (struct sockaddr_in *)sa; + salen = sizeof(struct sockaddr_in); + portp = &in->sin_port; + } else if (af == AF_INET6) { + in6 = (struct sockaddr_in6 *)sa; + salen = sizeof(struct sockaddr_in6); + portp = &in6->sin6_port; + } else { + errno = EPFNOSUPPORT; + return (-1); + } + sa->sa_family = af; + + port = ntohs(*portp); + if (port == 0) + port = arc4random_uniform(NPORTS) + STARTPORT; + + /* Avoid warning */ + error = -1; + + for(i = 0; i < NPORTS; i++) { + *portp = htons(port); + + error = bind(sd, sa, salen); + + /* Terminate on success */ + if (error == 0) + break; + + /* Terminate on errors, except "address already in use" */ + if ((error < 0) && !((errno == EADDRINUSE) || (errno == EINVAL))) + break; + + port++; + if (port > ENDPORT) + port = STARTPORT; + } + + return (error); +} + +#endif /* HAVE_BINDRESVPORT_SA */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/blf.h b/crypto/external/bsd/openssh/dist/openbsd-compat/blf.h new file mode 100644 index 000000000..f1ac5a5c2 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/blf.h @@ -0,0 +1,88 @@ +/* $OpenBSD: blf.h,v 1.7 2007/03/14 17:59:41 grunk Exp $ */ +/* + * Blowfish - a fast block cipher designed by Bruce Schneier + * + * Copyright 1997 Niels Provos + * 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 Niels Provos. + * 4. 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 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. + */ + +#ifndef _BLF_H_ +#define _BLF_H_ + +#include "includes.h" + +#if !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H) + +/* Schneier specifies a maximum key length of 56 bytes. + * This ensures that every key bit affects every cipher + * bit. However, the subkeys can hold up to 72 bytes. + * Warning: For normal blowfish encryption only 56 bytes + * of the key affect all cipherbits. + */ + +#define BLF_N 16 /* Number of Subkeys */ +#define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */ +#define BLF_MAXUTILIZED ((BLF_N+2)*4) /* 576 bits */ + +/* Blowfish context */ +typedef struct BlowfishContext { + u_int32_t S[4][256]; /* S-Boxes */ + u_int32_t P[BLF_N + 2]; /* Subkeys */ +} blf_ctx; + +/* Raw access to customized Blowfish + * blf_key is just: + * Blowfish_initstate( state ) + * Blowfish_expand0state( state, key, keylen ) + */ + +void Blowfish_encipher(blf_ctx *, u_int32_t *, u_int32_t *); +void Blowfish_decipher(blf_ctx *, u_int32_t *, u_int32_t *); +void Blowfish_initstate(blf_ctx *); +void Blowfish_expand0state(blf_ctx *, const u_int8_t *, u_int16_t); +void Blowfish_expandstate +(blf_ctx *, const u_int8_t *, u_int16_t, const u_int8_t *, u_int16_t); + +/* Standard Blowfish */ + +void blf_key(blf_ctx *, const u_int8_t *, u_int16_t); +void blf_enc(blf_ctx *, u_int32_t *, u_int16_t); +void blf_dec(blf_ctx *, u_int32_t *, u_int16_t); + +void blf_ecb_encrypt(blf_ctx *, u_int8_t *, u_int32_t); +void blf_ecb_decrypt(blf_ctx *, u_int8_t *, u_int32_t); + +void blf_cbc_encrypt(blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t); +void blf_cbc_decrypt(blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t); + +/* Converts u_int8_t to u_int32_t */ +u_int32_t Blowfish_stream2word(const u_int8_t *, u_int16_t , u_int16_t *); + +#endif /* !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H) */ +#endif /* _BLF_H */ + diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/blowfish.c b/crypto/external/bsd/openssh/dist/openbsd-compat/blowfish.c new file mode 100644 index 000000000..e10f7e7d9 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/blowfish.c @@ -0,0 +1,696 @@ +/* $OpenBSD: blowfish.c,v 1.18 2004/11/02 17:23:26 hshoexer Exp $ */ +/* + * Blowfish block cipher for OpenBSD + * Copyright 1997 Niels Provos + * All rights reserved. + * + * Implementation advice by David Mazieres . + * + * 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 Niels Provos. + * 4. 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 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. + */ + +/* + * This code is derived from section 14.3 and the given source + * in section V of Applied Cryptography, second edition. + * Blowfish is an unpatented fast block cipher designed by + * Bruce Schneier. + */ + +#include "includes.h" + +#if !defined(HAVE_BCRYPT_PBKDF) && (!defined(HAVE_BLOWFISH_INITSTATE) || \ + !defined(HAVE_BLOWFISH_EXPAND0STATE) || !defined(HAVE_BLF_ENC)) + +#if 0 +#include /* used for debugging */ +#include +#endif + +#include +#ifdef HAVE_BLF_H +#include +#endif + +#undef inline +#ifdef __GNUC__ +#define inline __inline +#else /* !__GNUC__ */ +#define inline +#endif /* !__GNUC__ */ + +/* Function for Feistel Networks */ + +#define F(s, x) ((((s)[ (((x)>>24)&0xFF)] \ + + (s)[0x100 + (((x)>>16)&0xFF)]) \ + ^ (s)[0x200 + (((x)>> 8)&0xFF)]) \ + + (s)[0x300 + ( (x) &0xFF)]) + +#define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n]) + +void +Blowfish_encipher(blf_ctx *c, u_int32_t *xl, u_int32_t *xr) +{ + u_int32_t Xl; + u_int32_t Xr; + u_int32_t *s = c->S[0]; + u_int32_t *p = c->P; + + Xl = *xl; + Xr = *xr; + + Xl ^= p[0]; + BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2); + BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4); + BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6); + BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8); + BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10); + BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12); + BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14); + BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16); + + *xl = Xr ^ p[17]; + *xr = Xl; +} + +void +Blowfish_decipher(blf_ctx *c, u_int32_t *xl, u_int32_t *xr) +{ + u_int32_t Xl; + u_int32_t Xr; + u_int32_t *s = c->S[0]; + u_int32_t *p = c->P; + + Xl = *xl; + Xr = *xr; + + Xl ^= p[17]; + BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15); + BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13); + BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11); + BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9); + BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7); + BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5); + BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3); + BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1); + + *xl = Xr ^ p[0]; + *xr = Xl; +} + +void +Blowfish_initstate(blf_ctx *c) +{ + /* P-box and S-box tables initialized with digits of Pi */ + + static const blf_ctx initstate = + { { + { + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, + 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, + 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, + 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, + 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, + 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, + 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, + 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, + 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, + 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, + 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, + 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, + 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, + 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, + 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, + 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, + 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, + 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, + 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, + 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, + 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, + 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, + 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, + 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, + 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, + 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, + 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, + 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, + 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, + 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, + 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, + 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, + 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, + 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, + 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, + 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, + 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, + 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, + 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, + 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, + 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, + 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, + 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, + 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, + 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, + 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, + 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, + 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, + 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, + 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, + 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, + 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, + 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, + 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, + 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, + 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, + 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, + 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, + 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, + 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, + 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, + 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a}, + { + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, + 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, + 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, + 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, + 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, + 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, + 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, + 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, + 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, + 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, + 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, + 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, + 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, + 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, + 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, + 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, + 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, + 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, + 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, + 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, + 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, + 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, + 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, + 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, + 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, + 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, + 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, + 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, + 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, + 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, + 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, + 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, + 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, + 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, + 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, + 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, + 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, + 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, + 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, + 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, + 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, + 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, + 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, + 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, + 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, + 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, + 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, + 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, + 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, + 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, + 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, + 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, + 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, + 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7}, + { + 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, + 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, + 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, + 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, + 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, + 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, + 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, + 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, + 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, + 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, + 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, + 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, + 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, + 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, + 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, + 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, + 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, + 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, + 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, + 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, + 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, + 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, + 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, + 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, + 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, + 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, + 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, + 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, + 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, + 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, + 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, + 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, + 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, + 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, + 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, + 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, + 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, + 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, + 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, + 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, + 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, + 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, + 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, + 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, + 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, + 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, + 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, + 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, + 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, + 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, + 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, + 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, + 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, + 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, + 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, + 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, + 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, + 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, + 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, + 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, + 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, + 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0}, + { + 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, + 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, + 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, + 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, + 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, + 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, + 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, + 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, + 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, + 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, + 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, + 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, + 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, + 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, + 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, + 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, + 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, + 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, + 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, + 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, + 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, + 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, + 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, + 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, + 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, + 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, + 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, + 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, + 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, + 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, + 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, + 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, + 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, + 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, + 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, + 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, + 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, + 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, + 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, + 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, + 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, + 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, + 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, + 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, + 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, + 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, + 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, + 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, + 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, + 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, + 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, + 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, + 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, + 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, + 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, + 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, + 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, + 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, + 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, + 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, + 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, + 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6} + }, + { + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, + 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, + 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, + 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, + 0x9216d5d9, 0x8979fb1b + } }; + + *c = initstate; +} + +u_int32_t +Blowfish_stream2word(const u_int8_t *data, u_int16_t databytes, + u_int16_t *current) +{ + u_int8_t i; + u_int16_t j; + u_int32_t temp; + + temp = 0x00000000; + j = *current; + + for (i = 0; i < 4; i++, j++) { + if (j >= databytes) + j = 0; + temp = (temp << 8) | data[j]; + } + + *current = j; + return temp; +} + +void +Blowfish_expand0state(blf_ctx *c, const u_int8_t *key, u_int16_t keybytes) +{ + u_int16_t i; + u_int16_t j; + u_int16_t k; + u_int32_t temp; + u_int32_t datal; + u_int32_t datar; + + j = 0; + for (i = 0; i < BLF_N + 2; i++) { + /* Extract 4 int8 to 1 int32 from keystream */ + temp = Blowfish_stream2word(key, keybytes, &j); + c->P[i] = c->P[i] ^ temp; + } + + j = 0; + datal = 0x00000000; + datar = 0x00000000; + for (i = 0; i < BLF_N + 2; i += 2) { + Blowfish_encipher(c, &datal, &datar); + + c->P[i] = datal; + c->P[i + 1] = datar; + } + + for (i = 0; i < 4; i++) { + for (k = 0; k < 256; k += 2) { + Blowfish_encipher(c, &datal, &datar); + + c->S[i][k] = datal; + c->S[i][k + 1] = datar; + } + } +} + + +void +Blowfish_expandstate(blf_ctx *c, const u_int8_t *data, u_int16_t databytes, + const u_int8_t *key, u_int16_t keybytes) +{ + u_int16_t i; + u_int16_t j; + u_int16_t k; + u_int32_t temp; + u_int32_t datal; + u_int32_t datar; + + j = 0; + for (i = 0; i < BLF_N + 2; i++) { + /* Extract 4 int8 to 1 int32 from keystream */ + temp = Blowfish_stream2word(key, keybytes, &j); + c->P[i] = c->P[i] ^ temp; + } + + j = 0; + datal = 0x00000000; + datar = 0x00000000; + for (i = 0; i < BLF_N + 2; i += 2) { + datal ^= Blowfish_stream2word(data, databytes, &j); + datar ^= Blowfish_stream2word(data, databytes, &j); + Blowfish_encipher(c, &datal, &datar); + + c->P[i] = datal; + c->P[i + 1] = datar; + } + + for (i = 0; i < 4; i++) { + for (k = 0; k < 256; k += 2) { + datal ^= Blowfish_stream2word(data, databytes, &j); + datar ^= Blowfish_stream2word(data, databytes, &j); + Blowfish_encipher(c, &datal, &datar); + + c->S[i][k] = datal; + c->S[i][k + 1] = datar; + } + } + +} + +void +blf_key(blf_ctx *c, const u_int8_t *k, u_int16_t len) +{ + /* Initialize S-boxes and subkeys with Pi */ + Blowfish_initstate(c); + + /* Transform S-boxes and subkeys with key */ + Blowfish_expand0state(c, k, len); +} + +void +blf_enc(blf_ctx *c, u_int32_t *data, u_int16_t blocks) +{ + u_int32_t *d; + u_int16_t i; + + d = data; + for (i = 0; i < blocks; i++) { + Blowfish_encipher(c, d, d + 1); + d += 2; + } +} + +void +blf_dec(blf_ctx *c, u_int32_t *data, u_int16_t blocks) +{ + u_int32_t *d; + u_int16_t i; + + d = data; + for (i = 0; i < blocks; i++) { + Blowfish_decipher(c, d, d + 1); + d += 2; + } +} + +void +blf_ecb_encrypt(blf_ctx *c, u_int8_t *data, u_int32_t len) +{ + u_int32_t l, r; + u_int32_t i; + + for (i = 0; i < len; i += 8) { + l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; + r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; + Blowfish_encipher(c, &l, &r); + data[0] = l >> 24 & 0xff; + data[1] = l >> 16 & 0xff; + data[2] = l >> 8 & 0xff; + data[3] = l & 0xff; + data[4] = r >> 24 & 0xff; + data[5] = r >> 16 & 0xff; + data[6] = r >> 8 & 0xff; + data[7] = r & 0xff; + data += 8; + } +} + +void +blf_ecb_decrypt(blf_ctx *c, u_int8_t *data, u_int32_t len) +{ + u_int32_t l, r; + u_int32_t i; + + for (i = 0; i < len; i += 8) { + l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; + r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; + Blowfish_decipher(c, &l, &r); + data[0] = l >> 24 & 0xff; + data[1] = l >> 16 & 0xff; + data[2] = l >> 8 & 0xff; + data[3] = l & 0xff; + data[4] = r >> 24 & 0xff; + data[5] = r >> 16 & 0xff; + data[6] = r >> 8 & 0xff; + data[7] = r & 0xff; + data += 8; + } +} + +void +blf_cbc_encrypt(blf_ctx *c, u_int8_t *iv, u_int8_t *data, u_int32_t len) +{ + u_int32_t l, r; + u_int32_t i, j; + + for (i = 0; i < len; i += 8) { + for (j = 0; j < 8; j++) + data[j] ^= iv[j]; + l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; + r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; + Blowfish_encipher(c, &l, &r); + data[0] = l >> 24 & 0xff; + data[1] = l >> 16 & 0xff; + data[2] = l >> 8 & 0xff; + data[3] = l & 0xff; + data[4] = r >> 24 & 0xff; + data[5] = r >> 16 & 0xff; + data[6] = r >> 8 & 0xff; + data[7] = r & 0xff; + iv = data; + data += 8; + } +} + +void +blf_cbc_decrypt(blf_ctx *c, u_int8_t *iva, u_int8_t *data, u_int32_t len) +{ + u_int32_t l, r; + u_int8_t *iv; + u_int32_t i, j; + + iv = data + len - 16; + data = data + len - 8; + for (i = len - 8; i >= 8; i -= 8) { + l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; + r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; + Blowfish_decipher(c, &l, &r); + data[0] = l >> 24 & 0xff; + data[1] = l >> 16 & 0xff; + data[2] = l >> 8 & 0xff; + data[3] = l & 0xff; + data[4] = r >> 24 & 0xff; + data[5] = r >> 16 & 0xff; + data[6] = r >> 8 & 0xff; + data[7] = r & 0xff; + for (j = 0; j < 8; j++) + data[j] ^= iv[j]; + iv -= 8; + data -= 8; + } + l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; + r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; + Blowfish_decipher(c, &l, &r); + data[0] = l >> 24 & 0xff; + data[1] = l >> 16 & 0xff; + data[2] = l >> 8 & 0xff; + data[3] = l & 0xff; + data[4] = r >> 24 & 0xff; + data[5] = r >> 16 & 0xff; + data[6] = r >> 8 & 0xff; + data[7] = r & 0xff; + for (j = 0; j < 8; j++) + data[j] ^= iva[j]; +} + +#if 0 +void +report(u_int32_t data[], u_int16_t len) +{ + u_int16_t i; + for (i = 0; i < len; i += 2) + printf("Block %0hd: %08lx %08lx.\n", + i / 2, data[i], data[i + 1]); +} +void +main(void) +{ + + blf_ctx c; + char key[] = "AAAAA"; + char key2[] = "abcdefghijklmnopqrstuvwxyz"; + + u_int32_t data[10]; + u_int32_t data2[] = + {0x424c4f57l, 0x46495348l}; + + u_int16_t i; + + /* First test */ + for (i = 0; i < 10; i++) + data[i] = i; + + blf_key(&c, (u_int8_t *) key, 5); + blf_enc(&c, data, 5); + blf_dec(&c, data, 1); + blf_dec(&c, data + 2, 4); + printf("Should read as 0 - 9.\n"); + report(data, 10); + + /* Second test */ + blf_key(&c, (u_int8_t *) key2, strlen(key2)); + blf_enc(&c, data2, 1); + printf("\nShould read as: 0x324ed0fe 0xf413a203.\n"); + report(data2, 2); + blf_dec(&c, data2, 1); + report(data2, 2); +} +#endif + +#endif /* !defined(HAVE_BCRYPT_PBKDF) && (!defined(HAVE_BLOWFISH_INITSTATE) || \ + !defined(HAVE_BLOWFISH_EXPAND0STATE) || !defined(HAVE_BLF_ENC)) */ + diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-asprintf.c b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-asprintf.c new file mode 100644 index 000000000..3368195d4 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-asprintf.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2004 Darren Tucker. + * + * Based originally on asprintf.c from OpenBSD: + * Copyright (c) 1997 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#ifndef HAVE_VASPRINTF + +#include +#include +#include + +#ifndef VA_COPY +# ifdef HAVE_VA_COPY +# define VA_COPY(dest, src) va_copy(dest, src) +# else +# ifdef HAVE___VA_COPY +# define VA_COPY(dest, src) __va_copy(dest, src) +# else +# define VA_COPY(dest, src) (dest) = (src) +# endif +# endif +#endif + +#define INIT_SZ 128 + +int +vasprintf(char **str, const char *fmt, va_list ap) +{ + int ret = -1; + va_list ap2; + char *string, *newstr; + size_t len; + + VA_COPY(ap2, ap); + if ((string = malloc(INIT_SZ)) == NULL) + goto fail; + + ret = vsnprintf(string, INIT_SZ, fmt, ap2); + if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */ + *str = string; + } else if (ret == INT_MAX || ret < 0) { /* Bad length */ + free(string); + goto fail; + } else { /* bigger than initial, realloc allowing for nul */ + len = (size_t)ret + 1; + if ((newstr = realloc(string, len)) == NULL) { + free(string); + goto fail; + } else { + va_end(ap2); + VA_COPY(ap2, ap); + ret = vsnprintf(newstr, len, fmt, ap2); + if (ret >= 0 && (size_t)ret < len) { + *str = newstr; + } else { /* failed with realloc'ed string, give up */ + free(newstr); + goto fail; + } + } + } + va_end(ap2); + return (ret); + +fail: + *str = NULL; + errno = ENOMEM; + va_end(ap2); + return (-1); +} +#endif + +#ifndef HAVE_ASPRINTF +int asprintf(char **str, const char *fmt, ...) +{ + va_list ap; + int ret; + + *str = NULL; + va_start(ap, fmt); + ret = vasprintf(str, fmt, ap); + va_end(ap); + + return ret; +} +#endif diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-closefrom.c b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-closefrom.c new file mode 100644 index 000000000..9380b33a7 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-closefrom.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2004-2005 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#ifndef HAVE_CLOSEFROM + +#include +#include +#include +#include +#ifdef HAVE_FCNTL_H +# include +#endif +#include +#include +#include +#include +#include +#ifdef HAVE_DIRENT_H +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# ifdef HAVE_SYS_NDIR_H +# include +# endif +# ifdef HAVE_SYS_DIR_H +# include +# endif +# ifdef HAVE_NDIR_H +# include +# endif +#endif + +#ifndef OPEN_MAX +# define OPEN_MAX 256 +#endif + +#if 0 +__unused static const char rcsid[] = "$Sudo: closefrom.c,v 1.11 2006/08/17 15:26:54 millert Exp $"; +#endif /* lint */ + +/* + * Close all file descriptors greater than or equal to lowfd. + */ +#ifdef HAVE_FCNTL_CLOSEM +void +closefrom(int lowfd) +{ + (void) fcntl(lowfd, F_CLOSEM, 0); +} +#else +void +closefrom(int lowfd) +{ + long fd, maxfd; +#if defined(HAVE_DIRFD) && defined(HAVE_PROC_PID) + char fdpath[PATH_MAX], *endp; + struct dirent *dent; + DIR *dirp; + int len; + + /* Check for a /proc/$$/fd directory. */ + len = snprintf(fdpath, sizeof(fdpath), "/proc/%ld/fd", (long)getpid()); + if (len > 0 && (size_t)len <= sizeof(fdpath) && (dirp = opendir(fdpath))) { + while ((dent = readdir(dirp)) != NULL) { + fd = strtol(dent->d_name, &endp, 10); + if (dent->d_name != endp && *endp == '\0' && + fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp)) + (void) close((int) fd); + } + (void) closedir(dirp); + } else +#endif + { + /* + * Fall back on sysconf() or getdtablesize(). We avoid checking + * resource limits since it is possible to open a file descriptor + * and then drop the rlimit such that it is below the open fd. + */ +#ifdef HAVE_SYSCONF + maxfd = sysconf(_SC_OPEN_MAX); +#else + maxfd = getdtablesize(); +#endif /* HAVE_SYSCONF */ + if (maxfd < 0) + maxfd = OPEN_MAX; + + for (fd = lowfd; fd < maxfd; fd++) + (void) close((int) fd); + } +} +#endif /* !HAVE_FCNTL_CLOSEM */ +#endif /* HAVE_CLOSEFROM */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-cray.c b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-cray.c new file mode 100644 index 000000000..f1bbd7dec --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-cray.c @@ -0,0 +1,817 @@ +/* + * $Id: bsd-cray.c,v 1.17 2007/08/15 09:17:43 dtucker Exp $ + * + * bsd-cray.c + * + * Copyright (c) 2002, Cray Inc. (Wendy Palm ) + * Significant portions provided by + * Wayne Schroeder, SDSC + * William Jones, UTexas + * + * 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. + * + * Created: Apr 22 16.34:00 2002 wp + * + * This file contains functions required for proper execution + * on UNICOS systems. + * + */ +#ifdef _UNICOS + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ssh.h" + +#include "includes.h" +#include "sys/types.h" + +#ifndef HAVE_STRUCT_SOCKADDR_STORAGE +# define _SS_MAXSIZE 128 /* Implementation specific max size */ +# define _SS_PADSIZE (_SS_MAXSIZE - sizeof (struct sockaddr)) + +# define ss_family ss_sa.sa_family +#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */ + +#ifndef IN6_IS_ADDR_LOOPBACK +# define IN6_IS_ADDR_LOOPBACK(a) \ + (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \ + ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1)) +#endif /* !IN6_IS_ADDR_LOOPBACK */ + +#ifndef AF_INET6 +/* Define it to something that should never appear */ +#define AF_INET6 AF_MAX +#endif + +#include "log.h" +#include "servconf.h" +#include "bsd-cray.h" + +#define MAXACID 80 + +extern ServerOptions options; + +char cray_tmpdir[TPATHSIZ + 1]; /* job TMPDIR path */ + +struct sysv sysv; /* system security structure */ +struct usrv usrv; /* user security structure */ + +/* + * Functions. + */ +void cray_retain_utmp(struct utmp *, int); +void cray_delete_tmpdir(char *, int, uid_t); +void cray_init_job(struct passwd *); +void cray_set_tmpdir(struct utmp *); +void cray_login_failure(char *, int); +int cray_setup(uid_t, char *, const char *); +int cray_access_denied(char *); + +void +cray_login_failure(char *username, int errcode) +{ + struct udb *ueptr; /* UDB pointer for username */ + ia_failure_t fsent; /* ia_failure structure */ + ia_failure_ret_t fret; /* ia_failure return stuff */ + struct jtab jtab; /* job table structure */ + int jid = 0; /* job id */ + + if ((jid = getjtab(&jtab)) < 0) + debug("cray_login_failure(): getjtab error"); + + getsysudb(); + if ((ueptr = getudbnam(username)) == UDB_NULL) + debug("cray_login_failure(): getudbname() returned NULL"); + endudb(); + + memset(&fsent, '\0', sizeof(fsent)); + fsent.revision = 0; + fsent.uname = username; + fsent.host = (char *)get_canonical_hostname(options.use_dns); + fsent.ttyn = "sshd"; + fsent.caller = IA_SSHD; + fsent.flags = IA_INTERACTIVE; + fsent.ueptr = ueptr; + fsent.jid = jid; + fsent.errcode = errcode; + fsent.pwdp = NULL; + fsent.exitcode = 0; /* dont exit in ia_failure() */ + + fret.revision = 0; + fret.normal = 0; + + /* + * Call ia_failure because of an login failure. + */ + ia_failure(&fsent, &fret); +} + +/* + * Cray access denied + */ +int +cray_access_denied(char *username) +{ + struct udb *ueptr; /* UDB pointer for username */ + int errcode; /* IA errorcode */ + + errcode = 0; + getsysudb(); + if ((ueptr = getudbnam(username)) == UDB_NULL) + debug("cray_login_failure(): getudbname() returned NULL"); + endudb(); + + if (ueptr != NULL && ueptr->ue_disabled) + errcode = IA_DISABLED; + if (errcode) + cray_login_failure(username, errcode); + + return (errcode); +} + +/* + * record_failed_login: generic "login failed" interface function + */ +void +record_failed_login(const char *user, const char *hostname, const char *ttyname) +{ + cray_login_failure((char *)user, IA_UDBERR); +} + +int +cray_setup (uid_t uid, char *username, const char *command) +{ + extern struct udb *getudb(); + extern char *setlimits(); + + int err; /* error return */ + time_t system_time; /* current system clock */ + time_t expiration_time; /* password expiration time */ + int maxattempts; /* maximum no. of failed login attempts */ + int SecureSys; /* unicos security flag */ + int minslevel = 0; /* system minimum security level */ + int i, j; + int valid_acct = -1; /* flag for reading valid acct */ + char acct_name[MAXACID] = { "" }; /* used to read acct name */ + struct jtab jtab; /* Job table struct */ + struct udb ue; /* udb entry for logging-in user */ + struct udb *up; /* pointer to UDB entry */ + struct secstat secinfo; /* file security attributes */ + struct servprov init_info; /* used for sesscntl() call */ + int jid; /* job ID */ + int pid; /* process ID */ + char *sr; /* status return from setlimits() */ + char *ttyn = NULL; /* ttyname or command name*/ + char hostname[MAXHOSTNAMELEN]; + /* passwd stuff for ia_user */ + passwd_t pwdacm, pwddialup, pwdudb, pwdwal, pwddce; + ia_user_ret_t uret; /* stuff returned from ia_user */ + ia_user_t usent; /* ia_user main structure */ + int ia_rcode; /* ia_user return code */ + ia_failure_t fsent; /* ia_failure structure */ + ia_failure_ret_t fret; /* ia_failure return stuff */ + ia_success_t ssent; /* ia_success structure */ + ia_success_ret_t sret; /* ia_success return stuff */ + int ia_mlsrcode; /* ia_mlsuser return code */ + int secstatrc; /* [f]secstat return code */ + + if (SecureSys = (int)sysconf(_SC_CRAY_SECURE_SYS)) { + getsysv(&sysv, sizeof(struct sysv)); + minslevel = sysv.sy_minlvl; + if (getusrv(&usrv) < 0) + fatal("getusrv() failed, errno = %d", errno); + } + hostname[0] = '\0'; + strlcpy(hostname, + (char *)get_canonical_hostname(options.use_dns), + MAXHOSTNAMELEN); + /* + * Fetch user's UDB entry. + */ + getsysudb(); + if ((up = getudbnam(username)) == UDB_NULL) + fatal("cannot fetch user's UDB entry"); + + /* + * Prevent any possible fudging so perform a data + * safety check and compare the supplied uid against + * the udb's uid. + */ + if (up->ue_uid != uid) + fatal("IA uid missmatch"); + endudb(); + + if ((jid = getjtab(&jtab)) < 0) { + debug("getjtab"); + return(-1); + } + pid = getpid(); + ttyn = ttyname(0); + if (SecureSys) { + if (ttyn != NULL) + secstatrc = secstat(ttyn, &secinfo); + else + secstatrc = fsecstat(1, &secinfo); + + if (secstatrc == 0) + debug("[f]secstat() successful"); + else + fatal("[f]secstat() error, rc = %d", secstatrc); + } + if ((ttyn == NULL) && ((char *)command != NULL)) + ttyn = (char *)command; + /* + * Initialize all structures to call ia_user + */ + usent.revision = 0; + usent.uname = username; + usent.host = hostname; + usent.ttyn = ttyn; + usent.caller = IA_SSHD; + usent.pswdlist = &pwdacm; + usent.ueptr = &ue; + usent.flags = IA_INTERACTIVE | IA_FFLAG; + pwdacm.atype = IA_SECURID; + pwdacm.pwdp = NULL; + pwdacm.next = &pwdudb; + + pwdudb.atype = IA_UDB; + pwdudb.pwdp = NULL; + pwdudb.next = &pwddce; + + pwddce.atype = IA_DCE; + pwddce.pwdp = NULL; + pwddce.next = &pwddialup; + + pwddialup.atype = IA_DIALUP; + pwddialup.pwdp = NULL; + /* pwddialup.next = &pwdwal; */ + pwddialup.next = NULL; + + pwdwal.atype = IA_WAL; + pwdwal.pwdp = NULL; + pwdwal.next = NULL; + + uret.revision = 0; + uret.pswd = NULL; + uret.normal = 0; + + ia_rcode = ia_user(&usent, &uret); + switch (ia_rcode) { + /* + * These are acceptable return codes from ia_user() + */ + case IA_UDBWEEK: /* Password Expires in 1 week */ + expiration_time = ue.ue_pwage.time + ue.ue_pwage.maxage; + printf ("WARNING - your current password will expire %s\n", + ctime((const time_t *)&expiration_time)); + break; + case IA_UDBEXPIRED: + if (ttyname(0) != NULL) { + /* Force a password change */ + printf("Your password has expired; Choose a new one.\n"); + execl("/bin/passwd", "passwd", username, 0); + exit(9); + } + break; + case IA_NORMAL: /* Normal Return Code */ + break; + case IA_BACKDOOR: + /* XXX: can we memset it to zero here so save some of this */ + strlcpy(ue.ue_name, "root", sizeof(ue.ue_name)); + strlcpy(ue.ue_dir, "/", sizeof(ue.ue_dir)); + strlcpy(ue.ue_shell, "/bin/sh", sizeof(ue.ue_shell)); + + ue.ue_passwd[0] = '\0'; + ue.ue_age[0] = '\0'; + ue.ue_comment[0] = '\0'; + ue.ue_loghost[0] = '\0'; + ue.ue_logline[0] = '\0'; + + ue.ue_uid = -1; + ue.ue_nice[UDBRC_INTER] = 0; + + for (i = 0; i < MAXVIDS; i++) + ue.ue_gids[i] = 0; + + ue.ue_logfails = 0; + ue.ue_minlvl = ue.ue_maxlvl = ue.ue_deflvl = minslevel; + ue.ue_defcomps = 0; + ue.ue_comparts = 0; + ue.ue_permits = 0; + ue.ue_trap = 0; + ue.ue_disabled = 0; + ue.ue_logtime = 0; + break; + case IA_CONSOLE: /* Superuser not from Console */ + case IA_TRUSTED: /* Trusted user */ + if (options.permit_root_login > PERMIT_NO) + break; /* Accept root login */ + default: + /* + * These are failed return codes from ia_user() + */ + switch (ia_rcode) + { + case IA_BADAUTH: + printf("Bad authorization, access denied.\n"); + break; + case IA_DISABLED: + printf("Your login has been disabled. Contact the system "); + printf("administrator for assistance.\n"); + break; + case IA_GETSYSV: + printf("getsysv() failed - errno = %d\n", errno); + break; + case IA_MAXLOGS: + printf("Maximum number of failed login attempts exceeded.\n"); + printf("Access denied.\n"); + break; + case IA_UDBPWDNULL: + if (SecureSys) + printf("NULL Password not allowed on MLS systems.\n"); + break; + default: + break; + } + + /* + * Authentication failed. + */ + printf("sshd: Login incorrect, (0%o)\n", + ia_rcode-IA_ERRORCODE); + + /* + * Initialize structure for ia_failure + * which will exit. + */ + fsent.revision = 0; + fsent.uname = username; + fsent.host = hostname; + fsent.ttyn = ttyn; + fsent.caller = IA_SSHD; + fsent.flags = IA_INTERACTIVE; + fsent.ueptr = &ue; + fsent.jid = jid; + fsent.errcode = ia_rcode; + fsent.pwdp = uret.pswd; + fsent.exitcode = 1; + + fret.revision = 0; + fret.normal = 0; + + /* + * Call ia_failure because of an IA failure. + * There is no return because ia_failure exits. + */ + ia_failure(&fsent, &fret); + + exit(1); + } + + ia_mlsrcode = IA_NORMAL; + if (SecureSys) { + debug("calling ia_mlsuser()"); + ia_mlsrcode = ia_mlsuser(&ue, &secinfo, &usrv, NULL, 0); + } + if (ia_mlsrcode != IA_NORMAL) { + printf("sshd: Login incorrect, (0%o)\n", + ia_mlsrcode-IA_ERRORCODE); + /* + * Initialize structure for ia_failure + * which will exit. + */ + fsent.revision = 0; + fsent.uname = username; + fsent.host = hostname; + fsent.ttyn = ttyn; + fsent.caller = IA_SSHD; + fsent.flags = IA_INTERACTIVE; + fsent.ueptr = &ue; + fsent.jid = jid; + fsent.errcode = ia_mlsrcode; + fsent.pwdp = uret.pswd; + fsent.exitcode = 1; + fret.revision = 0; + fret.normal = 0; + + /* + * Call ia_failure because of an IA failure. + * There is no return because ia_failure exits. + */ + ia_failure(&fsent,&fret); + exit(1); + } + + /* Provide login status information */ + if (options.print_lastlog && ue.ue_logtime != 0) { + printf("Last successful login was : %.*s ", 19, + (char *)ctime(&ue.ue_logtime)); + + if (*ue.ue_loghost != '\0') { + printf("from %.*s\n", sizeof(ue.ue_loghost), + ue.ue_loghost); + } else { + printf("on %.*s\n", sizeof(ue.ue_logline), + ue.ue_logline); + } + + if (SecureSys && (ue.ue_logfails != 0)) { + printf(" followed by %d failed attempts\n", + ue.ue_logfails); + } + } + + /* + * Call ia_success to process successful I/A. + */ + ssent.revision = 0; + ssent.uname = username; + ssent.host = hostname; + ssent.ttyn = ttyn; + ssent.caller = IA_SSHD; + ssent.flags = IA_INTERACTIVE; + ssent.ueptr = &ue; + ssent.jid = jid; + ssent.errcode = ia_rcode; + ssent.us = NULL; + ssent.time = 1; /* Set ue_logtime */ + + sret.revision = 0; + sret.normal = 0; + + ia_success(&ssent, &sret); + + /* + * Query for account, iff > 1 valid acid & askacid permbit + */ + if (((ue.ue_permbits & PERMBITS_ACCTID) || + (ue.ue_acids[0] >= 0) && (ue.ue_acids[1] >= 0)) && + ue.ue_permbits & PERMBITS_ASKACID) { + if (ttyname(0) != NULL) { + debug("cray_setup: ttyname true case, %.100s", ttyname); + while (valid_acct == -1) { + printf("Account (? for available accounts)" + " [%s]: ", acid2nam(ue.ue_acids[0])); + fgets(acct_name, MAXACID, stdin); + switch (acct_name[0]) { + case EOF: + exit(0); + break; + case '\0': + valid_acct = ue.ue_acids[0]; + strlcpy(acct_name, acid2nam(valid_acct), MAXACID); + break; + case '?': + /* Print the list 3 wide */ + for (i = 0, j = 0; i < MAXVIDS; i++) { + if (ue.ue_acids[i] == -1) { + printf("\n"); + break; + } + if (++j == 4) { + j = 1; + printf("\n"); + } + printf(" %s", + acid2nam(ue.ue_acids[i])); + } + if (ue.ue_permbits & PERMBITS_ACCTID) { + printf("\"acctid\" permbit also allows" + " you to select any valid " + "account name.\n"); + } + printf("\n"); + break; + default: + valid_acct = nam2acid(acct_name); + if (valid_acct == -1) + printf( + "Account id not found for" + " account name \"%s\"\n\n", + acct_name); + break; + } + /* + * If an account was given, search the user's + * acids array to verify they can use this account. + */ + if ((valid_acct != -1) && + !(ue.ue_permbits & PERMBITS_ACCTID)) { + for (i = 0; i < MAXVIDS; i++) { + if (ue.ue_acids[i] == -1) + break; + if (valid_acct == ue.ue_acids[i]) + break; + } + if (i == MAXVIDS || + ue.ue_acids[i] == -1) { + fprintf(stderr, "Cannot set" + " account name to " + "\"%s\", permission " + "denied\n\n", acct_name); + valid_acct = -1; + } + } + } + } else { + /* + * The client isn't connected to a terminal and can't + * respond to an acid prompt. Use default acid. + */ + debug("cray_setup: ttyname false case, %.100s", + ttyname); + valid_acct = ue.ue_acids[0]; + } + } else { + /* + * The user doesn't have the askacid permbit set or + * only has one valid account to use. + */ + valid_acct = ue.ue_acids[0]; + } + if (acctid(0, valid_acct) < 0) { + printf ("Bad account id: %d\n", valid_acct); + exit(1); + } + + /* + * Now set shares, quotas, limits, including CPU time for the + * (interactive) job and process, and set up permissions + * (for chown etc), etc. + */ + if (setshares(ue.ue_uid, valid_acct, printf, 0, 0)) { + printf("Unable to give %d shares to <%s>(%d/%d)\n", + ue.ue_shares, ue.ue_name, ue.ue_uid, valid_acct); + exit(1); + } + + sr = setlimits(username, C_PROC, pid, UDBRC_INTER); + if (sr != NULL) { + debug("%.200s", sr); + exit(1); + } + sr = setlimits(username, C_JOB, jid, UDBRC_INTER); + if (sr != NULL) { + debug("%.200s", sr); + exit(1); + } + /* + * Place the service provider information into + * the session table (Unicos) or job table (Unicos/mk). + * There exist double defines for the job/session table in + * unicos/mk (jtab.h) so no need for a compile time switch. + */ + memset(&init_info, '\0', sizeof(init_info)); + init_info.s_sessinit.si_id = URM_SPT_LOGIN; + init_info.s_sessinit.si_pid = getpid(); + init_info.s_sessinit.si_sid = jid; + sesscntl(0, S_SETSERVPO, (int)&init_info); + + /* + * Set user and controlling tty security attributes. + */ + if (SecureSys) { + if (setusrv(&usrv) == -1) { + debug("setusrv() failed, errno = %d",errno); + exit(1); + } + } + + return (0); +} + +/* + * The rc.* and /etc/sdaemon methods of starting a program on unicos/unicosmk + * can have pal privileges that sshd can inherit which + * could allow a user to su to root with out a password. + * This subroutine clears all privileges. + */ +void +drop_cray_privs() +{ +#if defined(_SC_CRAY_PRIV_SU) + priv_proc_t *privstate; + int result; + extern int priv_set_proc(); + extern priv_proc_t *priv_init_proc(); + + /* + * If ether of theses two flags are not set + * then don't allow this version of ssh to run. + */ + if (!sysconf(_SC_CRAY_PRIV_SU)) + fatal("Not PRIV_SU system."); + if (!sysconf(_SC_CRAY_POSIX_PRIV)) + fatal("Not POSIX_PRIV."); + + debug("Setting MLS labels.");; + + if (sysconf(_SC_CRAY_SECURE_MAC)) { + usrv.sv_minlvl = SYSLOW; + usrv.sv_actlvl = SYSHIGH; + usrv.sv_maxlvl = SYSHIGH; + } else { + usrv.sv_minlvl = sysv.sy_minlvl; + usrv.sv_actlvl = sysv.sy_minlvl; + usrv.sv_maxlvl = sysv.sy_maxlvl; + } + usrv.sv_actcmp = 0; + usrv.sv_valcmp = sysv.sy_valcmp; + + usrv.sv_intcat = TFM_SYSTEM; + usrv.sv_valcat |= (TFM_SYSTEM | TFM_SYSFILE); + + if (setusrv(&usrv) < 0) { + fatal("%s(%d): setusrv(): %s", __FILE__, __LINE__, + strerror(errno)); + } + + if ((privstate = priv_init_proc()) != NULL) { + result = priv_set_proc(privstate); + if (result != 0 ) { + fatal("%s(%d): priv_set_proc(): %s", + __FILE__, __LINE__, strerror(errno)); + } + priv_free_proc(privstate); + } + debug ("Privileges should be cleared..."); +#else + /* XXX: do this differently */ +# error Cray systems must be run with _SC_CRAY_PRIV_SU on! +#endif +} + + +/* + * Retain utmp/wtmp information - used by cray accounting. + */ +void +cray_retain_utmp(struct utmp *ut, int pid) +{ + int fd; + struct utmp utmp; + + if ((fd = open(UTMP_FILE, O_RDONLY)) != -1) { + /* XXX use atomicio */ + while (read(fd, (char *)&utmp, sizeof(utmp)) == sizeof(utmp)) { + if (pid == utmp.ut_pid) { + ut->ut_jid = utmp.ut_jid; + strncpy(ut->ut_tpath, utmp.ut_tpath, sizeof(utmp.ut_tpath)); + strncpy(ut->ut_host, utmp.ut_host, sizeof(utmp.ut_host)); + strncpy(ut->ut_name, utmp.ut_name, sizeof(utmp.ut_name)); + break; + } + } + close(fd); + } else + fatal("Unable to open utmp file"); +} + +/* + * tmpdir support. + */ + +/* + * find and delete jobs tmpdir. + */ +void +cray_delete_tmpdir(char *login, int jid, uid_t uid) +{ + static char jtmp[TPATHSIZ]; + struct stat statbuf; + int child, c, wstat; + + for (c = 'a'; c <= 'z'; c++) { + snprintf(jtmp, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c); + if (stat(jtmp, &statbuf) == 0 && statbuf.st_uid == uid) + break; + } + + if (c > 'z') + return; + + if ((child = fork()) == 0) { + execl(CLEANTMPCMD, CLEANTMPCMD, login, jtmp, (char *)NULL); + fatal("cray_delete_tmpdir: execl of CLEANTMPCMD failed"); + } + + while (waitpid(child, &wstat, 0) == -1 && errno == EINTR) + ; +} + +/* + * Remove tmpdir on job termination. + */ +void +cray_job_termination_handler(int sig) +{ + int jid; + char *login = NULL; + struct jtab jtab; + + if ((jid = waitjob(&jtab)) == -1 || + (login = uid2nam(jtab.j_uid)) == NULL) + return; + + cray_delete_tmpdir(login, jid, jtab.j_uid); +} + +/* + * Set job id and create tmpdir directory. + */ +void +cray_init_job(struct passwd *pw) +{ + int jid; + int c; + + jid = setjob(pw->pw_uid, WJSIGNAL); + if (jid < 0) + fatal("System call setjob failure"); + + for (c = 'a'; c <= 'z'; c++) { + snprintf(cray_tmpdir, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c); + if (mkdir(cray_tmpdir, JTMPMODE) != 0) + continue; + if (chown(cray_tmpdir, pw->pw_uid, pw->pw_gid) != 0) { + rmdir(cray_tmpdir); + continue; + } + break; + } + + if (c > 'z') + cray_tmpdir[0] = '\0'; +} + +void +cray_set_tmpdir(struct utmp *ut) +{ + int jid; + struct jtab jbuf; + + if ((jid = getjtab(&jbuf)) < 0) + return; + + /* + * Set jid and tmpdir in utmp record. + */ + ut->ut_jid = jid; + strncpy(ut->ut_tpath, cray_tmpdir, TPATHSIZ); +} +#endif /* UNICOS */ + +#ifdef _UNICOSMP +#include +/* + * Set job id and create tmpdir directory. + */ +void +cray_init_job(struct passwd *pw) +{ + initrm_silent(pw->pw_uid); + return; +} +#endif /* _UNICOSMP */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-cray.h b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-cray.h new file mode 100644 index 000000000..774eceb5a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-cray.h @@ -0,0 +1,61 @@ +/* $Id: bsd-cray.h,v 1.12 2005/02/02 06:10:11 dtucker Exp $ */ + +/* + * Copyright (c) 2002, Cray Inc. (Wendy Palm ) + * Significant portions provided by + * Wayne Schroeder, SDSC + * William Jones, UTexas + * + * 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. + * + * Created: Apr 22 16.34:00 2002 wp + * + * This file contains functions required for proper execution + * on UNICOS systems. + * + */ + +#ifndef _BSD_CRAY_H +#define _BSD_CRAY_H + +#ifdef _UNICOS + +void cray_init_job(struct passwd *); +void cray_job_termination_handler(int); +void cray_login_failure(char *, int ); +int cray_access_denied(char *); +extern char cray_tmpdir[]; + +#define CUSTOM_FAILED_LOGIN 1 + +#ifndef IA_SSHD +# define IA_SSHD IA_LOGIN +#endif +#ifndef MAXHOSTNAMELEN +# define MAXHOSTNAMELEN 64 +#endif +#ifndef _CRAYT3E +# define TIOCGPGRP (tIOC|20) +#endif + +#endif /* UNICOS */ + +#endif /* _BSD_CRAY_H */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-cygwin_util.c b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-cygwin_util.c new file mode 100644 index 000000000..8672ccf7f --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-cygwin_util.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2000, 2001, 2011, 2013 Corinna Vinschen + * + * 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. + * + * Created: Sat Sep 02 12:17:00 2000 cv + * + * This file contains functions for forcing opened file descriptors to + * binary mode on Windows systems. + */ + +#define NO_BINARY_OPEN /* Avoid redefining open to binary_open for this file */ +#include "includes.h" + +#ifdef HAVE_CYGWIN + +#include +#include +#include +#include + +#include "xmalloc.h" + +int +binary_open(const char *filename, int flags, ...) +{ + va_list ap; + mode_t mode; + + va_start(ap, flags); + mode = va_arg(ap, mode_t); + va_end(ap); + return (open(filename, flags | O_BINARY, mode)); +} + +int +check_ntsec(const char *filename) +{ + return (pathconf(filename, _PC_POSIX_PERMISSIONS)); +} + +const char * +cygwin_ssh_privsep_user() +{ + static char cyg_privsep_user[DNLEN + UNLEN + 2]; + + if (!cyg_privsep_user[0]) + { +#ifdef CW_CYGNAME_FROM_WINNAME + if (cygwin_internal (CW_CYGNAME_FROM_WINNAME, "sshd", cyg_privsep_user, + sizeof cyg_privsep_user) != 0) +#endif + strlcpy(cyg_privsep_user, "sshd", sizeof(cyg_privsep_user)); + } + return cyg_privsep_user; +} + +#define NL(x) x, (sizeof (x) - 1) +#define WENV_SIZ (sizeof (wenv_arr) / sizeof (wenv_arr[0])) + +static struct wenv { + const char *name; + size_t namelen; +} wenv_arr[] = { + { NL("ALLUSERSPROFILE=") }, + { NL("COMPUTERNAME=") }, + { NL("COMSPEC=") }, + { NL("CYGWIN=") }, + { NL("OS=") }, + { NL("PATH=") }, + { NL("PATHEXT=") }, + { NL("PROGRAMFILES=") }, + { NL("SYSTEMDRIVE=") }, + { NL("SYSTEMROOT=") }, + { NL("WINDIR=") } +}; + +char ** +fetch_windows_environment(void) +{ + char **e, **p; + unsigned int i, idx = 0; + + p = xcalloc(WENV_SIZ + 1, sizeof(char *)); + for (e = environ; *e != NULL; ++e) { + for (i = 0; i < WENV_SIZ; ++i) { + if (!strncmp(*e, wenv_arr[i].name, wenv_arr[i].namelen)) + p[idx++] = *e; + } + } + p[idx] = NULL; + return p; +} + +void +free_windows_environment(char **p) +{ + free(p); +} + +#endif /* HAVE_CYGWIN */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-cygwin_util.h b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-cygwin_util.h new file mode 100644 index 000000000..79cb2a197 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-cygwin_util.h @@ -0,0 +1,67 @@ +/* $Id: bsd-cygwin_util.h,v 1.18 2014/05/27 04:34:43 djm Exp $ */ + +/* + * Copyright (c) 2000, 2001, 2011, 2013 Corinna Vinschen + * + * 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. + * + * Created: Sat Sep 02 12:17:00 2000 cv + * + * This file contains functions for forcing opened file descriptors to + * binary mode on Windows systems. + */ + +#ifndef _BSD_CYGWIN_UTIL_H +#define _BSD_CYGWIN_UTIL_H + +#ifdef HAVE_CYGWIN + +#undef ERROR + +/* Avoid including windows headers. */ +typedef void *HANDLE; +#define INVALID_HANDLE_VALUE ((HANDLE) -1) +#define DNLEN 16 +#define UNLEN 256 + +/* Cygwin functions for which declarations are only available when including + windows headers, so we have to define them here explicitely. */ +extern HANDLE cygwin_logon_user (const struct passwd *, const char *); +extern void cygwin_set_impersonation_token (const HANDLE); + +#include +#include + +#define CYGWIN_SSH_PRIVSEP_USER (cygwin_ssh_privsep_user()) +const char *cygwin_ssh_privsep_user(); + +int binary_open(const char *, int , ...); +int check_ntsec(const char *); +char **fetch_windows_environment(void); +void free_windows_environment(char **); + +#ifndef NO_BINARY_OPEN +#define open binary_open +#endif + +#endif /* HAVE_CYGWIN */ + +#endif /* _BSD_CYGWIN_UTIL_H */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-getpeereid.c b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-getpeereid.c new file mode 100644 index 000000000..5f7e677e5 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-getpeereid.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2002,2004 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#if !defined(HAVE_GETPEEREID) + +#include +#include + +#include + +#if defined(SO_PEERCRED) +int +getpeereid(int s, uid_t *euid, gid_t *gid) +{ + struct ucred cred; + socklen_t len = sizeof(cred); + + if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cred, &len) < 0) + return (-1); + *euid = cred.uid; + *gid = cred.gid; + + return (0); +} +#elif defined(HAVE_GETPEERUCRED) + +#ifdef HAVE_UCRED_H +# include +#endif + +int +getpeereid(int s, uid_t *euid, gid_t *gid) +{ + ucred_t *ucred = NULL; + + if (getpeerucred(s, &ucred) == -1) + return (-1); + if ((*euid = ucred_geteuid(ucred)) == -1) + return (-1); + if ((*gid = ucred_getrgid(ucred)) == -1) + return (-1); + + ucred_free(ucred); + + return (0); +} +#else +int +getpeereid(int s, uid_t *euid, gid_t *gid) +{ + *euid = geteuid(); + *gid = getgid(); + + return (0); +} +#endif /* defined(SO_PEERCRED) */ + +#endif /* !defined(HAVE_GETPEEREID) */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-misc.c b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-misc.c new file mode 100644 index 000000000..f7be415ec --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-misc.c @@ -0,0 +1,278 @@ + +/* + * Copyright (c) 1999-2004 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_SYS_TIME_H +# include +#endif + +#include +#include +#include +#include +#include + +#ifndef HAVE___PROGNAME +char *__progname; +#endif + +/* + * NB. duplicate __progname in case it is an alias for argv[0] + * Otherwise it may get clobbered by setproctitle() + */ +char *ssh_get_progname(char *argv0) +{ + char *p, *q; +#ifdef HAVE___PROGNAME + extern char *__progname; + + p = __progname; +#else + if (argv0 == NULL) + return ("unknown"); /* XXX */ + p = strrchr(argv0, '/'); + if (p == NULL) + p = argv0; + else + p++; +#endif + if ((q = strdup(p)) == NULL) { + perror("strdup"); + exit(1); + } + return q; +} + +#ifndef HAVE_SETLOGIN +int setlogin(const char *name) +{ + return (0); +} +#endif /* !HAVE_SETLOGIN */ + +#ifndef HAVE_INNETGR +int innetgr(const char *netgroup, const char *host, + const char *user, const char *domain) +{ + return (0); +} +#endif /* HAVE_INNETGR */ + +#if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) +int seteuid(uid_t euid) +{ + return (setreuid(-1, euid)); +} +#endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ + +#if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) +int setegid(uid_t egid) +{ + return(setresgid(-1, egid, -1)); +} +#endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */ + +#if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR) +const char *strerror(int e) +{ + extern int sys_nerr; + extern char *sys_errlist[]; + + if ((e >= 0) && (e < sys_nerr)) + return (sys_errlist[e]); + + return ("unlisted error"); +} +#endif + +#ifndef HAVE_UTIMES +int utimes(char *filename, struct timeval *tvp) +{ + struct utimbuf ub; + + ub.actime = tvp[0].tv_sec; + ub.modtime = tvp[1].tv_sec; + + return (utime(filename, &ub)); +} +#endif + +#ifndef HAVE_TRUNCATE +int truncate(const char *path, off_t length) +{ + int fd, ret, saverrno; + + fd = open(path, O_WRONLY); + if (fd < 0) + return (-1); + + ret = ftruncate(fd, length); + saverrno = errno; + close(fd); + if (ret == -1) + errno = saverrno; + + return(ret); +} +#endif /* HAVE_TRUNCATE */ + +#if !defined(HAVE_NANOSLEEP) && !defined(HAVE_NSLEEP) +int nanosleep(const struct timespec *req, struct timespec *rem) +{ + int rc, saverrno; + extern int errno; + struct timeval tstart, tstop, tremain, time2wait; + + TIMESPEC_TO_TIMEVAL(&time2wait, req) + (void) gettimeofday(&tstart, NULL); + rc = select(0, NULL, NULL, NULL, &time2wait); + if (rc == -1) { + saverrno = errno; + (void) gettimeofday (&tstop, NULL); + errno = saverrno; + tremain.tv_sec = time2wait.tv_sec - + (tstop.tv_sec - tstart.tv_sec); + tremain.tv_usec = time2wait.tv_usec - + (tstop.tv_usec - tstart.tv_usec); + tremain.tv_sec += tremain.tv_usec / 1000000L; + tremain.tv_usec %= 1000000L; + } else { + tremain.tv_sec = 0; + tremain.tv_usec = 0; + } + if (rem != NULL) + TIMEVAL_TO_TIMESPEC(&tremain, rem) + + return(rc); +} +#endif + +#if !defined(HAVE_USLEEP) +int usleep(unsigned int useconds) +{ + struct timespec ts; + + ts.tv_sec = useconds / 1000000; + ts.tv_nsec = (useconds % 1000000) * 1000; + return nanosleep(&ts, NULL); +} +#endif + +#ifndef HAVE_TCGETPGRP +pid_t +tcgetpgrp(int fd) +{ + int ctty_pgrp; + + if (ioctl(fd, TIOCGPGRP, &ctty_pgrp) == -1) + return(-1); + else + return(ctty_pgrp); +} +#endif /* HAVE_TCGETPGRP */ + +#ifndef HAVE_TCSENDBREAK +int +tcsendbreak(int fd, int duration) +{ +# if defined(TIOCSBRK) && defined(TIOCCBRK) + struct timeval sleepytime; + + sleepytime.tv_sec = 0; + sleepytime.tv_usec = 400000; + if (ioctl(fd, TIOCSBRK, 0) == -1) + return (-1); + (void)select(0, 0, 0, 0, &sleepytime); + if (ioctl(fd, TIOCCBRK, 0) == -1) + return (-1); + return (0); +# else + return -1; +# endif +} +#endif /* HAVE_TCSENDBREAK */ + +mysig_t +mysignal(int sig, mysig_t act) +{ +#ifdef HAVE_SIGACTION + struct sigaction sa, osa; + + if (sigaction(sig, NULL, &osa) == -1) + return (mysig_t) -1; + if (osa.sa_handler != act) { + memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; +#ifdef SA_INTERRUPT + if (sig == SIGALRM) + sa.sa_flags |= SA_INTERRUPT; +#endif + sa.sa_handler = act; + if (sigaction(sig, &sa, NULL) == -1) + return (mysig_t) -1; + } + return (osa.sa_handler); +#else + #undef signal + return (signal(sig, act)); +#endif +} + +#ifndef HAVE_STRDUP +char * +strdup(const char *str) +{ + size_t len; + char *cp; + + len = strlen(str) + 1; + cp = malloc(len); + if (cp != NULL) + return(memcpy(cp, str, len)); + return NULL; +} +#endif + +#ifndef HAVE_ISBLANK +int +isblank(int c) +{ + return (c == ' ' || c == '\t'); +} +#endif + +#ifndef HAVE_GETPGID +pid_t +getpgid(pid_t pid) +{ +#if defined(HAVE_GETPGRP) && !defined(GETPGRP_VOID) + return getpgrp(pid); +#elif defined(HAVE_GETPGRP) + if (pid == 0) + return getpgrp(); +#endif + + errno = ESRCH; + return -1; +} +#endif diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-misc.h b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-misc.h new file mode 100644 index 000000000..ff347a24b --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-misc.h @@ -0,0 +1,125 @@ +/* $Id: bsd-misc.h,v 1.25 2013/08/04 11:48:41 dtucker Exp $ */ + +/* + * Copyright (c) 1999-2004 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _BSD_MISC_H +#define _BSD_MISC_H + +#include "includes.h" + +char *ssh_get_progname(char *); + +#ifndef HAVE_SETSID +#define setsid() setpgrp(0, getpid()) +#endif /* !HAVE_SETSID */ + +#ifndef HAVE_SETENV +int setenv(const char *, const char *, int); +#endif /* !HAVE_SETENV */ + +#ifndef HAVE_SETLOGIN +int setlogin(const char *); +#endif /* !HAVE_SETLOGIN */ + +#ifndef HAVE_INNETGR +int innetgr(const char *, const char *, const char *, const char *); +#endif /* HAVE_INNETGR */ + +#if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) +int seteuid(uid_t); +#endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ + +#if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) +int setegid(uid_t); +#endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */ + +#if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR) +const char *strerror(int); +#endif + +#if !defined(HAVE_SETLINEBUF) +#define setlinebuf(a) (setvbuf((a), NULL, _IOLBF, 0)) +#endif + +#ifndef HAVE_UTIMES +#ifndef HAVE_STRUCT_TIMEVAL +struct timeval { + long tv_sec; + long tv_usec; +} +#endif /* HAVE_STRUCT_TIMEVAL */ + +int utimes(char *, struct timeval *); +#endif /* HAVE_UTIMES */ + +#ifndef HAVE_TRUNCATE +int truncate (const char *, off_t); +#endif /* HAVE_TRUNCATE */ + +#if !defined(HAVE_NANOSLEEP) && !defined(HAVE_NSLEEP) +#ifndef HAVE_STRUCT_TIMESPEC +struct timespec { + time_t tv_sec; + long tv_nsec; +}; +#endif +int nanosleep(const struct timespec *, struct timespec *); +#endif + +#ifndef HAVE_USLEEP +int usleep(unsigned int useconds); +#endif + +#ifndef HAVE_TCGETPGRP +pid_t tcgetpgrp(int); +#endif + +#ifndef HAVE_TCSENDBREAK +int tcsendbreak(int, int); +#endif + +#ifndef HAVE_UNSETENV +int unsetenv(const char *); +#endif + +/* wrapper for signal interface */ +typedef void (*mysig_t)(int); +mysig_t mysignal(int sig, mysig_t act); + +#define signal(a,b) mysignal(a,b) + +#ifndef HAVE_ISBLANK +int isblank(int); +#endif + +#ifndef HAVE_GETPGID +pid_t getpgid(pid_t); +#endif + +#ifndef HAVE_ENDGRENT +# define endgrent() do { } while(0) +#endif + +#ifndef HAVE_KRB5_GET_ERROR_MESSAGE +# define krb5_get_error_message krb5_get_err_text +#endif + +#ifndef HAVE_KRB5_FREE_ERROR_MESSAGE +# define krb5_free_error_message(a,b) do { } while(0) +#endif + +#endif /* _BSD_MISC_H */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-nextstep.c b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-nextstep.c new file mode 100644 index 000000000..8195af88a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-nextstep.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2000,2001 Ben Lindstrom. 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" + +#ifdef HAVE_NEXT +#include +#include +#include "bsd-nextstep.h" + +pid_t +posix_wait(int *status) +{ + union wait statusp; + pid_t wait_pid; + + #undef wait /* Use NeXT's wait() function */ + wait_pid = wait(&statusp); + if (status) + *status = (int) statusp.w_status; + + return (wait_pid); +} + +int +tcgetattr(int fd, struct termios *t) +{ + return (ioctl(fd, TIOCGETA, t)); +} + +int +tcsetattr(int fd, int opt, const struct termios *t) +{ + struct termios localterm; + + if (opt & TCSASOFT) { + localterm = *t; + localterm.c_cflag |= CIGNORE; + t = &localterm; + } + switch (opt & ~TCSASOFT) { + case TCSANOW: + return (ioctl(fd, TIOCSETA, t)); + case TCSADRAIN: + return (ioctl(fd, TIOCSETAW, t)); + case TCSAFLUSH: + return (ioctl(fd, TIOCSETAF, t)); + default: + errno = EINVAL; + return (-1); + } +} + +int tcsetpgrp(int fd, pid_t pgrp) +{ + return (ioctl(fd, TIOCSPGRP, &pgrp)); +} + +speed_t cfgetospeed(const struct termios *t) +{ + return (t->c_ospeed); +} + +speed_t cfgetispeed(const struct termios *t) +{ + return (t->c_ispeed); +} + +int +cfsetospeed(struct termios *t,int speed) +{ + t->c_ospeed = speed; + return (0); +} + +int +cfsetispeed(struct termios *t, int speed) +{ + t->c_ispeed = speed; + return (0); +} +#endif /* HAVE_NEXT */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-nextstep.h b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-nextstep.h new file mode 100644 index 000000000..ca5b4b54a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-nextstep.h @@ -0,0 +1,59 @@ +/* $Id: bsd-nextstep.h,v 1.9 2003/08/29 16:59:52 mouring Exp $ */ + +/* + * Copyright (c) 2000,2001 Ben Lindstrom. 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. + * + */ + +#ifndef _NEXT_POSIX_H +#define _NEXT_POSIX_H + +#ifdef HAVE_NEXT +#include + +/* NGROUPS_MAX is behind -lposix. Use the BSD version which is NGROUPS */ +#undef NGROUPS_MAX +#define NGROUPS_MAX NGROUPS + +/* NeXT's readdir() is BSD (struct direct) not POSIX (struct dirent) */ +#define dirent direct + +/* Swap out NeXT's BSD wait() for a more POSIX complient one */ +pid_t posix_wait(int *); +#define wait(a) posix_wait(a) + +/* #ifdef wrapped functions that need defining for clean compiling */ +pid_t getppid(void); +void vhangup(void); +int innetgr(const char *, const char *, const char *, const char *); + +/* TERMCAP */ +int tcgetattr(int, struct termios *); +int tcsetattr(int, int, const struct termios *); +int tcsetpgrp(int, pid_t); +speed_t cfgetospeed(const struct termios *); +speed_t cfgetispeed(const struct termios *); +int cfsetospeed(struct termios *, int); +int cfsetispeed(struct termios *, int); +#endif /* HAVE_NEXT */ +#endif /* _NEXT_POSIX_H */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-openpty.c b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-openpty.c new file mode 100644 index 000000000..9777eb556 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-openpty.c @@ -0,0 +1,220 @@ +/* + * Please note: this implementation of openpty() is far from complete. + * it is just enough for portable OpenSSH's needs. + */ + +/* + * Copyright (c) 2004 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Allocating a pseudo-terminal, and making it the controlling tty. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#include "includes.h" +#if !defined(HAVE_OPENPTY) + +#include + +#include + +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif + +#ifdef HAVE_FCNTL_H +# include +#endif + +#ifdef HAVE_UTIL_H +# include +#endif /* HAVE_UTIL_H */ + +#ifdef HAVE_PTY_H +# include +#endif +#if defined(HAVE_DEV_PTMX) && defined(HAVE_SYS_STROPTS_H) +# include +#endif + +#include +#include +#include + +#ifndef O_NOCTTY +#define O_NOCTTY 0 +#endif + +int +openpty(int *amaster, int *aslave, char *name, struct termios *termp, + struct winsize *winp) +{ +#if defined(HAVE__GETPTY) + /* + * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more + * pty's automagically when needed + */ + char *slave; + + if ((slave = _getpty(amaster, O_RDWR, 0622, 0)) == NULL) + return (-1); + + /* Open the slave side. */ + if ((*aslave = open(slave, O_RDWR | O_NOCTTY)) == -1) { + close(*amaster); + return (-1); + } + return (0); + +#elif defined(HAVE_DEV_PTMX) + /* + * This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3 + * also has bsd-style ptys, but they simply do not work.) + */ + int ptm; + char *pts; + mysig_t old_signal; + + if ((ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY)) == -1) + return (-1); + + /* XXX: need to close ptm on error? */ + old_signal = signal(SIGCHLD, SIG_DFL); + if (grantpt(ptm) < 0) + return (-1); + signal(SIGCHLD, old_signal); + + if (unlockpt(ptm) < 0) + return (-1); + + if ((pts = ptsname(ptm)) == NULL) + return (-1); + *amaster = ptm; + + /* Open the slave side. */ + if ((*aslave = open(pts, O_RDWR | O_NOCTTY)) == -1) { + close(*amaster); + return (-1); + } + + /* + * Try to push the appropriate streams modules, as described + * in Solaris pts(7). + */ + ioctl(*aslave, I_PUSH, "ptem"); + ioctl(*aslave, I_PUSH, "ldterm"); +# ifndef __hpux + ioctl(*aslave, I_PUSH, "ttcompat"); +# endif /* __hpux */ + + return (0); + +#elif defined(HAVE_DEV_PTS_AND_PTC) + /* AIX-style pty code. */ + const char *ttname; + + if ((*amaster = open("/dev/ptc", O_RDWR | O_NOCTTY)) == -1) + return (-1); + if ((ttname = ttyname(*amaster)) == NULL) + return (-1); + if ((*aslave = open(ttname, O_RDWR | O_NOCTTY)) == -1) { + close(*amaster); + return (-1); + } + return (0); + +#elif defined(_UNICOS) + char ptbuf[64], ttbuf[64]; + int i; + int highpty; + + highpty = 128; +#ifdef _SC_CRAY_NPTY + if ((highpty = sysconf(_SC_CRAY_NPTY)) == -1) + highpty = 128; +#endif /* _SC_CRAY_NPTY */ + + for (i = 0; i < highpty; i++) { + snprintf(ptbuf, sizeof(ptbuf), "/dev/pty/%03d", i); + snprintf(ttbuf, sizeof(ttbuf), "/dev/ttyp%03d", i); + if ((*amaster = open(ptbuf, O_RDWR|O_NOCTTY)) == -1) + continue; + /* Open the slave side. */ + if ((*aslave = open(ttbuf, O_RDWR|O_NOCTTY)) == -1) { + close(*amaster); + return (-1); + } + return (0); + } + return (-1); + +#else + /* BSD-style pty code. */ + char ptbuf[64], ttbuf[64]; + int i; + const char *ptymajors = "pqrstuvwxyzabcdefghijklmno" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const char *ptyminors = "0123456789abcdef"; + int num_minors = strlen(ptyminors); + int num_ptys = strlen(ptymajors) * num_minors; + struct termios tio; + + for (i = 0; i < num_ptys; i++) { + snprintf(ptbuf, sizeof(ptbuf), "/dev/pty%c%c", + ptymajors[i / num_minors], ptyminors[i % num_minors]); + snprintf(ttbuf, sizeof(ttbuf), "/dev/tty%c%c", + ptymajors[i / num_minors], ptyminors[i % num_minors]); + + if ((*amaster = open(ptbuf, O_RDWR | O_NOCTTY)) == -1) { + /* Try SCO style naming */ + snprintf(ptbuf, sizeof(ptbuf), "/dev/ptyp%d", i); + snprintf(ttbuf, sizeof(ttbuf), "/dev/ttyp%d", i); + if ((*amaster = open(ptbuf, O_RDWR | O_NOCTTY)) == -1) + continue; + } + + /* Open the slave side. */ + if ((*aslave = open(ttbuf, O_RDWR | O_NOCTTY)) == -1) { + close(*amaster); + return (-1); + } + /* set tty modes to a sane state for broken clients */ + if (tcgetattr(*amaster, &tio) != -1) { + tio.c_lflag |= (ECHO | ISIG | ICANON); + tio.c_oflag |= (OPOST | ONLCR); + tio.c_iflag |= ICRNL; + tcsetattr(*amaster, TCSANOW, &tio); + } + + return (0); + } + return (-1); +#endif +} + +#endif /* !defined(HAVE_OPENPTY) */ + diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-poll.c b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-poll.c new file mode 100644 index 000000000..73a852480 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-poll.c @@ -0,0 +1,119 @@ +/* $Id: bsd-poll.c,v 1.6 2014/02/05 23:44:13 dtucker Exp $ */ + +/* + * Copyright (c) 2004, 2005, 2007 Darren Tucker (dtucker at zip com au). + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" +#if !defined(HAVE_POLL) + +#include +#include +#ifdef HAVE_SYS_SELECT_H +# include +#endif + +#include +#include +#include +#include "bsd-poll.h" + +/* + * A minimal implementation of poll(2), built on top of select(2). + * + * Only supports POLLIN and POLLOUT flags in pfd.events, and POLLIN, POLLOUT + * and POLLERR flags in revents. + * + * Supports pfd.fd = -1 meaning "unused" although it's not standard. + */ + +int +poll(struct pollfd *fds, nfds_t nfds, int timeout) +{ + nfds_t i; + int saved_errno, ret, fd, maxfd = 0; + fd_set *readfds = NULL, *writefds = NULL, *exceptfds = NULL; + size_t nmemb; + struct timeval tv, *tvp = NULL; + + for (i = 0; i < nfds; i++) { + fd = fds[i].fd; + if (fd >= FD_SETSIZE) { + errno = EINVAL; + return -1; + } + maxfd = MAX(maxfd, fd); + } + + nmemb = howmany(maxfd + 1 , NFDBITS); + if ((readfds = calloc(nmemb, sizeof(fd_mask))) == NULL || + (writefds = calloc(nmemb, sizeof(fd_mask))) == NULL || + (exceptfds = calloc(nmemb, sizeof(fd_mask))) == NULL) { + saved_errno = ENOMEM; + ret = -1; + goto out; + } + + /* populate event bit vectors for the events we're interested in */ + for (i = 0; i < nfds; i++) { + fd = fds[i].fd; + if (fd == -1) + continue; + if (fds[i].events & POLLIN) { + FD_SET(fd, readfds); + FD_SET(fd, exceptfds); + } + if (fds[i].events & POLLOUT) { + FD_SET(fd, writefds); + FD_SET(fd, exceptfds); + } + } + + /* poll timeout is msec, select is timeval (sec + usec) */ + if (timeout >= 0) { + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + tvp = &tv; + } + + ret = select(maxfd + 1, readfds, writefds, exceptfds, tvp); + saved_errno = errno; + + /* scan through select results and set poll() flags */ + for (i = 0; i < nfds; i++) { + fd = fds[i].fd; + fds[i].revents = 0; + if (fd == -1) + continue; + if (FD_ISSET(fd, readfds)) { + fds[i].revents |= POLLIN; + } + if (FD_ISSET(fd, writefds)) { + fds[i].revents |= POLLOUT; + } + if (FD_ISSET(fd, exceptfds)) { + fds[i].revents |= POLLERR; + } + } + +out: + free(readfds); + free(writefds); + free(exceptfds); + if (ret == -1) + errno = saved_errno; + return ret; +} +#endif diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-poll.h b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-poll.h new file mode 100644 index 000000000..dcbb9ca40 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-poll.h @@ -0,0 +1,61 @@ +/* $OpenBSD: poll.h,v 1.11 2003/12/10 23:10:08 millert Exp $ */ + +/* + * Copyright (c) 1996 Theo de Raadt + * 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. + */ + +/* OPENBSD ORIGINAL: sys/sys/poll.h */ + +#if !defined(HAVE_POLL) && !defined(HAVE_POLL_H) +#ifndef _COMPAT_POLL_H_ +#define _COMPAT_POLL_H_ + +typedef struct pollfd { + int fd; + short events; + short revents; +} pollfd_t; + +typedef unsigned int nfds_t; + +#define POLLIN 0x0001 +#define POLLOUT 0x0004 +#define POLLERR 0x0008 +#if 0 +/* the following are currently not implemented */ +#define POLLPRI 0x0002 +#define POLLHUP 0x0010 +#define POLLNVAL 0x0020 +#define POLLRDNORM 0x0040 +#define POLLNORM POLLRDNORM +#define POLLWRNORM POLLOUT +#define POLLRDBAND 0x0080 +#define POLLWRBAND 0x0100 +#endif + +#define INFTIM (-1) /* not standard */ + +int poll(struct pollfd *, nfds_t, int); +#endif /* !_COMPAT_POLL_H_ */ +#endif /* !HAVE_POLL_H */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-setres_id.c b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-setres_id.c new file mode 100644 index 000000000..018bde8c7 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-setres_id.c @@ -0,0 +1,100 @@ +/* $Id: bsd-setres_id.c,v 1.2 2013/12/07 21:23:09 djm Exp $ */ + +/* + * Copyright (c) 2012 Darren Tucker (dtucker at zip com au). + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include + +#include +#include +#include + +#include "log.h" + +#if !defined(HAVE_SETRESGID) || defined(BROKEN_SETRESGID) +int +setresgid(gid_t rgid, gid_t egid, gid_t sgid) +{ + int ret = 0, saved_errno; + + if (rgid != sgid) { + errno = ENOSYS; + return -1; + } +#if defined(HAVE_SETREGID) && !defined(BROKEN_SETREGID) + if (setregid(rgid, egid) < 0) { + saved_errno = errno; + error("setregid %u: %.100s", rgid, strerror(errno)); + errno = saved_errno; + ret = -1; + } +#else + if (setegid(egid) < 0) { + saved_errno = errno; + error("setegid %u: %.100s", (u_int)egid, strerror(errno)); + errno = saved_errno; + ret = -1; + } + if (setgid(rgid) < 0) { + saved_errno = errno; + error("setgid %u: %.100s", rgid, strerror(errno)); + errno = saved_errno; + ret = -1; + } +#endif + return ret; +} +#endif + +#if !defined(HAVE_SETRESUID) || defined(BROKEN_SETRESUID) +int +setresuid(uid_t ruid, uid_t euid, uid_t suid) +{ + int ret = 0, saved_errno; + + if (ruid != suid) { + errno = ENOSYS; + return -1; + } +#if defined(HAVE_SETREUID) && !defined(BROKEN_SETREUID) + if (setreuid(ruid, euid) < 0) { + saved_errno = errno; + error("setreuid %u: %.100s", ruid, strerror(errno)); + errno = saved_errno; + ret = -1; + } +#else + +# ifndef SETEUID_BREAKS_SETUID + if (seteuid(euid) < 0) { + saved_errno = errno; + error("seteuid %u: %.100s", euid, strerror(errno)); + errno = saved_errno; + ret = -1; + } +# endif + if (setuid(ruid) < 0) { + saved_errno = errno; + error("setuid %u: %.100s", ruid, strerror(errno)); + errno = saved_errno; + ret = -1; + } +#endif + return ret; +} +#endif diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-setres_id.h b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-setres_id.h new file mode 100644 index 000000000..6c269e0b9 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-setres_id.h @@ -0,0 +1,24 @@ +/* $Id: bsd-setres_id.h,v 1.1 2012/11/05 06:04:37 dtucker Exp $ */ + +/* + * Copyright (c) 2012 Darren Tucker (dtucker at zip com au). + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HAVE_SETRESGID +int setresgid(gid_t, gid_t, gid_t); +#endif +#ifndef HAVE_SETRESUID +int setresuid(uid_t, uid_t, uid_t); +#endif diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-snprintf.c b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-snprintf.c new file mode 100644 index 000000000..23a635989 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-snprintf.c @@ -0,0 +1,892 @@ +/* + * Copyright Patrick Powell 1995 + * This code is based on code written by Patrick Powell (papowell@astart.com) + * It may be used for any purpose as long as this notice remains intact + * on all source code distributions + */ + +/************************************************************** + * Original: + * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 + * A bombproof version of doprnt (dopr) included. + * Sigh. This sort of thing is always nasty do deal with. Note that + * the version here does not include floating point... + * + * snprintf() is used instead of sprintf() as it does limit checks + * for string length. This covers a nasty loophole. + * + * The other functions are there to prevent NULL pointers from + * causing nast effects. + * + * More Recently: + * Brandon Long 9/15/96 for mutt 0.43 + * This was ugly. It is still ugly. I opted out of floating point + * numbers, but the formatter understands just about everything + * from the normal C string format, at least as far as I can tell from + * the Solaris 2.5 printf(3S) man page. + * + * Brandon Long 10/22/97 for mutt 0.87.1 + * Ok, added some minimal floating point support, which means this + * probably requires libm on most operating systems. Don't yet + * support the exponent (e,E) and sigfig (g,G). Also, fmtint() + * was pretty badly broken, it just wasn't being exercised in ways + * which showed it, so that's been fixed. Also, formated the code + * to mutt conventions, and removed dead code left over from the + * original. Also, there is now a builtin-test, just compile with: + * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm + * and run snprintf for results. + * + * Thomas Roessler 01/27/98 for mutt 0.89i + * The PGP code was using unsigned hexadecimal formats. + * Unfortunately, unsigned formats simply didn't work. + * + * Michael Elkins 03/05/98 for mutt 0.90.8 + * The original code assumed that both snprintf() and vsnprintf() were + * missing. Some systems only have snprintf() but not vsnprintf(), so + * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. + * + * Andrew Tridgell (tridge@samba.org) Oct 1998 + * fixed handling of %.0f + * added test for HAVE_LONG_DOUBLE + * + * tridge@samba.org, idra@samba.org, April 2001 + * got rid of fcvt code (twas buggy and made testing harder) + * added C99 semantics + * + * date: 2002/12/19 19:56:31; author: herb; state: Exp; lines: +2 -0 + * actually print args for %g and %e + * + * date: 2002/06/03 13:37:52; author: jmcd; state: Exp; lines: +8 -0 + * Since includes.h isn't included here, VA_COPY has to be defined here. I don't + * see any include file that is guaranteed to be here, so I'm defining it + * locally. Fixes AIX and Solaris builds. + * + * date: 2002/06/03 03:07:24; author: tridge; state: Exp; lines: +5 -13 + * put the ifdef for HAVE_VA_COPY in one place rather than in lots of + * functions + * + * date: 2002/05/17 14:51:22; author: jmcd; state: Exp; lines: +21 -4 + * Fix usage of va_list passed as an arg. Use __va_copy before using it + * when it exists. + * + * date: 2002/04/16 22:38:04; author: idra; state: Exp; lines: +20 -14 + * Fix incorrect zpadlen handling in fmtfp. + * Thanks to Ollie Oldham for spotting it. + * few mods to make it easier to compile the tests. + * addedd the "Ollie" test to the floating point ones. + * + * Martin Pool (mbp@samba.org) April 2003 + * Remove NO_CONFIG_H so that the test case can be built within a source + * tree with less trouble. + * Remove unnecessary SAFE_FREE() definition. + * + * Martin Pool (mbp@samba.org) May 2003 + * Put in a prototype for dummy_snprintf() to quiet compiler warnings. + * + * Move #endif to make sure VA_COPY, LDOUBLE, etc are defined even + * if the C library has some snprintf functions already. + * + * Damien Miller (djm@mindrot.org) Jan 2007 + * Fix integer overflows in return value. + * Make formatting quite a bit faster by inlining dopr_outch() + * + **************************************************************/ + +#include "includes.h" + +#if defined(BROKEN_SNPRINTF) /* For those with broken snprintf() */ +# undef HAVE_SNPRINTF +# undef HAVE_VSNPRINTF +#endif + +#ifndef VA_COPY +# ifdef HAVE_VA_COPY +# define VA_COPY(dest, src) va_copy(dest, src) +# else +# ifdef HAVE___VA_COPY +# define VA_COPY(dest, src) __va_copy(dest, src) +# else +# define VA_COPY(dest, src) (dest) = (src) +# endif +# endif +#endif + +#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_LONG_DOUBLE +# define LDOUBLE long double +#else +# define LDOUBLE double +#endif + +#ifdef HAVE_LONG_LONG +# define LLONG long long +#else +# define LLONG long +#endif + +/* + * dopr(): poor man's version of doprintf + */ + +/* format read states */ +#define DP_S_DEFAULT 0 +#define DP_S_FLAGS 1 +#define DP_S_MIN 2 +#define DP_S_DOT 3 +#define DP_S_MAX 4 +#define DP_S_MOD 5 +#define DP_S_CONV 6 +#define DP_S_DONE 7 + +/* format flags - Bits */ +#define DP_F_MINUS (1 << 0) +#define DP_F_PLUS (1 << 1) +#define DP_F_SPACE (1 << 2) +#define DP_F_NUM (1 << 3) +#define DP_F_ZERO (1 << 4) +#define DP_F_UP (1 << 5) +#define DP_F_UNSIGNED (1 << 6) + +/* Conversion Flags */ +#define DP_C_SHORT 1 +#define DP_C_LONG 2 +#define DP_C_LDOUBLE 3 +#define DP_C_LLONG 4 +#define DP_C_SIZE 5 +#define DP_C_INTMAX 6 + +#define char_to_int(p) ((p)- '0') +#ifndef MAX +# define MAX(p,q) (((p) >= (q)) ? (p) : (q)) +#endif + +#define DOPR_OUTCH(buf, pos, buflen, thechar) \ + do { \ + if (pos + 1 >= INT_MAX) { \ + errno = ERANGE; \ + return -1; \ + } \ + if (pos < buflen) \ + buf[pos] = thechar; \ + (pos)++; \ + } while (0) + +static int dopr(char *buffer, size_t maxlen, const char *format, + va_list args_in); +static int fmtstr(char *buffer, size_t *currlen, size_t maxlen, + char *value, int flags, int min, int max); +static int fmtint(char *buffer, size_t *currlen, size_t maxlen, + intmax_t value, int base, int min, int max, int flags); +static int fmtfp(char *buffer, size_t *currlen, size_t maxlen, + LDOUBLE fvalue, int min, int max, int flags); + +static int +dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) +{ + char ch; + intmax_t value; + LDOUBLE fvalue; + char *strvalue; + int min; + int max; + int state; + int flags; + int cflags; + size_t currlen; + va_list args; + + VA_COPY(args, args_in); + + state = DP_S_DEFAULT; + currlen = flags = cflags = min = 0; + max = -1; + ch = *format++; + + while (state != DP_S_DONE) { + if (ch == '\0') + state = DP_S_DONE; + + switch(state) { + case DP_S_DEFAULT: + if (ch == '%') + state = DP_S_FLAGS; + else + DOPR_OUTCH(buffer, currlen, maxlen, ch); + ch = *format++; + break; + case DP_S_FLAGS: + switch (ch) { + case '-': + flags |= DP_F_MINUS; + ch = *format++; + break; + case '+': + flags |= DP_F_PLUS; + ch = *format++; + break; + case ' ': + flags |= DP_F_SPACE; + ch = *format++; + break; + case '#': + flags |= DP_F_NUM; + ch = *format++; + break; + case '0': + flags |= DP_F_ZERO; + ch = *format++; + break; + default: + state = DP_S_MIN; + break; + } + break; + case DP_S_MIN: + if (isdigit((unsigned char)ch)) { + min = 10*min + char_to_int (ch); + ch = *format++; + } else if (ch == '*') { + min = va_arg (args, int); + ch = *format++; + state = DP_S_DOT; + } else { + state = DP_S_DOT; + } + break; + case DP_S_DOT: + if (ch == '.') { + state = DP_S_MAX; + ch = *format++; + } else { + state = DP_S_MOD; + } + break; + case DP_S_MAX: + if (isdigit((unsigned char)ch)) { + if (max < 0) + max = 0; + max = 10*max + char_to_int (ch); + ch = *format++; + } else if (ch == '*') { + max = va_arg (args, int); + ch = *format++; + state = DP_S_MOD; + } else { + state = DP_S_MOD; + } + break; + case DP_S_MOD: + switch (ch) { + case 'h': + cflags = DP_C_SHORT; + ch = *format++; + break; + case 'j': + cflags = DP_C_INTMAX; + ch = *format++; + break; + case 'l': + cflags = DP_C_LONG; + ch = *format++; + if (ch == 'l') { /* It's a long long */ + cflags = DP_C_LLONG; + ch = *format++; + } + break; + case 'L': + cflags = DP_C_LDOUBLE; + ch = *format++; + break; + case 'z': + cflags = DP_C_SIZE; + ch = *format++; + break; + default: + break; + } + state = DP_S_CONV; + break; + case DP_S_CONV: + switch (ch) { + case 'd': + case 'i': + if (cflags == DP_C_SHORT) + value = va_arg (args, int); + else if (cflags == DP_C_LONG) + value = va_arg (args, long int); + else if (cflags == DP_C_LLONG) + value = va_arg (args, LLONG); + else if (cflags == DP_C_SIZE) + value = va_arg (args, ssize_t); + else if (cflags == DP_C_INTMAX) + value = va_arg (args, intmax_t); + else + value = va_arg (args, int); + if (fmtint(buffer, &currlen, maxlen, + value, 10, min, max, flags) == -1) + return -1; + break; + case 'o': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg (args, unsigned int); + else if (cflags == DP_C_LONG) + value = (long)va_arg (args, unsigned long int); + else if (cflags == DP_C_LLONG) + value = (long)va_arg (args, unsigned LLONG); + else if (cflags == DP_C_SIZE) + value = va_arg (args, size_t); +#ifdef notyet + else if (cflags == DP_C_INTMAX) + value = va_arg (args, uintmax_t); +#endif + else + value = (long)va_arg (args, unsigned int); + if (fmtint(buffer, &currlen, maxlen, value, + 8, min, max, flags) == -1) + return -1; + break; + case 'u': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg (args, unsigned int); + else if (cflags == DP_C_LONG) + value = (long)va_arg (args, unsigned long int); + else if (cflags == DP_C_LLONG) + value = (LLONG)va_arg (args, unsigned LLONG); + else if (cflags == DP_C_SIZE) + value = va_arg (args, size_t); +#ifdef notyet + else if (cflags == DP_C_INTMAX) + value = va_arg (args, uintmax_t); +#endif + else + value = (long)va_arg (args, unsigned int); + if (fmtint(buffer, &currlen, maxlen, value, + 10, min, max, flags) == -1) + return -1; + break; + case 'X': + flags |= DP_F_UP; + case 'x': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg (args, unsigned int); + else if (cflags == DP_C_LONG) + value = (long)va_arg (args, unsigned long int); + else if (cflags == DP_C_LLONG) + value = (LLONG)va_arg (args, unsigned LLONG); + else if (cflags == DP_C_SIZE) + value = va_arg (args, size_t); +#ifdef notyet + else if (cflags == DP_C_INTMAX) + value = va_arg (args, uintmax_t); +#endif + else + value = (long)va_arg (args, unsigned int); + if (fmtint(buffer, &currlen, maxlen, value, + 16, min, max, flags) == -1) + return -1; + break; + case 'f': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, LDOUBLE); + else + fvalue = va_arg (args, double); + if (fmtfp(buffer, &currlen, maxlen, fvalue, + min, max, flags) == -1) + return -1; + break; + case 'E': + flags |= DP_F_UP; + case 'e': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, LDOUBLE); + else + fvalue = va_arg (args, double); + if (fmtfp(buffer, &currlen, maxlen, fvalue, + min, max, flags) == -1) + return -1; + break; + case 'G': + flags |= DP_F_UP; + case 'g': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, LDOUBLE); + else + fvalue = va_arg (args, double); + if (fmtfp(buffer, &currlen, maxlen, fvalue, + min, max, flags) == -1) + return -1; + break; + case 'c': + DOPR_OUTCH(buffer, currlen, maxlen, + va_arg (args, int)); + break; + case 's': + strvalue = va_arg (args, char *); + if (!strvalue) strvalue = "(NULL)"; + if (max == -1) { + max = strlen(strvalue); + } + if (min > 0 && max >= 0 && min > max) max = min; + if (fmtstr(buffer, &currlen, maxlen, + strvalue, flags, min, max) == -1) + return -1; + break; + case 'p': + strvalue = va_arg (args, void *); + if (fmtint(buffer, &currlen, maxlen, + (long) strvalue, 16, min, max, flags) == -1) + return -1; + break; +#if we_dont_want_this_in_openssh + case 'n': + if (cflags == DP_C_SHORT) { + short int *num; + num = va_arg (args, short int *); + *num = currlen; + } else if (cflags == DP_C_LONG) { + long int *num; + num = va_arg (args, long int *); + *num = (long int)currlen; + } else if (cflags == DP_C_LLONG) { + LLONG *num; + num = va_arg (args, LLONG *); + *num = (LLONG)currlen; + } else if (cflags == DP_C_SIZE) { + ssize_t *num; + num = va_arg (args, ssize_t *); + *num = (ssize_t)currlen; + } else if (cflags == DP_C_INTMAX) { + intmax_t *num; + num = va_arg (args, intmax_t *); + *num = (intmax_t)currlen; + } else { + int *num; + num = va_arg (args, int *); + *num = currlen; + } + break; +#endif + case '%': + DOPR_OUTCH(buffer, currlen, maxlen, ch); + break; + case 'w': + /* not supported yet, treat as next char */ + ch = *format++; + break; + default: + /* Unknown, skip */ + break; + } + ch = *format++; + state = DP_S_DEFAULT; + flags = cflags = min = 0; + max = -1; + break; + case DP_S_DONE: + break; + default: + /* hmm? */ + break; /* some picky compilers need this */ + } + } + if (maxlen != 0) { + if (currlen < maxlen - 1) + buffer[currlen] = '\0'; + else if (maxlen > 0) + buffer[maxlen - 1] = '\0'; + } + + return currlen < INT_MAX ? (int)currlen : -1; +} + +static int +fmtstr(char *buffer, size_t *currlen, size_t maxlen, + char *value, int flags, int min, int max) +{ + int padlen, strln; /* amount to pad */ + int cnt = 0; + +#ifdef DEBUG_SNPRINTF + printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value); +#endif + if (value == 0) { + value = ""; + } + + for (strln = 0; strln < max && value[strln]; ++strln); /* strlen */ + padlen = min - strln; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justify */ + + while ((padlen > 0) && (cnt < max)) { + DOPR_OUTCH(buffer, *currlen, maxlen, ' '); + --padlen; + ++cnt; + } + while (*value && (cnt < max)) { + DOPR_OUTCH(buffer, *currlen, maxlen, *value); + value++; + ++cnt; + } + while ((padlen < 0) && (cnt < max)) { + DOPR_OUTCH(buffer, *currlen, maxlen, ' '); + ++padlen; + ++cnt; + } + return 0; +} + +/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ + +static int +fmtint(char *buffer, size_t *currlen, size_t maxlen, + intmax_t value, int base, int min, int max, int flags) +{ + int signvalue = 0; + unsigned LLONG uvalue; + char convert[20]; + int place = 0; + int spadlen = 0; /* amount to space pad */ + int zpadlen = 0; /* amount to zero pad */ + int caps = 0; + + if (max < 0) + max = 0; + + uvalue = value; + + if(!(flags & DP_F_UNSIGNED)) { + if( value < 0 ) { + signvalue = '-'; + uvalue = -value; + } else { + if (flags & DP_F_PLUS) /* Do a sign (+/i) */ + signvalue = '+'; + else if (flags & DP_F_SPACE) + signvalue = ' '; + } + } + + if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ + + do { + convert[place++] = + (caps? "0123456789ABCDEF":"0123456789abcdef") + [uvalue % (unsigned)base ]; + uvalue = (uvalue / (unsigned)base ); + } while(uvalue && (place < 20)); + if (place == 20) place--; + convert[place] = 0; + + zpadlen = max - place; + spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); + if (zpadlen < 0) zpadlen = 0; + if (spadlen < 0) spadlen = 0; + if (flags & DP_F_ZERO) { + zpadlen = MAX(zpadlen, spadlen); + spadlen = 0; + } + if (flags & DP_F_MINUS) + spadlen = -spadlen; /* Left Justifty */ + +#ifdef DEBUG_SNPRINTF + printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", + zpadlen, spadlen, min, max, place); +#endif + + /* Spaces */ + while (spadlen > 0) { + DOPR_OUTCH(buffer, *currlen, maxlen, ' '); + --spadlen; + } + + /* Sign */ + if (signvalue) + DOPR_OUTCH(buffer, *currlen, maxlen, signvalue); + + /* Zeros */ + if (zpadlen > 0) { + while (zpadlen > 0) { + DOPR_OUTCH(buffer, *currlen, maxlen, '0'); + --zpadlen; + } + } + + /* Digits */ + while (place > 0) { + --place; + DOPR_OUTCH(buffer, *currlen, maxlen, convert[place]); + } + + /* Left Justified spaces */ + while (spadlen < 0) { + DOPR_OUTCH(buffer, *currlen, maxlen, ' '); + ++spadlen; + } + return 0; +} + +static LDOUBLE abs_val(LDOUBLE value) +{ + LDOUBLE result = value; + + if (value < 0) + result = -value; + + return result; +} + +static LDOUBLE POW10(int val) +{ + LDOUBLE result = 1; + + while (val) { + result *= 10; + val--; + } + + return result; +} + +static LLONG ROUND(LDOUBLE value) +{ + LLONG intpart; + + intpart = (LLONG)value; + value = value - intpart; + if (value >= 0.5) intpart++; + + return intpart; +} + +/* a replacement for modf that doesn't need the math library. Should + be portable, but slow */ +static double my_modf(double x0, double *iptr) +{ + int i; + long l; + double x = x0; + double f = 1.0; + + for (i=0;i<100;i++) { + l = (long)x; + if (l <= (x+1) && l >= (x-1)) break; + x *= 0.1; + f *= 10.0; + } + + if (i == 100) { + /* + * yikes! the number is beyond what we can handle. + * What do we do? + */ + (*iptr) = 0; + return 0; + } + + if (i != 0) { + double i2; + double ret; + + ret = my_modf(x0-l*f, &i2); + (*iptr) = l*f + i2; + return ret; + } + + (*iptr) = l; + return x - (*iptr); +} + + +static int +fmtfp (char *buffer, size_t *currlen, size_t maxlen, + LDOUBLE fvalue, int min, int max, int flags) +{ + int signvalue = 0; + double ufvalue; + char iconvert[311]; + char fconvert[311]; + int iplace = 0; + int fplace = 0; + int padlen = 0; /* amount to pad */ + int zpadlen = 0; + int caps = 0; + int idx; + double intpart; + double fracpart; + double temp; + + /* + * AIX manpage says the default is 0, but Solaris says the default + * is 6, and sprintf on AIX defaults to 6 + */ + if (max < 0) + max = 6; + + ufvalue = abs_val (fvalue); + + if (fvalue < 0) { + signvalue = '-'; + } else { + if (flags & DP_F_PLUS) { /* Do a sign (+/i) */ + signvalue = '+'; + } else { + if (flags & DP_F_SPACE) + signvalue = ' '; + } + } + +#if 0 + if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ +#endif + +#if 0 + if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */ +#endif + + /* + * Sorry, we only support 16 digits past the decimal because of our + * conversion method + */ + if (max > 16) + max = 16; + + /* We "cheat" by converting the fractional part to integer by + * multiplying by a factor of 10 + */ + + temp = ufvalue; + my_modf(temp, &intpart); + + fracpart = ROUND((POW10(max)) * (ufvalue - intpart)); + + if (fracpart >= POW10(max)) { + intpart++; + fracpart -= POW10(max); + } + + /* Convert integer part */ + do { + temp = intpart*0.1; + my_modf(temp, &intpart); + idx = (int) ((temp -intpart +0.05)* 10.0); + /* idx = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */ + /* printf ("%llf, %f, %x\n", temp, intpart, idx); */ + iconvert[iplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[idx]; + } while (intpart && (iplace < 311)); + if (iplace == 311) iplace--; + iconvert[iplace] = 0; + + /* Convert fractional part */ + if (fracpart) + { + do { + temp = fracpart*0.1; + my_modf(temp, &fracpart); + idx = (int) ((temp -fracpart +0.05)* 10.0); + /* idx = (int) ((((temp/10) -fracpart) +0.05) *10); */ + /* printf ("%lf, %lf, %ld\n", temp, fracpart, idx ); */ + fconvert[fplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[idx]; + } while(fracpart && (fplace < 311)); + if (fplace == 311) fplace--; + } + fconvert[fplace] = 0; + + /* -1 for decimal point, another -1 if we are printing a sign */ + padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); + zpadlen = max - fplace; + if (zpadlen < 0) zpadlen = 0; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justifty */ + + if ((flags & DP_F_ZERO) && (padlen > 0)) { + if (signvalue) { + DOPR_OUTCH(buffer, *currlen, maxlen, signvalue); + --padlen; + signvalue = 0; + } + while (padlen > 0) { + DOPR_OUTCH(buffer, *currlen, maxlen, '0'); + --padlen; + } + } + while (padlen > 0) { + DOPR_OUTCH(buffer, *currlen, maxlen, ' '); + --padlen; + } + if (signvalue) + DOPR_OUTCH(buffer, *currlen, maxlen, signvalue); + + while (iplace > 0) { + --iplace; + DOPR_OUTCH(buffer, *currlen, maxlen, iconvert[iplace]); + } + +#ifdef DEBUG_SNPRINTF + printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); +#endif + + /* + * Decimal point. This should probably use locale to find the correct + * char to print out. + */ + if (max > 0) { + DOPR_OUTCH(buffer, *currlen, maxlen, '.'); + + while (zpadlen > 0) { + DOPR_OUTCH(buffer, *currlen, maxlen, '0'); + --zpadlen; + } + + while (fplace > 0) { + --fplace; + DOPR_OUTCH(buffer, *currlen, maxlen, fconvert[fplace]); + } + } + + while (padlen < 0) { + DOPR_OUTCH(buffer, *currlen, maxlen, ' '); + ++padlen; + } + return 0; +} +#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */ + +#if !defined(HAVE_VSNPRINTF) +int +vsnprintf (char *str, size_t count, const char *fmt, va_list args) +{ + return dopr(str, count, fmt, args); +} +#endif + +#if !defined(HAVE_SNPRINTF) +int +snprintf(char *str, size_t count, SNPRINTF_CONST char *fmt, ...) +{ + size_t ret; + va_list ap; + + va_start(ap, fmt); + ret = vsnprintf(str, count, fmt, ap); + va_end(ap); + return ret; +} +#endif diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-statvfs.c b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-statvfs.c new file mode 100644 index 000000000..2b1da80ec --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-statvfs.c @@ -0,0 +1,82 @@ +/* $Id: bsd-statvfs.c,v 1.2 2014/01/17 07:10:59 dtucker Exp $ */ + +/* + * Copyright (c) 2008,2014 Darren Tucker + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#if !defined(HAVE_STATVFS) || !defined(HAVE_FSTATVFS) + +#include +#ifdef HAVE_SYS_MOUNT_H +# include +#endif + +#include + +static void +copy_statfs_to_statvfs(struct statvfs *to, struct statfs *from) +{ + to->f_bsize = from->f_bsize; + to->f_frsize = from->f_bsize; /* no exact equivalent */ + to->f_blocks = from->f_blocks; + to->f_bfree = from->f_bfree; + to->f_bavail = from->f_bavail; + to->f_files = from->f_files; + to->f_ffree = from->f_ffree; + to->f_favail = from->f_ffree; /* no exact equivalent */ + to->f_fsid = 0; /* XXX fix me */ + to->f_flag = from->f_flags; + to->f_namemax = MNAMELEN; +} + +# ifndef HAVE_STATVFS +int statvfs(const char *path, struct statvfs *buf) +{ +# ifdef HAVE_STATFS + struct statfs fs; + + memset(&fs, 0, sizeof(fs)); + if (statfs(path, &fs) == -1) + return -1; + copy_statfs_to_statvfs(buf, &fs); + return 0; +# else + errno = ENOSYS; + return -1; +# endif +} +# endif + +# ifndef HAVE_FSTATVFS +int fstatvfs(int fd, struct statvfs *buf) +{ +# ifdef HAVE_FSTATFS + struct statfs fs; + + memset(&fs, 0, sizeof(fs)); + if (fstatfs(fd, &fs) == -1) + return -1; + copy_statfs_to_statvfs(buf, &fs); + return 0; +# else + errno = ENOSYS; + return -1; +# endif +} +# endif + +#endif diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-statvfs.h b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-statvfs.h new file mode 100644 index 000000000..dfd609974 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-statvfs.h @@ -0,0 +1,71 @@ +/* $Id: bsd-statvfs.h,v 1.3 2014/01/17 07:48:22 dtucker Exp $ */ + +/* + * Copyright (c) 2008,2014 Darren Tucker + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#if !defined(HAVE_STATVFS) || !defined(HAVE_FSTATVFS) + +#include + +#ifdef HAVE_SYS_MOUNT_H +#include +#endif +#ifdef HAVE_SYS_STATFS_H +#include +#endif + +#ifndef HAVE_FSBLKCNT_T +typedef unsigned long fsblkcnt_t; +#endif +#ifndef HAVE_FSFILCNT_T +typedef unsigned long fsfilcnt_t; +#endif + +#ifndef ST_RDONLY +#define ST_RDONLY 1 +#endif +#ifndef ST_NOSUID +#define ST_NOSUID 2 +#endif + + /* as defined in IEEE Std 1003.1, 2004 Edition */ +struct statvfs { + unsigned long f_bsize; /* File system block size. */ + unsigned long f_frsize; /* Fundamental file system block size. */ + fsblkcnt_t f_blocks; /* Total number of blocks on file system in */ + /* units of f_frsize. */ + fsblkcnt_t f_bfree; /* Total number of free blocks. */ + fsblkcnt_t f_bavail; /* Number of free blocks available to */ + /* non-privileged process. */ + fsfilcnt_t f_files; /* Total number of file serial numbers. */ + fsfilcnt_t f_ffree; /* Total number of free file serial numbers. */ + fsfilcnt_t f_favail; /* Number of file serial numbers available to */ + /* non-privileged process. */ + unsigned long f_fsid; /* File system ID. */ + unsigned long f_flag; /* BBit mask of f_flag values. */ + unsigned long f_namemax;/* Maximum filename length. */ +}; +#endif + +#ifndef HAVE_STATVFS +int statvfs(const char *, struct statvfs *); +#endif + +#ifndef HAVE_FSTATVFS +int fstatvfs(int, struct statvfs *); +#endif diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-waitpid.c b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-waitpid.c new file mode 100644 index 000000000..40e6ffaa8 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-waitpid.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2000 Ben Lindstrom. 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" + +#ifndef HAVE_WAITPID +#include +#include +#include "bsd-waitpid.h" + +pid_t +waitpid(int pid, int *stat_loc, int options) +{ + union wait statusp; + pid_t wait_pid; + + if (pid <= 0) { + if (pid != -1) { + errno = EINVAL; + return (-1); + } + /* wait4() wants pid=0 for indiscriminate wait. */ + pid = 0; + } + wait_pid = wait4(pid, &statusp, options, NULL); + if (stat_loc) + *stat_loc = (int) statusp.w_status; + + return (wait_pid); +} + +#endif /* !HAVE_WAITPID */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-waitpid.h b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-waitpid.h new file mode 100644 index 000000000..2d853db61 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/bsd-waitpid.h @@ -0,0 +1,51 @@ +/* $Id: bsd-waitpid.h,v 1.5 2003/08/29 16:59:52 mouring Exp $ */ + +/* + * Copyright (c) 2000 Ben Lindstrom. 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. + * + */ + +#ifndef _BSD_WAITPID_H +#define _BSD_WAITPID_H + +#ifndef HAVE_WAITPID +/* Clean out any potental issues */ +#undef WIFEXITED +#undef WIFSTOPPED +#undef WIFSIGNALED + +/* Define required functions to mimic a POSIX look and feel */ +#define _W_INT(w) (*(int*)&(w)) /* convert union wait to int */ +#define WIFEXITED(w) (!((_W_INT(w)) & 0377)) +#define WIFSTOPPED(w) ((_W_INT(w)) & 0100) +#define WIFSIGNALED(w) (!WIFEXITED(w) && !WIFSTOPPED(w)) +#define WEXITSTATUS(w) (int)(WIFEXITED(w) ? ((_W_INT(w) >> 8) & 0377) : -1) +#define WTERMSIG(w) (int)(WIFSIGNALED(w) ? (_W_INT(w) & 0177) : -1) +#define WCOREFLAG 0x80 +#define WCOREDUMP(w) ((_W_INT(w)) & WCOREFLAG) + +/* Prototype */ +pid_t waitpid(int, int *, int); + +#endif /* !HAVE_WAITPID */ +#endif /* _BSD_WAITPID_H */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/chacha_private.h b/crypto/external/bsd/openssh/dist/openbsd-compat/chacha_private.h new file mode 100644 index 000000000..7c3680fa6 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/chacha_private.h @@ -0,0 +1,222 @@ +/* +chacha-merged.c version 20080118 +D. J. Bernstein +Public domain. +*/ + +/* $OpenBSD: chacha_private.h,v 1.2 2013/10/04 07:02:27 djm Exp $ */ + +typedef unsigned char u8; +typedef unsigned int u32; + +typedef struct +{ + u32 input[16]; /* could be compressed */ +} chacha_ctx; + +#define U8C(v) (v##U) +#define U32C(v) (v##U) + +#define U8V(v) ((u8)(v) & U8C(0xFF)) +#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF)) + +#define ROTL32(v, n) \ + (U32V((v) << (n)) | ((v) >> (32 - (n)))) + +#define U8TO32_LITTLE(p) \ + (((u32)((p)[0]) ) | \ + ((u32)((p)[1]) << 8) | \ + ((u32)((p)[2]) << 16) | \ + ((u32)((p)[3]) << 24)) + +#define U32TO8_LITTLE(p, v) \ + do { \ + (p)[0] = U8V((v) ); \ + (p)[1] = U8V((v) >> 8); \ + (p)[2] = U8V((v) >> 16); \ + (p)[3] = U8V((v) >> 24); \ + } while (0) + +#define ROTATE(v,c) (ROTL32(v,c)) +#define XOR(v,w) ((v) ^ (w)) +#define PLUS(v,w) (U32V((v) + (w))) +#define PLUSONE(v) (PLUS((v),1)) + +#define QUARTERROUND(a,b,c,d) \ + a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \ + c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \ + a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \ + c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); + +static const char sigma[16] = "expand 32-byte k"; +static const char tau[16] = "expand 16-byte k"; + +static void +chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits,u32 ivbits) +{ + const char *constants; + + x->input[4] = U8TO32_LITTLE(k + 0); + x->input[5] = U8TO32_LITTLE(k + 4); + x->input[6] = U8TO32_LITTLE(k + 8); + x->input[7] = U8TO32_LITTLE(k + 12); + if (kbits == 256) { /* recommended */ + k += 16; + constants = sigma; + } else { /* kbits == 128 */ + constants = tau; + } + x->input[8] = U8TO32_LITTLE(k + 0); + x->input[9] = U8TO32_LITTLE(k + 4); + x->input[10] = U8TO32_LITTLE(k + 8); + x->input[11] = U8TO32_LITTLE(k + 12); + x->input[0] = U8TO32_LITTLE(constants + 0); + x->input[1] = U8TO32_LITTLE(constants + 4); + x->input[2] = U8TO32_LITTLE(constants + 8); + x->input[3] = U8TO32_LITTLE(constants + 12); +} + +static void +chacha_ivsetup(chacha_ctx *x,const u8 *iv) +{ + x->input[12] = 0; + x->input[13] = 0; + x->input[14] = U8TO32_LITTLE(iv + 0); + x->input[15] = U8TO32_LITTLE(iv + 4); +} + +static void +chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes) +{ + u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; + u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; + u8 *ctarget = NULL; + u8 tmp[64]; + u_int i; + + if (!bytes) return; + + j0 = x->input[0]; + j1 = x->input[1]; + j2 = x->input[2]; + j3 = x->input[3]; + j4 = x->input[4]; + j5 = x->input[5]; + j6 = x->input[6]; + j7 = x->input[7]; + j8 = x->input[8]; + j9 = x->input[9]; + j10 = x->input[10]; + j11 = x->input[11]; + j12 = x->input[12]; + j13 = x->input[13]; + j14 = x->input[14]; + j15 = x->input[15]; + + for (;;) { + if (bytes < 64) { + for (i = 0;i < bytes;++i) tmp[i] = m[i]; + m = tmp; + ctarget = c; + c = tmp; + } + x0 = j0; + x1 = j1; + x2 = j2; + x3 = j3; + x4 = j4; + x5 = j5; + x6 = j6; + x7 = j7; + x8 = j8; + x9 = j9; + x10 = j10; + x11 = j11; + x12 = j12; + x13 = j13; + x14 = j14; + x15 = j15; + for (i = 20;i > 0;i -= 2) { + QUARTERROUND( x0, x4, x8,x12) + QUARTERROUND( x1, x5, x9,x13) + QUARTERROUND( x2, x6,x10,x14) + QUARTERROUND( x3, x7,x11,x15) + QUARTERROUND( x0, x5,x10,x15) + QUARTERROUND( x1, x6,x11,x12) + QUARTERROUND( x2, x7, x8,x13) + QUARTERROUND( x3, x4, x9,x14) + } + x0 = PLUS(x0,j0); + x1 = PLUS(x1,j1); + x2 = PLUS(x2,j2); + x3 = PLUS(x3,j3); + x4 = PLUS(x4,j4); + x5 = PLUS(x5,j5); + x6 = PLUS(x6,j6); + x7 = PLUS(x7,j7); + x8 = PLUS(x8,j8); + x9 = PLUS(x9,j9); + x10 = PLUS(x10,j10); + x11 = PLUS(x11,j11); + x12 = PLUS(x12,j12); + x13 = PLUS(x13,j13); + x14 = PLUS(x14,j14); + x15 = PLUS(x15,j15); + +#ifndef KEYSTREAM_ONLY + x0 = XOR(x0,U8TO32_LITTLE(m + 0)); + x1 = XOR(x1,U8TO32_LITTLE(m + 4)); + x2 = XOR(x2,U8TO32_LITTLE(m + 8)); + x3 = XOR(x3,U8TO32_LITTLE(m + 12)); + x4 = XOR(x4,U8TO32_LITTLE(m + 16)); + x5 = XOR(x5,U8TO32_LITTLE(m + 20)); + x6 = XOR(x6,U8TO32_LITTLE(m + 24)); + x7 = XOR(x7,U8TO32_LITTLE(m + 28)); + x8 = XOR(x8,U8TO32_LITTLE(m + 32)); + x9 = XOR(x9,U8TO32_LITTLE(m + 36)); + x10 = XOR(x10,U8TO32_LITTLE(m + 40)); + x11 = XOR(x11,U8TO32_LITTLE(m + 44)); + x12 = XOR(x12,U8TO32_LITTLE(m + 48)); + x13 = XOR(x13,U8TO32_LITTLE(m + 52)); + x14 = XOR(x14,U8TO32_LITTLE(m + 56)); + x15 = XOR(x15,U8TO32_LITTLE(m + 60)); +#endif + + j12 = PLUSONE(j12); + if (!j12) { + j13 = PLUSONE(j13); + /* stopping at 2^70 bytes per nonce is user's responsibility */ + } + + U32TO8_LITTLE(c + 0,x0); + U32TO8_LITTLE(c + 4,x1); + U32TO8_LITTLE(c + 8,x2); + U32TO8_LITTLE(c + 12,x3); + U32TO8_LITTLE(c + 16,x4); + U32TO8_LITTLE(c + 20,x5); + U32TO8_LITTLE(c + 24,x6); + U32TO8_LITTLE(c + 28,x7); + U32TO8_LITTLE(c + 32,x8); + U32TO8_LITTLE(c + 36,x9); + U32TO8_LITTLE(c + 40,x10); + U32TO8_LITTLE(c + 44,x11); + U32TO8_LITTLE(c + 48,x12); + U32TO8_LITTLE(c + 52,x13); + U32TO8_LITTLE(c + 56,x14); + U32TO8_LITTLE(c + 60,x15); + + if (bytes <= 64) { + if (bytes < 64) { + for (i = 0;i < bytes;++i) ctarget[i] = c[i]; + } + x->input[12] = j12; + x->input[13] = j13; + return; + } + bytes -= 64; + c += 64; +#ifndef KEYSTREAM_ONLY + m += 64; +#endif + } +} diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/charclass.h b/crypto/external/bsd/openssh/dist/openbsd-compat/charclass.h new file mode 100644 index 000000000..91f517447 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/charclass.h @@ -0,0 +1,31 @@ +/* + * Public domain, 2008, Todd C. Miller + * + * $OpenBSD: charclass.h,v 1.1 2008/10/01 23:04:13 millert Exp $ + */ + +/* OPENBSD ORIGINAL: lib/libc/gen/charclass.h */ + +/* + * POSIX character class support for fnmatch() and glob(). + */ +static struct cclass { + const char *name; + int (*isctype)(int); +} cclasses[] = { + { "alnum", isalnum }, + { "alpha", isalpha }, + { "blank", isblank }, + { "cntrl", iscntrl }, + { "digit", isdigit }, + { "graph", isgraph }, + { "lower", islower }, + { "print", isprint }, + { "punct", ispunct }, + { "space", isspace }, + { "upper", isupper }, + { "xdigit", isxdigit }, + { NULL, NULL } +}; + +#define NCCLASSES (sizeof(cclasses) / sizeof(cclasses[0]) - 1) diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/daemon.c b/crypto/external/bsd/openssh/dist/openbsd-compat/daemon.c new file mode 100644 index 000000000..3efe14c68 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/daemon.c @@ -0,0 +1,82 @@ +/* $OpenBSD: daemon.c,v 1.6 2005/08/08 08:05:33 espie Exp $ */ +/*- + * Copyright (c) 1990, 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. 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. + */ + +/* OPENBSD ORIGINAL: lib/libc/gen/daemon.c */ + +#include "includes.h" + +#ifndef HAVE_DAEMON + +#include + +#ifdef HAVE_SYS_STAT_H +# include +#endif + +#ifdef HAVE_FCNTL_H +# include +#endif + +#ifdef HAVE_UNISTD_H +# include +#endif + +int +daemon(int nochdir, int noclose) +{ + int fd; + + switch (fork()) { + case -1: + return (-1); + case 0: + break; + default: + _exit(0); + } + + if (setsid() == -1) + return (-1); + + if (!nochdir) + (void)chdir("/"); + + if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { + (void)dup2(fd, STDIN_FILENO); + (void)dup2(fd, STDOUT_FILENO); + (void)dup2(fd, STDERR_FILENO); + if (fd > 2) + (void)close (fd); + } + return (0); +} + +#endif /* !HAVE_DAEMON */ + diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/dirname.c b/crypto/external/bsd/openssh/dist/openbsd-compat/dirname.c new file mode 100644 index 000000000..30fcb4968 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/dirname.c @@ -0,0 +1,72 @@ +/* $OpenBSD: dirname.c,v 1.13 2005/08/08 08:05:33 espie Exp $ */ + +/* + * Copyright (c) 1997, 2004 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/gen/dirname.c */ + +#include "includes.h" +#ifndef HAVE_DIRNAME + +#include +#include +#include + +char * +dirname(const char *path) +{ + static char dname[MAXPATHLEN]; + size_t len; + const char *endp; + + /* Empty or NULL string gets treated as "." */ + if (path == NULL || *path == '\0') { + dname[0] = '.'; + dname[1] = '\0'; + return (dname); + } + + /* Strip any trailing slashes */ + endp = path + strlen(path) - 1; + while (endp > path && *endp == '/') + endp--; + + /* Find the start of the dir */ + while (endp > path && *endp != '/') + endp--; + + /* Either the dir is "/" or there are no slashes */ + if (endp == path) { + dname[0] = *endp == '/' ? '/' : '.'; + dname[1] = '\0'; + return (dname); + } else { + /* Move forward past the separating slashes */ + do { + endp--; + } while (endp > path && *endp == '/'); + } + + len = endp - path + 1; + if (len >= sizeof(dname)) { + errno = ENAMETOOLONG; + return (NULL); + } + memcpy(dname, path, len); + dname[len] = '\0'; + return (dname); +} +#endif diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/explicit_bzero.c b/crypto/external/bsd/openssh/dist/openbsd-compat/explicit_bzero.c new file mode 100644 index 000000000..3c85a4843 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/explicit_bzero.c @@ -0,0 +1,40 @@ +/* OPENBSD ORIGINAL: lib/libc/string/explicit_bzero.c */ +/* $OpenBSD: explicit_bzero.c,v 1.1 2014/01/22 21:06:45 tedu Exp $ */ +/* + * Public domain. + * Written by Ted Unangst + */ + +#include "includes.h" + +/* + * explicit_bzero - don't let the compiler optimize away bzero + */ + +#ifndef HAVE_EXPLICIT_BZERO + +#ifdef HAVE_MEMSET_S + +void +explicit_bzero(void *p, size_t n) +{ + (void)memset_s(p, n, 0, n); +} + +#else /* HAVE_MEMSET_S */ + +/* + * Indirect bzero through a volatile pointer to hopefully avoid + * dead-store optimisation eliminating the call. + */ +static void (* volatile ssh_bzero)(void *, size_t) = bzero; + +void +explicit_bzero(void *p, size_t n) +{ + ssh_bzero(p, n); +} + +#endif /* HAVE_MEMSET_S */ + +#endif /* HAVE_EXPLICIT_BZERO */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/fake-rfc2553.c b/crypto/external/bsd/openssh/dist/openbsd-compat/fake-rfc2553.c new file mode 100644 index 000000000..096d9e092 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/fake-rfc2553.c @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2000-2003 Damien Miller. All rights reserved. + * Copyright (C) 1999 WIDE Project. 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. Neither the name of the project 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 PROJECT 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 PROJECT 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. + */ + +/* + * Pseudo-implementation of RFC2553 name / address resolution functions + * + * But these functions are not implemented correctly. The minimum subset + * is implemented for ssh use only. For example, this routine assumes + * that ai_family is AF_INET. Don't use it for another purpose. + */ + +#include "includes.h" + +#include +#include + +#include +#include + +#ifndef HAVE_GETNAMEINFO +int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, + size_t hostlen, char *serv, size_t servlen, int flags) +{ + struct sockaddr_in *sin = (struct sockaddr_in *)sa; + struct hostent *hp; + char tmpserv[16]; + + if (sa->sa_family != AF_UNSPEC && sa->sa_family != AF_INET) + return (EAI_FAMILY); + if (serv != NULL) { + snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port)); + if (strlcpy(serv, tmpserv, servlen) >= servlen) + return (EAI_MEMORY); + } + + if (host != NULL) { + if (flags & NI_NUMERICHOST) { + if (strlcpy(host, inet_ntoa(sin->sin_addr), + hostlen) >= hostlen) + return (EAI_MEMORY); + else + return (0); + } else { + hp = gethostbyaddr((char *)&sin->sin_addr, + sizeof(struct in_addr), AF_INET); + if (hp == NULL) + return (EAI_NODATA); + + if (strlcpy(host, hp->h_name, hostlen) >= hostlen) + return (EAI_MEMORY); + else + return (0); + } + } + return (0); +} +#endif /* !HAVE_GETNAMEINFO */ + +#ifndef HAVE_GAI_STRERROR +#ifdef HAVE_CONST_GAI_STRERROR_PROTO +const char * +#else +char * +#endif +gai_strerror(int err) +{ + switch (err) { + case EAI_NODATA: + return ("no address associated with name"); + case EAI_MEMORY: + return ("memory allocation failure."); + case EAI_NONAME: + return ("nodename nor servname provided, or not known"); + case EAI_FAMILY: + return ("ai_family not supported"); + default: + return ("unknown/invalid error."); + } +} +#endif /* !HAVE_GAI_STRERROR */ + +#ifndef HAVE_FREEADDRINFO +void +freeaddrinfo(struct addrinfo *ai) +{ + struct addrinfo *next; + + for(; ai != NULL;) { + next = ai->ai_next; + free(ai); + ai = next; + } +} +#endif /* !HAVE_FREEADDRINFO */ + +#ifndef HAVE_GETADDRINFO +static struct +addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints) +{ + struct addrinfo *ai; + + ai = malloc(sizeof(*ai) + sizeof(struct sockaddr_in)); + if (ai == NULL) + return (NULL); + + memset(ai, '\0', sizeof(*ai) + sizeof(struct sockaddr_in)); + + ai->ai_addr = (struct sockaddr *)(ai + 1); + /* XXX -- ssh doesn't use sa_len */ + ai->ai_addrlen = sizeof(struct sockaddr_in); + ai->ai_addr->sa_family = ai->ai_family = AF_INET; + + ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; + ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; + + /* XXX: the following is not generally correct, but does what we want */ + if (hints->ai_socktype) + ai->ai_socktype = hints->ai_socktype; + else + ai->ai_socktype = SOCK_STREAM; + + if (hints->ai_protocol) + ai->ai_protocol = hints->ai_protocol; + + return (ai); +} + +int +getaddrinfo(const char *hostname, const char *servname, + const struct addrinfo *hints, struct addrinfo **res) +{ + struct hostent *hp; + struct servent *sp; + struct in_addr in; + int i; + long int port; + u_long addr; + + port = 0; + if (hints && hints->ai_family != AF_UNSPEC && + hints->ai_family != AF_INET) + return (EAI_FAMILY); + if (servname != NULL) { + char *cp; + + port = strtol(servname, &cp, 10); + if (port > 0 && port <= 65535 && *cp == '\0') + port = htons(port); + else if ((sp = getservbyname(servname, NULL)) != NULL) + port = sp->s_port; + else + port = 0; + } + + if (hints && hints->ai_flags & AI_PASSIVE) { + addr = htonl(0x00000000); + if (hostname && inet_aton(hostname, &in) != 0) + addr = in.s_addr; + *res = malloc_ai(port, addr, hints); + if (*res == NULL) + return (EAI_MEMORY); + return (0); + } + + if (!hostname) { + *res = malloc_ai(port, htonl(0x7f000001), hints); + if (*res == NULL) + return (EAI_MEMORY); + return (0); + } + + if (inet_aton(hostname, &in)) { + *res = malloc_ai(port, in.s_addr, hints); + if (*res == NULL) + return (EAI_MEMORY); + return (0); + } + + /* Don't try DNS if AI_NUMERICHOST is set */ + if (hints && hints->ai_flags & AI_NUMERICHOST) + return (EAI_NONAME); + + hp = gethostbyname(hostname); + if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { + struct addrinfo *cur, *prev; + + cur = prev = *res = NULL; + for (i = 0; hp->h_addr_list[i]; i++) { + struct in_addr *in = (struct in_addr *)hp->h_addr_list[i]; + + cur = malloc_ai(port, in->s_addr, hints); + if (cur == NULL) { + if (*res != NULL) + freeaddrinfo(*res); + return (EAI_MEMORY); + } + if (prev) + prev->ai_next = cur; + else + *res = cur; + + prev = cur; + } + return (0); + } + + return (EAI_NODATA); +} +#endif /* !HAVE_GETADDRINFO */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/fake-rfc2553.h b/crypto/external/bsd/openssh/dist/openbsd-compat/fake-rfc2553.h new file mode 100644 index 000000000..6426f7bf6 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/fake-rfc2553.h @@ -0,0 +1,178 @@ +/* $Id: fake-rfc2553.h,v 1.16 2008/07/14 11:37:37 djm Exp $ */ + +/* + * Copyright (C) 2000-2003 Damien Miller. All rights reserved. + * Copyright (C) 1999 WIDE Project. 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. Neither the name of the project 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 PROJECT 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 PROJECT 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. + */ + +/* + * Pseudo-implementation of RFC2553 name / address resolution functions + * + * But these functions are not implemented correctly. The minimum subset + * is implemented for ssh use only. For example, this routine assumes + * that ai_family is AF_INET. Don't use it for another purpose. + */ + +#ifndef _FAKE_RFC2553_H +#define _FAKE_RFC2553_H + +#include "includes.h" +#include +#if defined(HAVE_NETDB_H) +# include +#endif + +/* + * First, socket and INET6 related definitions + */ +#ifndef HAVE_STRUCT_SOCKADDR_STORAGE +# define _SS_MAXSIZE 128 /* Implementation specific max size */ +# define _SS_PADSIZE (_SS_MAXSIZE - sizeof (struct sockaddr)) +struct sockaddr_storage { + struct sockaddr ss_sa; + char __ss_pad2[_SS_PADSIZE]; +}; +# define ss_family ss_sa.sa_family +#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */ + +#ifndef IN6_IS_ADDR_LOOPBACK +# define IN6_IS_ADDR_LOOPBACK(a) \ + (((u_int32_t *)(a))[0] == 0 && ((u_int32_t *)(a))[1] == 0 && \ + ((u_int32_t *)(a))[2] == 0 && ((u_int32_t *)(a))[3] == htonl(1)) +#endif /* !IN6_IS_ADDR_LOOPBACK */ + +#ifndef HAVE_STRUCT_IN6_ADDR +struct in6_addr { + u_int8_t s6_addr[16]; +}; +#endif /* !HAVE_STRUCT_IN6_ADDR */ + +#ifndef HAVE_STRUCT_SOCKADDR_IN6 +struct sockaddr_in6 { + unsigned short sin6_family; + u_int16_t sin6_port; + u_int32_t sin6_flowinfo; + struct in6_addr sin6_addr; + u_int32_t sin6_scope_id; +}; +#endif /* !HAVE_STRUCT_SOCKADDR_IN6 */ + +#ifndef AF_INET6 +/* Define it to something that should never appear */ +#define AF_INET6 AF_MAX +#endif + +/* + * Next, RFC2553 name / address resolution API + */ + +#ifndef NI_NUMERICHOST +# define NI_NUMERICHOST (1) +#endif +#ifndef NI_NAMEREQD +# define NI_NAMEREQD (1<<1) +#endif +#ifndef NI_NUMERICSERV +# define NI_NUMERICSERV (1<<2) +#endif + +#ifndef AI_PASSIVE +# define AI_PASSIVE (1) +#endif +#ifndef AI_CANONNAME +# define AI_CANONNAME (1<<1) +#endif +#ifndef AI_NUMERICHOST +# define AI_NUMERICHOST (1<<2) +#endif +#ifndef AI_NUMERICSERV +# define AI_NUMERICSERV (1<<3) +#endif + +#ifndef NI_MAXSERV +# define NI_MAXSERV 32 +#endif /* !NI_MAXSERV */ +#ifndef NI_MAXHOST +# define NI_MAXHOST 1025 +#endif /* !NI_MAXHOST */ + +#ifndef EAI_NODATA +# define EAI_NODATA (INT_MAX - 1) +#endif +#ifndef EAI_MEMORY +# define EAI_MEMORY (INT_MAX - 2) +#endif +#ifndef EAI_NONAME +# define EAI_NONAME (INT_MAX - 3) +#endif +#ifndef EAI_SYSTEM +# define EAI_SYSTEM (INT_MAX - 4) +#endif +#ifndef EAI_FAMILY +# define EAI_FAMILY (INT_MAX - 5) +#endif + +#ifndef HAVE_STRUCT_ADDRINFO +struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for hostname */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ +}; +#endif /* !HAVE_STRUCT_ADDRINFO */ + +#ifndef HAVE_GETADDRINFO +#ifdef getaddrinfo +# undef getaddrinfo +#endif +#define getaddrinfo(a,b,c,d) (ssh_getaddrinfo(a,b,c,d)) +int getaddrinfo(const char *, const char *, + const struct addrinfo *, struct addrinfo **); +#endif /* !HAVE_GETADDRINFO */ + +#if !defined(HAVE_GAI_STRERROR) && !defined(HAVE_CONST_GAI_STRERROR_PROTO) +#define gai_strerror(a) (_ssh_compat_gai_strerror(a)) +char *gai_strerror(int); +#endif /* !HAVE_GAI_STRERROR */ + +#ifndef HAVE_FREEADDRINFO +#define freeaddrinfo(a) (ssh_freeaddrinfo(a)) +void freeaddrinfo(struct addrinfo *); +#endif /* !HAVE_FREEADDRINFO */ + +#ifndef HAVE_GETNAMEINFO +#define getnameinfo(a,b,c,d,e,f,g) (ssh_getnameinfo(a,b,c,d,e,f,g)) +int getnameinfo(const struct sockaddr *, size_t, char *, size_t, + char *, size_t, int); +#endif /* !HAVE_GETNAMEINFO */ + +#endif /* !_FAKE_RFC2553_H */ + diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/fmt_scaled.c b/crypto/external/bsd/openssh/dist/openbsd-compat/fmt_scaled.c new file mode 100644 index 000000000..edd682a49 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/fmt_scaled.c @@ -0,0 +1,274 @@ +/* $OpenBSD: fmt_scaled.c,v 1.9 2007/03/20 03:42:52 tedu Exp $ */ + +/* + * Copyright (c) 2001, 2002, 2003 Ian F. Darwin. 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 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. + */ + +/* OPENBSD ORIGINAL: lib/libutil/fmt_scaled.c */ + +/* + * fmt_scaled: Format numbers scaled for human comprehension + * scan_scaled: Scan numbers in this format. + * + * "Human-readable" output uses 4 digits max, and puts a unit suffix at + * the end. Makes output compact and easy-to-read esp. on huge disks. + * Formatting code was originally in OpenBSD "df", converted to library routine. + * Scanning code written for OpenBSD libutil. + */ + +#include "includes.h" + +#ifndef HAVE_FMT_SCALED + +#include +#include +#include +#include +#include +#include + +typedef enum { + NONE = 0, KILO = 1, MEGA = 2, GIGA = 3, TERA = 4, PETA = 5, EXA = 6 +} unit_type; + +/* These three arrays MUST be in sync! XXX make a struct */ +static unit_type units[] = { NONE, KILO, MEGA, GIGA, TERA, PETA, EXA }; +static char scale_chars[] = "BKMGTPE"; +static long long scale_factors[] = { + 1LL, + 1024LL, + 1024LL*1024, + 1024LL*1024*1024, + 1024LL*1024*1024*1024, + 1024LL*1024*1024*1024*1024, + 1024LL*1024*1024*1024*1024*1024, +}; +#define SCALE_LENGTH (sizeof(units)/sizeof(units[0])) + +#define MAX_DIGITS (SCALE_LENGTH * 3) /* XXX strlen(sprintf("%lld", -1)? */ + +/** Convert the given input string "scaled" into numeric in "result". + * Return 0 on success, -1 and errno set on error. + */ +int +scan_scaled(char *scaled, long long *result) +{ + char *p = scaled; + int sign = 0; + unsigned int i, ndigits = 0, fract_digits = 0; + long long scale_fact = 1, whole = 0, fpart = 0; + + /* Skip leading whitespace */ + while (isascii(*p) && isspace(*p)) + ++p; + + /* Then at most one leading + or - */ + while (*p == '-' || *p == '+') { + if (*p == '-') { + if (sign) { + errno = EINVAL; + return -1; + } + sign = -1; + ++p; + } else if (*p == '+') { + if (sign) { + errno = EINVAL; + return -1; + } + sign = +1; + ++p; + } + } + + /* Main loop: Scan digits, find decimal point, if present. + * We don't allow exponentials, so no scientific notation + * (but note that E for Exa might look like e to some!). + * Advance 'p' to end, to get scale factor. + */ + for (; isascii(*p) && (isdigit(*p) || *p=='.'); ++p) { + if (*p == '.') { + if (fract_digits > 0) { /* oops, more than one '.' */ + errno = EINVAL; + return -1; + } + fract_digits = 1; + continue; + } + + i = (*p) - '0'; /* whew! finally a digit we can use */ + if (fract_digits > 0) { + if (fract_digits >= MAX_DIGITS-1) + /* ignore extra fractional digits */ + continue; + fract_digits++; /* for later scaling */ + fpart *= 10; + fpart += i; + } else { /* normal digit */ + if (++ndigits >= MAX_DIGITS) { + errno = ERANGE; + return -1; + } + whole *= 10; + whole += i; + } + } + + if (sign) { + whole *= sign; + fpart *= sign; + } + + /* If no scale factor given, we're done. fraction is discarded. */ + if (!*p) { + *result = whole; + return 0; + } + + /* Validate scale factor, and scale whole and fraction by it. */ + for (i = 0; i < SCALE_LENGTH; i++) { + + /** Are we there yet? */ + if (*p == scale_chars[i] || + *p == tolower(scale_chars[i])) { + + /* If it ends with alphanumerics after the scale char, bad. */ + if (isalnum(*(p+1))) { + errno = EINVAL; + return -1; + } + scale_fact = scale_factors[i]; + + /* scale whole part */ + whole *= scale_fact; + + /* truncate fpart so it does't overflow. + * then scale fractional part. + */ + while (fpart >= LLONG_MAX / scale_fact) { + fpart /= 10; + fract_digits--; + } + fpart *= scale_fact; + if (fract_digits > 0) { + for (i = 0; i < fract_digits -1; i++) + fpart /= 10; + } + whole += fpart; + *result = whole; + return 0; + } + } + errno = ERANGE; + return -1; +} + +/* Format the given "number" into human-readable form in "result". + * Result must point to an allocated buffer of length FMT_SCALED_STRSIZE. + * Return 0 on success, -1 and errno set if error. + */ +int +fmt_scaled(long long number, char *result) +{ + long long abval, fract = 0; + unsigned int i; + unit_type unit = NONE; + + abval = (number < 0LL) ? -number : number; /* no long long_abs yet */ + + /* Not every negative long long has a positive representation. + * Also check for numbers that are just too darned big to format + */ + if (abval < 0 || abval / 1024 >= scale_factors[SCALE_LENGTH-1]) { + errno = ERANGE; + return -1; + } + + /* scale whole part; get unscaled fraction */ + for (i = 0; i < SCALE_LENGTH; i++) { + if (abval/1024 < scale_factors[i]) { + unit = units[i]; + fract = (i == 0) ? 0 : abval % scale_factors[i]; + number /= scale_factors[i]; + if (i > 0) + fract /= scale_factors[i - 1]; + break; + } + } + + fract = (10 * fract + 512) / 1024; + /* if the result would be >= 10, round main number */ + if (fract == 10) { + if (number >= 0) + number++; + else + number--; + fract = 0; + } + + if (number == 0) + strlcpy(result, "0B", FMT_SCALED_STRSIZE); + else if (unit == NONE || number >= 100 || number <= -100) { + if (fract >= 5) { + if (number >= 0) + number++; + else + number--; + } + (void)snprintf(result, FMT_SCALED_STRSIZE, "%lld%c", + number, scale_chars[unit]); + } else + (void)snprintf(result, FMT_SCALED_STRSIZE, "%lld.%1lld%c", + number, fract, scale_chars[unit]); + + return 0; +} + +#ifdef MAIN +/* + * This is the original version of the program in the man page. + * Copy-and-paste whatever you need from it. + */ +int +main(int argc, char **argv) +{ + char *cinput = "1.5K", buf[FMT_SCALED_STRSIZE]; + long long ninput = 10483892, result; + + if (scan_scaled(cinput, &result) == 0) + printf("\"%s\" -> %lld\n", cinput, result); + else + perror(cinput); + + if (fmt_scaled(ninput, buf) == 0) + printf("%lld -> \"%s\"\n", ninput, buf); + else + fprintf(stderr, "%lld invalid (%s)\n", ninput, strerror(errno)); + + return 0; +} +#endif + +#endif /* HAVE_FMT_SCALED */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/getcwd.c b/crypto/external/bsd/openssh/dist/openbsd-compat/getcwd.c new file mode 100644 index 000000000..3edbb9cba --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/getcwd.c @@ -0,0 +1,240 @@ +/* from OpenBSD: getcwd.c,v 1.14 2005/08/08 08:05:34 espie Exp */ +/* + * Copyright (c) 1989, 1991, 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. 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. + */ + +/* OPENBSD ORIGINAL: lib/libc/gen/getcwd.c */ + +#include "includes.h" + +#if !defined(HAVE_GETCWD) + +#include +#include +#include +#include +#include +#include +#include +#include +#include "includes.h" + +#define ISDOT(dp) \ + (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \ + (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) + +char * +getcwd(char *pt, size_t size) +{ + struct dirent *dp; + DIR *dir = NULL; + dev_t dev; + ino_t ino; + int first; + char *bpt, *bup; + struct stat s; + dev_t root_dev; + ino_t root_ino; + size_t ptsize, upsize; + int save_errno; + char *ept, *eup, *up; + + /* + * If no buffer specified by the user, allocate one as necessary. + * If a buffer is specified, the size has to be non-zero. The path + * is built from the end of the buffer backwards. + */ + if (pt) { + ptsize = 0; + if (!size) { + errno = EINVAL; + return (NULL); + } + ept = pt + size; + } else { + if ((pt = malloc(ptsize = MAXPATHLEN)) == NULL) + return (NULL); + ept = pt + ptsize; + } + bpt = ept - 1; + *bpt = '\0'; + + /* + * Allocate bytes for the string of "../"'s. + * Should always be enough (it's 340 levels). If it's not, allocate + * as necessary. Special * case the first stat, it's ".", not "..". + */ + if ((up = malloc(upsize = MAXPATHLEN)) == NULL) + goto err; + eup = up + upsize; + bup = up; + up[0] = '.'; + up[1] = '\0'; + + /* Save root values, so know when to stop. */ + if (stat("/", &s)) + goto err; + root_dev = s.st_dev; + root_ino = s.st_ino; + + errno = 0; /* XXX readdir has no error return. */ + + for (first = 1;; first = 0) { + /* Stat the current level. */ + if (lstat(up, &s)) + goto err; + + /* Save current node values. */ + ino = s.st_ino; + dev = s.st_dev; + + /* Check for reaching root. */ + if (root_dev == dev && root_ino == ino) { + *--bpt = '/'; + /* + * It's unclear that it's a requirement to copy the + * path to the beginning of the buffer, but it's always + * been that way and stuff would probably break. + */ + memmove(pt, bpt, ept - bpt); + free(up); + return (pt); + } + + /* + * Build pointer to the parent directory, allocating memory + * as necessary. Max length is 3 for "../", the largest + * possible component name, plus a trailing NUL. + */ + if (bup + 3 + MAXNAMLEN + 1 >= eup) { + char *nup; + + if ((nup = realloc(up, upsize *= 2)) == NULL) + goto err; + bup = nup + (bup - up); + up = nup; + eup = up + upsize; + } + *bup++ = '.'; + *bup++ = '.'; + *bup = '\0'; + + /* Open and stat parent directory. */ + if (!(dir = opendir(up)) || fstat(dirfd(dir), &s)) + goto err; + + /* Add trailing slash for next directory. */ + *bup++ = '/'; + + /* + * If it's a mount point, have to stat each element because + * the inode number in the directory is for the entry in the + * parent directory, not the inode number of the mounted file. + */ + save_errno = 0; + if (s.st_dev == dev) { + for (;;) { + if (!(dp = readdir(dir))) + goto notfound; + if (dp->d_fileno == ino) + break; + } + } else + for (;;) { + if (!(dp = readdir(dir))) + goto notfound; + if (ISDOT(dp)) + continue; + memcpy(bup, dp->d_name, dp->d_namlen + 1); + + /* Save the first error for later. */ + if (lstat(up, &s)) { + if (!save_errno) + save_errno = errno; + errno = 0; + continue; + } + if (s.st_dev == dev && s.st_ino == ino) + break; + } + + /* + * Check for length of the current name, preceding slash, + * leading slash. + */ + if (bpt - pt < dp->d_namlen + (first ? 1 : 2)) { + size_t len; + char *npt; + + if (!ptsize) { + errno = ERANGE; + goto err; + } + len = ept - bpt; + if ((npt = realloc(pt, ptsize *= 2)) == NULL) + goto err; + bpt = npt + (bpt - pt); + pt = npt; + ept = pt + ptsize; + memmove(ept - len, bpt, len); + bpt = ept - len; + } + if (!first) + *--bpt = '/'; + bpt -= dp->d_namlen; + memcpy(bpt, dp->d_name, dp->d_namlen); + (void)closedir(dir); + + /* Truncate any file name. */ + *bup = '\0'; + } + +notfound: + /* + * If readdir set errno, use it, not any saved error; otherwise, + * didn't find the current directory in its parent directory, set + * errno to ENOENT. + */ + if (!errno) + errno = save_errno ? save_errno : ENOENT; + /* FALLTHROUGH */ +err: + save_errno = errno; + + if (ptsize) + free(pt); + free(up); + if (dir) + (void)closedir(dir); + + errno = save_errno; + + return (NULL); +} + +#endif /* !defined(HAVE_GETCWD) */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/getgrouplist.c b/crypto/external/bsd/openssh/dist/openbsd-compat/getgrouplist.c new file mode 100644 index 000000000..3afcb9281 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/getgrouplist.c @@ -0,0 +1,95 @@ +/* from OpenBSD: getgrouplist.c,v 1.12 2005/08/08 08:05:34 espie Exp */ +/* + * Copyright (c) 1991, 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. 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. + */ + +/* OPENBSD ORIGINAL: lib/libc/gen/getgrouplist.c */ + +#include "includes.h" + +#ifndef HAVE_GETGROUPLIST + +/* + * get credential + */ +#include +#include +#include +#include + +int +getgrouplist(const char *uname, gid_t agroup, gid_t *groups, int *grpcnt) +{ + struct group *grp; + int i, ngroups; + int ret, maxgroups; + int bail; + + ret = 0; + ngroups = 0; + maxgroups = *grpcnt; + + /* + * install primary group + */ + if (ngroups >= maxgroups) { + *grpcnt = ngroups; + return (-1); + } + groups[ngroups++] = agroup; + + /* + * Scan the group file to find additional groups. + */ + setgrent(); + while ((grp = getgrent())) { + if (grp->gr_gid == agroup) + continue; + for (bail = 0, i = 0; bail == 0 && i < ngroups; i++) + if (groups[i] == grp->gr_gid) + bail = 1; + if (bail) + continue; + for (i = 0; grp->gr_mem[i]; i++) { + if (!strcmp(grp->gr_mem[i], uname)) { + if (ngroups >= maxgroups) { + ret = -1; + goto out; + } + groups[ngroups++] = grp->gr_gid; + break; + } + } + } +out: + endgrent(); + *grpcnt = ngroups; + return (ret); +} + +#endif /* HAVE_GETGROUPLIST */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/getopt.h b/crypto/external/bsd/openssh/dist/openbsd-compat/getopt.h new file mode 100644 index 000000000..8eb12447e --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/getopt.h @@ -0,0 +1,74 @@ +/* $OpenBSD: getopt.h,v 1.2 2008/06/26 05:42:04 ray Exp $ */ +/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#ifndef _GETOPT_H_ +#define _GETOPT_H_ + +/* + * GNU-like getopt_long() and 4.4BSD getsubopt()/optreset extensions + */ +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +struct option { + /* name of long option */ + const char *name; + /* + * one of no_argument, required_argument, and optional_argument: + * whether option takes an argument + */ + int has_arg; + /* if not NULL, set *flag to val when option found */ + int *flag; + /* if flag not NULL, value to set *flag to; else return value */ + int val; +}; + +int getopt_long(int, char * const *, const char *, + const struct option *, int *); +int getopt_long_only(int, char * const *, const char *, + const struct option *, int *); +#ifndef _GETOPT_DEFINED_ +#define _GETOPT_DEFINED_ +int getopt(int, char * const *, const char *); +int getsubopt(char **, char * const *, char **); + +extern char *optarg; /* getopt(3) external variables */ +extern int opterr; +extern int optind; +extern int optopt; +extern int optreset; +extern char *suboptarg; /* getsubopt(3) external variable */ +#endif + +#endif /* !_GETOPT_H_ */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/getopt_long.c b/crypto/external/bsd/openssh/dist/openbsd-compat/getopt_long.c new file mode 100644 index 000000000..e28947430 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/getopt_long.c @@ -0,0 +1,532 @@ +/* $OpenBSD: getopt_long.c,v 1.25 2011/03/05 22:10:11 guenther Exp $ */ +/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ + +/* + * Copyright (c) 2002 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* OPENBSD ORIGINAL: lib/libc/stdlib/getopt_long.c */ +#include "includes.h" + +#if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET) + +/* + * Some defines to make it easier to keep the code in sync with upstream. + * getopt opterr optind optopt optreset optarg are all in defines.h which is + * pulled in by includes.h. + */ +#define warnx logit + +#if 0 +#include +#include +#endif +#include +#include +#include +#include + +#include "log.h" + +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt = '?'; /* character checked for validity */ +int optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ + +#define PRINT_ERROR ((opterr) && (*options != ':')) + +#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ +#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ +#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ + +/* return values */ +#define BADCH (int)'?' +#define BADARG ((*options == ':') ? (int)':' : (int)'?') +#define INORDER (int)1 + +#define EMSG "" + +static int getopt_internal(int, char * const *, const char *, + const struct option *, int *, int); +static int parse_long_options(char * const *, const char *, + const struct option *, int *, int); +static int gcd(int, int); +static void permute_args(int, int, int, char * const *); + +static char *place = EMSG; /* option letter processing */ + +/* XXX: set optreset to 1 rather than these two */ +static int nonopt_start = -1; /* first non option argument (for permute) */ +static int nonopt_end = -1; /* first option after non options (for permute) */ + +/* Error messages */ +static const char recargchar[] = "option requires an argument -- %c"; +static const char recargstring[] = "option requires an argument -- %s"; +static const char ambig[] = "ambiguous option -- %.*s"; +static const char noarg[] = "option doesn't take an argument -- %.*s"; +static const char illoptchar[] = "unknown option -- %c"; +static const char illoptstring[] = "unknown option -- %s"; + +/* + * Compute the greatest common divisor of a and b. + */ +static int +gcd(int a, int b) +{ + int c; + + c = a % b; + while (c != 0) { + a = b; + b = c; + c = a % b; + } + + return (b); +} + +/* + * Exchange the block from nonopt_start to nonopt_end with the block + * from nonopt_end to opt_end (keeping the same order of arguments + * in each block). + */ +static void +permute_args(int panonopt_start, int panonopt_end, int opt_end, + char * const *nargv) +{ + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char *swap; + + /* + * compute lengths of blocks and number and size of cycles + */ + nnonopts = panonopt_end - panonopt_start; + nopts = opt_end - panonopt_end; + ncycle = gcd(nnonopts, nopts); + cyclelen = (opt_end - panonopt_start) / ncycle; + + for (i = 0; i < ncycle; i++) { + cstart = panonopt_end+i; + pos = cstart; + for (j = 0; j < cyclelen; j++) { + if (pos >= panonopt_end) + pos -= nnonopts; + else + pos += nopts; + swap = nargv[pos]; + /* LINTED const cast */ + ((char **) nargv)[pos] = nargv[cstart]; + /* LINTED const cast */ + ((char **)nargv)[cstart] = swap; + } + } +} + +/* + * parse_long_options -- + * Parse long options in argc/argv argument vector. + * Returns -1 if short_too is set and the option does not match long_options. + */ +static int +parse_long_options(char * const *nargv, const char *options, + const struct option *long_options, int *idx, int short_too) +{ + char *current_argv, *has_equal; + size_t current_argv_len; + int i, match; + + current_argv = place; + match = -1; + + optind++; + + if ((has_equal = strchr(current_argv, '=')) != NULL) { + /* argument found (--option=arg) */ + current_argv_len = has_equal - current_argv; + has_equal++; + } else + current_argv_len = strlen(current_argv); + + for (i = 0; long_options[i].name; i++) { + /* find matching long option */ + if (strncmp(current_argv, long_options[i].name, + current_argv_len)) + continue; + + if (strlen(long_options[i].name) == current_argv_len) { + /* exact match */ + match = i; + break; + } + /* + * If this is a known short option, don't allow + * a partial match of a single character. + */ + if (short_too && current_argv_len == 1) + continue; + + if (match == -1) /* partial match */ + match = i; + else { + /* ambiguous abbreviation */ + if (PRINT_ERROR) + warnx(ambig, (int)current_argv_len, + current_argv); + optopt = 0; + return (BADCH); + } + } + if (match != -1) { /* option found */ + if (long_options[match].has_arg == no_argument + && has_equal) { + if (PRINT_ERROR) + warnx(noarg, (int)current_argv_len, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + return (BADARG); + } + if (long_options[match].has_arg == required_argument || + long_options[match].has_arg == optional_argument) { + if (has_equal) + optarg = has_equal; + else if (long_options[match].has_arg == + required_argument) { + /* + * optional argument doesn't use next nargv + */ + optarg = nargv[optind++]; + } + } + if ((long_options[match].has_arg == required_argument) + && (optarg == NULL)) { + /* + * Missing argument; leading ':' indicates no error + * should be generated. + */ + if (PRINT_ERROR) + warnx(recargstring, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + --optind; + return (BADARG); + } + } else { /* unknown option */ + if (short_too) { + --optind; + return (-1); + } + if (PRINT_ERROR) + warnx(illoptstring, current_argv); + optopt = 0; + return (BADCH); + } + if (idx) + *idx = match; + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + return (0); + } else + return (long_options[match].val); +} + +/* + * getopt_internal -- + * Parse argc/argv argument vector. Called by user level routines. + */ +static int +getopt_internal(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx, int flags) +{ + char *oli; /* option letter list index */ + int optchar, short_too; + static int posixly_correct = -1; + + if (options == NULL) + return (-1); + + /* + * XXX Some GNU programs (like cvs) set optind to 0 instead of + * XXX using optreset. Work around this braindamage. + */ + if (optind == 0) + optind = optreset = 1; + + /* + * Disable GNU extensions if POSIXLY_CORRECT is set or options + * string begins with a '+'. + */ + if (posixly_correct == -1 || optreset) + posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); + if (*options == '-') + flags |= FLAG_ALLARGS; + else if (posixly_correct || *options == '+') + flags &= ~FLAG_PERMUTE; + if (*options == '+' || *options == '-') + options++; + + optarg = NULL; + if (optreset) + nonopt_start = nonopt_end = -1; +start: + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc) { /* end of argument vector */ + place = EMSG; + if (nonopt_end != -1) { + /* do permutation, if we have to */ + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + else if (nonopt_start != -1) { + /* + * If we skipped non-options, set optind + * to the first of them. + */ + optind = nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + if (*(place = nargv[optind]) != '-' || + (place[1] == '\0' && strchr(options, '-') == NULL)) { + place = EMSG; /* found non-option */ + if (flags & FLAG_ALLARGS) { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + optarg = nargv[optind++]; + return (INORDER); + } + if (!(flags & FLAG_PERMUTE)) { + /* + * If no permutation wanted, stop parsing + * at first non-option. + */ + return (-1); + } + /* do permutation */ + if (nonopt_start == -1) + nonopt_start = optind; + else if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + nonopt_start = optind - + (nonopt_end - nonopt_start); + nonopt_end = -1; + } + optind++; + /* process next argument */ + goto start; + } + if (nonopt_start != -1 && nonopt_end == -1) + nonopt_end = optind; + + /* + * If we have "-" do nothing, if "--" we are done. + */ + if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { + optind++; + place = EMSG; + /* + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + } + + /* + * Check long options if: + * 1) we were passed some + * 2) the arg is not just "-" + * 3) either the arg starts with -- we are getopt_long_only() + */ + if (long_options != NULL && place != nargv[optind] && + (*place == '-' || (flags & FLAG_LONGONLY))) { + short_too = 0; + if (*place == '-') + place++; /* --foo long option */ + else if (*place != ':' && strchr(options, *place) != NULL) + short_too = 1; /* could be short option too */ + + optchar = parse_long_options(nargv, options, long_options, + idx, short_too); + if (optchar != -1) { + place = EMSG; + return (optchar); + } + } + + if ((optchar = (int)*place++) == (int)':' || + (optchar == (int)'-' && *place != '\0') || + (oli = strchr(options, optchar)) == NULL) { + /* + * If the user specified "-" and '-' isn't listed in + * options, return -1 (non-option) as per POSIX. + * Otherwise, it is an unknown option character (or ':'). + */ + if (optchar == (int)'-' && *place == '\0') + return (-1); + if (!*place) + ++optind; + if (PRINT_ERROR) + warnx(illoptchar, optchar); + optopt = optchar; + return (BADCH); + } + if (long_options != NULL && optchar == 'W' && oli[1] == ';') { + /* -W long-option */ + if (*place) /* no space */ + /* NOTHING */; + else if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else /* white space */ + place = nargv[optind]; + optchar = parse_long_options(nargv, options, long_options, + idx, 0); + place = EMSG; + return (optchar); + } + if (*++oli != ':') { /* doesn't take argument */ + if (!*place) + ++optind; + } else { /* takes (optional) argument */ + optarg = NULL; + if (*place) /* no white space */ + optarg = place; + else if (oli[1] != ':') { /* arg not optional */ + if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else + optarg = nargv[optind]; + } + place = EMSG; + ++optind; + } + /* dump back option letter */ + return (optchar); +} + +/* + * getopt -- + * Parse argc/argv argument vector. + * + * [eventually this will replace the BSD getopt] + */ +int +getopt(int nargc, char * const *nargv, const char *options) +{ + + /* + * We don't pass FLAG_PERMUTE to getopt_internal() since + * the BSD getopt(3) (unlike GNU) has never done this. + * + * Furthermore, since many privileged programs call getopt() + * before dropping privileges it makes sense to keep things + * as simple (and bug-free) as possible. + */ + return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); +} + +#if 0 +/* + * getopt_long -- + * Parse argc/argv argument vector. + */ +int +getopt_long(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE)); +} + +/* + * getopt_long_only -- + * Parse argc/argv argument vector. + */ +int +getopt_long_only(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE|FLAG_LONGONLY)); +} +#endif + +#endif /* !defined(HAVE_GETOPT) || !defined(HAVE_OPTRESET) */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/getrrsetbyname-ldns.c b/crypto/external/bsd/openssh/dist/openbsd-compat/getrrsetbyname-ldns.c new file mode 100644 index 000000000..4647b623b --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/getrrsetbyname-ldns.c @@ -0,0 +1,284 @@ +/* $OpenBSD: getrrsetbyname.c,v 1.10 2005/03/30 02:58:28 tedu Exp $ */ + +/* + * Copyright (c) 2007 Simon Vallet / Genoscope + * + * 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. + */ + +/* + * Portions Copyright (c) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#if !defined (HAVE_GETRRSETBYNAME) && defined (HAVE_LDNS) + +#include +#include + +#include + +#include "getrrsetbyname.h" +#include "log.h" +#include "xmalloc.h" + +#define malloc(x) (xmalloc(x)) +#define calloc(x, y) (xcalloc((x),(y))) + +int +getrrsetbyname(const char *hostname, unsigned int rdclass, + unsigned int rdtype, unsigned int flags, + struct rrsetinfo **res) +{ + int result; + unsigned int i, j, index_ans, index_sig; + struct rrsetinfo *rrset = NULL; + struct rdatainfo *rdata; + size_t len; + ldns_resolver *ldns_res = NULL; + ldns_rdf *domain = NULL; + ldns_pkt *pkt = NULL; + ldns_rr_list *rrsigs = NULL, *rrdata = NULL; + ldns_status err; + ldns_rr *rr; + + /* check for invalid class and type */ + if (rdclass > 0xffff || rdtype > 0xffff) { + result = ERRSET_INVAL; + goto fail; + } + + /* don't allow queries of class or type ANY */ + if (rdclass == 0xff || rdtype == 0xff) { + result = ERRSET_INVAL; + goto fail; + } + + /* don't allow flags yet, unimplemented */ + if (flags) { + result = ERRSET_INVAL; + goto fail; + } + + /* Initialize resolver from resolv.conf */ + domain = ldns_dname_new_frm_str(hostname); + if ((err = ldns_resolver_new_frm_file(&ldns_res, NULL)) != \ + LDNS_STATUS_OK) { + result = ERRSET_FAIL; + goto fail; + } + +#ifdef LDNS_DEBUG + ldns_resolver_set_debug(ldns_res, true); +#endif /* LDNS_DEBUG */ + + ldns_resolver_set_dnssec(ldns_res, true); /* Use DNSSEC */ + + /* make query */ + pkt = ldns_resolver_query(ldns_res, domain, rdtype, rdclass, LDNS_RD); + + /*** TODO: finer errcodes -- see original **/ + if (!pkt || ldns_pkt_ancount(pkt) < 1) { + result = ERRSET_FAIL; + goto fail; + } + + /* initialize rrset */ + rrset = calloc(1, sizeof(struct rrsetinfo)); + if (rrset == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + + rrdata = ldns_pkt_rr_list_by_type(pkt, rdtype, LDNS_SECTION_ANSWER); + rrset->rri_nrdatas = ldns_rr_list_rr_count(rrdata); + if (!rrset->rri_nrdatas) { + result = ERRSET_NODATA; + goto fail; + } + + /* copy name from answer section */ + len = ldns_rdf_size(ldns_rr_owner(ldns_rr_list_rr(rrdata, 0))); + if ((rrset->rri_name = malloc(len)) == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + memcpy(rrset->rri_name, + ldns_rdf_data(ldns_rr_owner(ldns_rr_list_rr(rrdata, 0))), len); + + rrset->rri_rdclass = ldns_rr_get_class(ldns_rr_list_rr(rrdata, 0)); + rrset->rri_rdtype = ldns_rr_get_type(ldns_rr_list_rr(rrdata, 0)); + rrset->rri_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrdata, 0)); + + debug2("ldns: got %u answers from DNS", rrset->rri_nrdatas); + + /* Check for authenticated data */ + if (ldns_pkt_ad(pkt)) { + rrset->rri_flags |= RRSET_VALIDATED; + } else { /* AD is not set, try autonomous validation */ + ldns_rr_list * trusted_keys = ldns_rr_list_new(); + + debug2("ldns: trying to validate RRset"); + /* Get eventual sigs */ + rrsigs = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_RRSIG, + LDNS_SECTION_ANSWER); + + rrset->rri_nsigs = ldns_rr_list_rr_count(rrsigs); + debug2("ldns: got %u signature(s) (RRTYPE %u) from DNS", + rrset->rri_nsigs, LDNS_RR_TYPE_RRSIG); + + if ((err = ldns_verify_trusted(ldns_res, rrdata, rrsigs, + trusted_keys)) == LDNS_STATUS_OK) { + rrset->rri_flags |= RRSET_VALIDATED; + debug2("ldns: RRset is signed with a valid key"); + } else { + debug2("ldns: RRset validation failed: %s", + ldns_get_errorstr_by_id(err)); + } + + ldns_rr_list_deep_free(trusted_keys); + } + + /* allocate memory for answers */ + rrset->rri_rdatas = calloc(rrset->rri_nrdatas, + sizeof(struct rdatainfo)); + + if (rrset->rri_rdatas == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + + /* allocate memory for signatures */ + if (rrset->rri_nsigs > 0) { + rrset->rri_sigs = calloc(rrset->rri_nsigs, + sizeof(struct rdatainfo)); + + if (rrset->rri_sigs == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + } + + /* copy answers & signatures */ + for (i=0, index_ans=0, index_sig=0; i< pkt->_header->_ancount; i++) { + rdata = NULL; + rr = ldns_rr_list_rr(ldns_pkt_answer(pkt), i); + + if (ldns_rr_get_class(rr) == rrset->rri_rdclass && + ldns_rr_get_type(rr) == rrset->rri_rdtype) { + rdata = &rrset->rri_rdatas[index_ans++]; + } + + if (rr->_rr_class == rrset->rri_rdclass && + rr->_rr_type == LDNS_RR_TYPE_RRSIG && + rrset->rri_sigs) { + rdata = &rrset->rri_sigs[index_sig++]; + } + + if (rdata) { + size_t rdata_offset = 0; + + rdata->rdi_length = 0; + for (j=0; j< rr->_rd_count; j++) { + rdata->rdi_length += + ldns_rdf_size(ldns_rr_rdf(rr, j)); + } + + rdata->rdi_data = malloc(rdata->rdi_length); + if (rdata->rdi_data == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + + /* Re-create the raw DNS RDATA */ + for (j=0; j< rr->_rd_count; j++) { + len = ldns_rdf_size(ldns_rr_rdf(rr, j)); + memcpy(rdata->rdi_data + rdata_offset, + ldns_rdf_data(ldns_rr_rdf(rr, j)), len); + rdata_offset += len; + } + } + } + + *res = rrset; + result = ERRSET_SUCCESS; + +fail: + /* freerrset(rrset); */ + ldns_rdf_deep_free(domain); + ldns_pkt_free(pkt); + ldns_rr_list_deep_free(rrsigs); + ldns_rr_list_deep_free(rrdata); + ldns_resolver_deep_free(ldns_res); + + return result; +} + + +void +freerrset(struct rrsetinfo *rrset) +{ + u_int16_t i; + + if (rrset == NULL) + return; + + if (rrset->rri_rdatas) { + for (i = 0; i < rrset->rri_nrdatas; i++) { + if (rrset->rri_rdatas[i].rdi_data == NULL) + break; + free(rrset->rri_rdatas[i].rdi_data); + } + free(rrset->rri_rdatas); + } + + if (rrset->rri_sigs) { + for (i = 0; i < rrset->rri_nsigs; i++) { + if (rrset->rri_sigs[i].rdi_data == NULL) + break; + free(rrset->rri_sigs[i].rdi_data); + } + free(rrset->rri_sigs); + } + + if (rrset->rri_name) + free(rrset->rri_name); + free(rrset); +} + + +#endif /* !defined (HAVE_GETRRSETBYNAME) && defined (HAVE_LDNS) */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/getrrsetbyname.c b/crypto/external/bsd/openssh/dist/openbsd-compat/getrrsetbyname.c new file mode 100644 index 000000000..dc6fe0533 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/getrrsetbyname.c @@ -0,0 +1,610 @@ +/* $OpenBSD: getrrsetbyname.c,v 1.11 2007/10/11 18:36:41 jakob Exp $ */ + +/* + * Copyright (c) 2001 Jakob Schlyter. 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. + */ + +/* + * Portions Copyright (c) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/net/getrrsetbyname.c */ + +#include "includes.h" + +#if !defined (HAVE_GETRRSETBYNAME) && !defined (HAVE_LDNS) + +#include +#include + +#include +#include + +#include "getrrsetbyname.h" + +#if defined(HAVE_DECL_H_ERRNO) && !HAVE_DECL_H_ERRNO +extern int h_errno; +#endif + +/* We don't need multithread support here */ +#ifdef _THREAD_PRIVATE +# undef _THREAD_PRIVATE +#endif +#define _THREAD_PRIVATE(a,b,c) (c) + +#ifndef HAVE__RES_EXTERN +struct __res_state _res; +#endif + +/* Necessary functions and macros */ + +/* + * Inline versions of get/put short/long. Pointer is advanced. + * + * These macros demonstrate the property of C whereby it can be + * portable or it can be elegant but rarely both. + */ + +#ifndef INT32SZ +# define INT32SZ 4 +#endif +#ifndef INT16SZ +# define INT16SZ 2 +#endif + +#ifndef GETSHORT +#define GETSHORT(s, cp) { \ + register u_char *t_cp = (u_char *)(cp); \ + (s) = ((u_int16_t)t_cp[0] << 8) \ + | ((u_int16_t)t_cp[1]) \ + ; \ + (cp) += INT16SZ; \ +} +#endif + +#ifndef GETLONG +#define GETLONG(l, cp) { \ + register u_char *t_cp = (u_char *)(cp); \ + (l) = ((u_int32_t)t_cp[0] << 24) \ + | ((u_int32_t)t_cp[1] << 16) \ + | ((u_int32_t)t_cp[2] << 8) \ + | ((u_int32_t)t_cp[3]) \ + ; \ + (cp) += INT32SZ; \ +} +#endif + +/* + * Routines to insert/extract short/long's. + */ + +#ifndef HAVE__GETSHORT +static u_int16_t +_getshort(msgp) + register const u_char *msgp; +{ + register u_int16_t u; + + GETSHORT(u, msgp); + return (u); +} +#elif defined(HAVE_DECL__GETSHORT) && (HAVE_DECL__GETSHORT == 0) +u_int16_t _getshort(register const u_char *); +#endif + +#ifndef HAVE__GETLONG +static u_int32_t +_getlong(msgp) + register const u_char *msgp; +{ + register u_int32_t u; + + GETLONG(u, msgp); + return (u); +} +#elif defined(HAVE_DECL__GETLONG) && (HAVE_DECL__GETLONG == 0) +u_int32_t _getlong(register const u_char *); +#endif + +/* ************** */ + +#define ANSWER_BUFFER_SIZE 0xffff + +struct dns_query { + char *name; + u_int16_t type; + u_int16_t class; + struct dns_query *next; +}; + +struct dns_rr { + char *name; + u_int16_t type; + u_int16_t class; + u_int16_t ttl; + u_int16_t size; + void *rdata; + struct dns_rr *next; +}; + +struct dns_response { + HEADER header; + struct dns_query *query; + struct dns_rr *answer; + struct dns_rr *authority; + struct dns_rr *additional; +}; + +static struct dns_response *parse_dns_response(const u_char *, int); +static struct dns_query *parse_dns_qsection(const u_char *, int, + const u_char **, int); +static struct dns_rr *parse_dns_rrsection(const u_char *, int, const u_char **, + int); + +static void free_dns_query(struct dns_query *); +static void free_dns_rr(struct dns_rr *); +static void free_dns_response(struct dns_response *); + +static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t); + +int +getrrsetbyname(const char *hostname, unsigned int rdclass, + unsigned int rdtype, unsigned int flags, + struct rrsetinfo **res) +{ + struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res); + int result; + struct rrsetinfo *rrset = NULL; + struct dns_response *response = NULL; + struct dns_rr *rr; + struct rdatainfo *rdata; + int length; + unsigned int index_ans, index_sig; + u_char answer[ANSWER_BUFFER_SIZE]; + + /* check for invalid class and type */ + if (rdclass > 0xffff || rdtype > 0xffff) { + result = ERRSET_INVAL; + goto fail; + } + + /* don't allow queries of class or type ANY */ + if (rdclass == 0xff || rdtype == 0xff) { + result = ERRSET_INVAL; + goto fail; + } + + /* don't allow flags yet, unimplemented */ + if (flags) { + result = ERRSET_INVAL; + goto fail; + } + + /* initialize resolver */ + if ((_resp->options & RES_INIT) == 0 && res_init() == -1) { + result = ERRSET_FAIL; + goto fail; + } + +#ifdef DEBUG + _resp->options |= RES_DEBUG; +#endif /* DEBUG */ + +#ifdef RES_USE_DNSSEC + /* turn on DNSSEC if EDNS0 is configured */ + if (_resp->options & RES_USE_EDNS0) + _resp->options |= RES_USE_DNSSEC; +#endif /* RES_USE_DNSEC */ + + /* make query */ + length = res_query(hostname, (signed int) rdclass, (signed int) rdtype, + answer, sizeof(answer)); + if (length < 0) { + switch(h_errno) { + case HOST_NOT_FOUND: + result = ERRSET_NONAME; + goto fail; + case NO_DATA: + result = ERRSET_NODATA; + goto fail; + default: + result = ERRSET_FAIL; + goto fail; + } + } + + /* parse result */ + response = parse_dns_response(answer, length); + if (response == NULL) { + result = ERRSET_FAIL; + goto fail; + } + + if (response->header.qdcount != 1) { + result = ERRSET_FAIL; + goto fail; + } + + /* initialize rrset */ + rrset = calloc(1, sizeof(struct rrsetinfo)); + if (rrset == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + rrset->rri_rdclass = response->query->class; + rrset->rri_rdtype = response->query->type; + rrset->rri_ttl = response->answer->ttl; + rrset->rri_nrdatas = response->header.ancount; + +#ifdef HAVE_HEADER_AD + /* check for authenticated data */ + if (response->header.ad == 1) + rrset->rri_flags |= RRSET_VALIDATED; +#endif + + /* copy name from answer section */ + rrset->rri_name = strdup(response->answer->name); + if (rrset->rri_name == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + + /* count answers */ + rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass, + rrset->rri_rdtype); + rrset->rri_nsigs = count_dns_rr(response->answer, rrset->rri_rdclass, + T_RRSIG); + + /* allocate memory for answers */ + rrset->rri_rdatas = calloc(rrset->rri_nrdatas, + sizeof(struct rdatainfo)); + if (rrset->rri_rdatas == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + + /* allocate memory for signatures */ + if (rrset->rri_nsigs > 0) { + rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo)); + if (rrset->rri_sigs == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + } + + /* copy answers & signatures */ + for (rr = response->answer, index_ans = 0, index_sig = 0; + rr; rr = rr->next) { + + rdata = NULL; + + if (rr->class == rrset->rri_rdclass && + rr->type == rrset->rri_rdtype) + rdata = &rrset->rri_rdatas[index_ans++]; + + if (rr->class == rrset->rri_rdclass && + rr->type == T_RRSIG) + rdata = &rrset->rri_sigs[index_sig++]; + + if (rdata) { + rdata->rdi_length = rr->size; + rdata->rdi_data = malloc(rr->size); + + if (rdata->rdi_data == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + memcpy(rdata->rdi_data, rr->rdata, rr->size); + } + } + free_dns_response(response); + + *res = rrset; + return (ERRSET_SUCCESS); + +fail: + if (rrset != NULL) + freerrset(rrset); + if (response != NULL) + free_dns_response(response); + return (result); +} + +void +freerrset(struct rrsetinfo *rrset) +{ + u_int16_t i; + + if (rrset == NULL) + return; + + if (rrset->rri_rdatas) { + for (i = 0; i < rrset->rri_nrdatas; i++) { + if (rrset->rri_rdatas[i].rdi_data == NULL) + break; + free(rrset->rri_rdatas[i].rdi_data); + } + free(rrset->rri_rdatas); + } + + if (rrset->rri_sigs) { + for (i = 0; i < rrset->rri_nsigs; i++) { + if (rrset->rri_sigs[i].rdi_data == NULL) + break; + free(rrset->rri_sigs[i].rdi_data); + } + free(rrset->rri_sigs); + } + + if (rrset->rri_name) + free(rrset->rri_name); + free(rrset); +} + +/* + * DNS response parsing routines + */ +static struct dns_response * +parse_dns_response(const u_char *answer, int size) +{ + struct dns_response *resp; + const u_char *cp; + + /* allocate memory for the response */ + resp = calloc(1, sizeof(*resp)); + if (resp == NULL) + return (NULL); + + /* initialize current pointer */ + cp = answer; + + /* copy header */ + memcpy(&resp->header, cp, HFIXEDSZ); + cp += HFIXEDSZ; + + /* fix header byte order */ + resp->header.qdcount = ntohs(resp->header.qdcount); + resp->header.ancount = ntohs(resp->header.ancount); + resp->header.nscount = ntohs(resp->header.nscount); + resp->header.arcount = ntohs(resp->header.arcount); + + /* there must be at least one query */ + if (resp->header.qdcount < 1) { + free_dns_response(resp); + return (NULL); + } + + /* parse query section */ + resp->query = parse_dns_qsection(answer, size, &cp, + resp->header.qdcount); + if (resp->header.qdcount && resp->query == NULL) { + free_dns_response(resp); + return (NULL); + } + + /* parse answer section */ + resp->answer = parse_dns_rrsection(answer, size, &cp, + resp->header.ancount); + if (resp->header.ancount && resp->answer == NULL) { + free_dns_response(resp); + return (NULL); + } + + /* parse authority section */ + resp->authority = parse_dns_rrsection(answer, size, &cp, + resp->header.nscount); + if (resp->header.nscount && resp->authority == NULL) { + free_dns_response(resp); + return (NULL); + } + + /* parse additional section */ + resp->additional = parse_dns_rrsection(answer, size, &cp, + resp->header.arcount); + if (resp->header.arcount && resp->additional == NULL) { + free_dns_response(resp); + return (NULL); + } + + return (resp); +} + +static struct dns_query * +parse_dns_qsection(const u_char *answer, int size, const u_char **cp, int count) +{ + struct dns_query *head, *curr, *prev; + int i, length; + char name[MAXDNAME]; + + for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) { + + /* allocate and initialize struct */ + curr = calloc(1, sizeof(struct dns_query)); + if (curr == NULL) { + free_dns_query(head); + return (NULL); + } + if (head == NULL) + head = curr; + if (prev != NULL) + prev->next = curr; + + /* name */ + length = dn_expand(answer, answer + size, *cp, name, + sizeof(name)); + if (length < 0) { + free_dns_query(head); + return (NULL); + } + curr->name = strdup(name); + if (curr->name == NULL) { + free_dns_query(head); + return (NULL); + } + *cp += length; + + /* type */ + curr->type = _getshort(*cp); + *cp += INT16SZ; + + /* class */ + curr->class = _getshort(*cp); + *cp += INT16SZ; + } + + return (head); +} + +static struct dns_rr * +parse_dns_rrsection(const u_char *answer, int size, const u_char **cp, + int count) +{ + struct dns_rr *head, *curr, *prev; + int i, length; + char name[MAXDNAME]; + + for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) { + + /* allocate and initialize struct */ + curr = calloc(1, sizeof(struct dns_rr)); + if (curr == NULL) { + free_dns_rr(head); + return (NULL); + } + if (head == NULL) + head = curr; + if (prev != NULL) + prev->next = curr; + + /* name */ + length = dn_expand(answer, answer + size, *cp, name, + sizeof(name)); + if (length < 0) { + free_dns_rr(head); + return (NULL); + } + curr->name = strdup(name); + if (curr->name == NULL) { + free_dns_rr(head); + return (NULL); + } + *cp += length; + + /* type */ + curr->type = _getshort(*cp); + *cp += INT16SZ; + + /* class */ + curr->class = _getshort(*cp); + *cp += INT16SZ; + + /* ttl */ + curr->ttl = _getlong(*cp); + *cp += INT32SZ; + + /* rdata size */ + curr->size = _getshort(*cp); + *cp += INT16SZ; + + /* rdata itself */ + curr->rdata = malloc(curr->size); + if (curr->rdata == NULL) { + free_dns_rr(head); + return (NULL); + } + memcpy(curr->rdata, *cp, curr->size); + *cp += curr->size; + } + + return (head); +} + +static void +free_dns_query(struct dns_query *p) +{ + if (p == NULL) + return; + + if (p->name) + free(p->name); + free_dns_query(p->next); + free(p); +} + +static void +free_dns_rr(struct dns_rr *p) +{ + if (p == NULL) + return; + + if (p->name) + free(p->name); + if (p->rdata) + free(p->rdata); + free_dns_rr(p->next); + free(p); +} + +static void +free_dns_response(struct dns_response *p) +{ + if (p == NULL) + return; + + free_dns_query(p->query); + free_dns_rr(p->answer); + free_dns_rr(p->authority); + free_dns_rr(p->additional); + free(p); +} + +static int +count_dns_rr(struct dns_rr *p, u_int16_t class, u_int16_t type) +{ + int n = 0; + + while(p) { + if (p->class == class && p->type == type) + n++; + p = p->next; + } + + return (n); +} + +#endif /* !defined (HAVE_GETRRSETBYNAME) && !defined (HAVE_LDNS) */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/getrrsetbyname.h b/crypto/external/bsd/openssh/dist/openbsd-compat/getrrsetbyname.h new file mode 100644 index 000000000..1283f5506 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/getrrsetbyname.h @@ -0,0 +1,110 @@ +/* OPENBSD BASED ON : include/netdb.h */ + +/* $OpenBSD: getrrsetbyname.c,v 1.4 2001/08/16 18:16:43 ho Exp $ */ + +/* + * Copyright (c) 2001 Jakob Schlyter. 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. + */ + +/* + * Portions Copyright (c) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _GETRRSETBYNAME_H +#define _GETRRSETBYNAME_H + +#include "includes.h" + +#ifndef HAVE_GETRRSETBYNAME + +#include +#include +#include +#include +#include + +#ifndef HFIXEDSZ +#define HFIXEDSZ 12 +#endif + +#ifndef T_RRSIG +#define T_RRSIG 46 +#endif + +/* + * Flags for getrrsetbyname() + */ +#ifndef RRSET_VALIDATED +# define RRSET_VALIDATED 1 +#endif + +/* + * Return codes for getrrsetbyname() + */ +#ifndef ERRSET_SUCCESS +# define ERRSET_SUCCESS 0 +# define ERRSET_NOMEMORY 1 +# define ERRSET_FAIL 2 +# define ERRSET_INVAL 3 +# define ERRSET_NONAME 4 +# define ERRSET_NODATA 5 +#endif + +struct rdatainfo { + unsigned int rdi_length; /* length of data */ + unsigned char *rdi_data; /* record data */ +}; + +struct rrsetinfo { + unsigned int rri_flags; /* RRSET_VALIDATED ... */ + unsigned int rri_rdclass; /* class number */ + unsigned int rri_rdtype; /* RR type number */ + unsigned int rri_ttl; /* time to live */ + unsigned int rri_nrdatas; /* size of rdatas array */ + unsigned int rri_nsigs; /* size of sigs array */ + char *rri_name; /* canonical name */ + struct rdatainfo *rri_rdatas; /* individual records */ + struct rdatainfo *rri_sigs; /* individual signatures */ +}; + +int getrrsetbyname(const char *, unsigned int, unsigned int, unsigned int, struct rrsetinfo **); +void freerrset(struct rrsetinfo *); + +#endif /* !defined(HAVE_GETRRSETBYNAME) */ + +#endif /* _GETRRSETBYNAME_H */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/glob.c b/crypto/external/bsd/openssh/dist/openbsd-compat/glob.c new file mode 100644 index 000000000..742b4b954 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/glob.c @@ -0,0 +1,1065 @@ +/* $OpenBSD: glob.c,v 1.38 2011/09/22 06:27:29 djm Exp $ */ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * 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. 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. + */ + +/* OPENBSD ORIGINAL: lib/libc/gen/glob.c */ + +/* + * glob(3) -- a superset of the one defined in POSIX 1003.2. + * + * The [!...] convention to negate a range is supported (SysV, Posix, ksh). + * + * Optional extra services, controlled by flags not defined by POSIX: + * + * GLOB_QUOTE: + * Escaping convention: \ inhibits any special meaning the following + * character might have (except \ at end of string is retained). + * GLOB_MAGCHAR: + * Set in gl_flags if pattern contained a globbing character. + * GLOB_NOMAGIC: + * Same as GLOB_NOCHECK, but it will only append pattern if it did + * not contain any magic characters. [Used in csh style globbing] + * GLOB_ALTDIRFUNC: + * Use alternately specified directory access functions. + * GLOB_TILDE: + * expand ~user/foo to the /home/dir/of/user/foo + * GLOB_BRACE: + * expand {1,2}{a,b} to 1a 1b 2a 2b + * gl_matchc: + * Number of matches in the current invocation of glob. + */ + +#include "includes.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) || \ + !defined(GLOB_HAS_GL_MATCHC) || !defined(GLOB_HAS_GL_STATV) || \ + !defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \ + defined(BROKEN_GLOB) + +#include "charclass.h" + +#define DOLLAR '$' +#define DOT '.' +#define EOS '\0' +#define LBRACKET '[' +#define NOT '!' +#define QUESTION '?' +#define QUOTE '\\' +#define RANGE '-' +#define RBRACKET ']' +#define SEP '/' +#define STAR '*' +#define TILDE '~' +#define UNDERSCORE '_' +#define LBRACE '{' +#define RBRACE '}' +#define SLASH '/' +#define COMMA ',' + +#ifndef DEBUG + +#define M_QUOTE 0x8000 +#define M_PROTECT 0x4000 +#define M_MASK 0xffff +#define M_ASCII 0x00ff + +typedef u_short Char; + +#else + +#define M_QUOTE 0x80 +#define M_PROTECT 0x40 +#define M_MASK 0xff +#define M_ASCII 0x7f + +typedef char Char; + +#endif + + +#define CHAR(c) ((Char)((c)&M_ASCII)) +#define META(c) ((Char)((c)|M_QUOTE)) +#define M_ALL META('*') +#define M_END META(']') +#define M_NOT META('!') +#define M_ONE META('?') +#define M_RNG META('-') +#define M_SET META('[') +#define M_CLASS META(':') +#define ismeta(c) (((c)&M_QUOTE) != 0) + +#define GLOB_LIMIT_MALLOC 65536 +#define GLOB_LIMIT_STAT 128 +#define GLOB_LIMIT_READDIR 16384 + +/* Limit of recursion during matching attempts. */ +#define GLOB_LIMIT_RECUR 64 + +struct glob_lim { + size_t glim_malloc; + size_t glim_stat; + size_t glim_readdir; +}; + +struct glob_path_stat { + char *gps_path; + struct stat *gps_stat; +}; + +static int compare(const void *, const void *); +static int compare_gps(const void *, const void *); +static int g_Ctoc(const Char *, char *, u_int); +static int g_lstat(Char *, struct stat *, glob_t *); +static DIR *g_opendir(Char *, glob_t *); +static Char *g_strchr(const Char *, int); +static int g_strncmp(const Char *, const char *, size_t); +static int g_stat(Char *, struct stat *, glob_t *); +static int glob0(const Char *, glob_t *, struct glob_lim *); +static int glob1(Char *, Char *, glob_t *, struct glob_lim *); +static int glob2(Char *, Char *, Char *, Char *, Char *, Char *, + glob_t *, struct glob_lim *); +static int glob3(Char *, Char *, Char *, Char *, Char *, + Char *, Char *, glob_t *, struct glob_lim *); +static int globextend(const Char *, glob_t *, struct glob_lim *, + struct stat *); +static const Char * + globtilde(const Char *, Char *, size_t, glob_t *); +static int globexp1(const Char *, glob_t *, struct glob_lim *); +static int globexp2(const Char *, const Char *, glob_t *, + struct glob_lim *); +static int match(Char *, Char *, Char *, int); +#ifdef DEBUG +static void qprintf(const char *, Char *); +#endif + +int +glob(const char *pattern, int flags, int (*errfunc)(const char *, int), + glob_t *pglob) +{ + const u_char *patnext; + int c; + Char *bufnext, *bufend, patbuf[MAXPATHLEN]; + struct glob_lim limit = { 0, 0, 0 }; + + if (strnlen(pattern, PATH_MAX) == PATH_MAX) + return(GLOB_NOMATCH); + + patnext = (u_char *) pattern; + if (!(flags & GLOB_APPEND)) { + pglob->gl_pathc = 0; + pglob->gl_pathv = NULL; + pglob->gl_statv = NULL; + if (!(flags & GLOB_DOOFFS)) + pglob->gl_offs = 0; + } + pglob->gl_flags = flags & ~GLOB_MAGCHAR; + pglob->gl_errfunc = errfunc; + pglob->gl_matchc = 0; + + if (pglob->gl_offs < 0 || pglob->gl_pathc < 0 || + pglob->gl_offs >= INT_MAX || pglob->gl_pathc >= INT_MAX || + pglob->gl_pathc >= INT_MAX - pglob->gl_offs - 1) + return GLOB_NOSPACE; + + bufnext = patbuf; + bufend = bufnext + MAXPATHLEN - 1; + if (flags & GLOB_NOESCAPE) + while (bufnext < bufend && (c = *patnext++) != EOS) + *bufnext++ = c; + else { + /* Protect the quoted characters. */ + while (bufnext < bufend && (c = *patnext++) != EOS) + if (c == QUOTE) { + if ((c = *patnext++) == EOS) { + c = QUOTE; + --patnext; + } + *bufnext++ = c | M_PROTECT; + } else + *bufnext++ = c; + } + *bufnext = EOS; + + if (flags & GLOB_BRACE) + return globexp1(patbuf, pglob, &limit); + else + return glob0(patbuf, pglob, &limit); +} + +/* + * Expand recursively a glob {} pattern. When there is no more expansion + * invoke the standard globbing routine to glob the rest of the magic + * characters + */ +static int +globexp1(const Char *pattern, glob_t *pglob, struct glob_lim *limitp) +{ + const Char* ptr = pattern; + + /* Protect a single {}, for find(1), like csh */ + if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) + return glob0(pattern, pglob, limitp); + + if ((ptr = (const Char *) g_strchr(ptr, LBRACE)) != NULL) + return globexp2(ptr, pattern, pglob, limitp); + + return glob0(pattern, pglob, limitp); +} + + +/* + * Recursive brace globbing helper. Tries to expand a single brace. + * If it succeeds then it invokes globexp1 with the new pattern. + * If it fails then it tries to glob the rest of the pattern and returns. + */ +static int +globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, + struct glob_lim *limitp) +{ + int i, rv; + Char *lm, *ls; + const Char *pe, *pm, *pl; + Char patbuf[MAXPATHLEN]; + + /* copy part up to the brace */ + for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) + ; + *lm = EOS; + ls = lm; + + /* Find the balanced brace */ + for (i = 0, pe = ++ptr; *pe; pe++) + if (*pe == LBRACKET) { + /* Ignore everything between [] */ + for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++) + ; + if (*pe == EOS) { + /* + * We could not find a matching RBRACKET. + * Ignore and just look for RBRACE + */ + pe = pm; + } + } else if (*pe == LBRACE) + i++; + else if (*pe == RBRACE) { + if (i == 0) + break; + i--; + } + + /* Non matching braces; just glob the pattern */ + if (i != 0 || *pe == EOS) + return glob0(patbuf, pglob, limitp); + + for (i = 0, pl = pm = ptr; pm <= pe; pm++) { + switch (*pm) { + case LBRACKET: + /* Ignore everything between [] */ + for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++) + ; + if (*pm == EOS) { + /* + * We could not find a matching RBRACKET. + * Ignore and just look for RBRACE + */ + pm = pl; + } + break; + + case LBRACE: + i++; + break; + + case RBRACE: + if (i) { + i--; + break; + } + /* FALLTHROUGH */ + case COMMA: + if (i && *pm == COMMA) + break; + else { + /* Append the current string */ + for (lm = ls; (pl < pm); *lm++ = *pl++) + ; + + /* + * Append the rest of the pattern after the + * closing brace + */ + for (pl = pe + 1; (*lm++ = *pl++) != EOS; ) + ; + + /* Expand the current pattern */ +#ifdef DEBUG + qprintf("globexp2:", patbuf); +#endif + rv = globexp1(patbuf, pglob, limitp); + if (rv && rv != GLOB_NOMATCH) + return rv; + + /* move after the comma, to the next string */ + pl = pm + 1; + } + break; + + default: + break; + } + } + return 0; +} + + + +/* + * expand tilde from the passwd file. + */ +static const Char * +globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob) +{ + struct passwd *pwd; + char *h; + const Char *p; + Char *b, *eb; + + if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) + return pattern; + + /* Copy up to the end of the string or / */ + eb = &patbuf[patbuf_len - 1]; + for (p = pattern + 1, h = (char *) patbuf; + h < (char *)eb && *p && *p != SLASH; *h++ = *p++) + ; + + *h = EOS; + +#if 0 + if (h == (char *)eb) + return what; +#endif + + if (((char *) patbuf)[0] == EOS) { + /* + * handle a plain ~ or ~/ by expanding $HOME + * first and then trying the password file + */ +#if 0 + if (issetugid() != 0 || (h = getenv("HOME")) == NULL) { +#endif + if ((getuid() != geteuid()) || (h = getenv("HOME")) == NULL) { + if ((pwd = getpwuid(getuid())) == NULL) + return pattern; + else + h = pwd->pw_dir; + } + } else { + /* + * Expand a ~user + */ + if ((pwd = getpwnam((char*) patbuf)) == NULL) + return pattern; + else + h = pwd->pw_dir; + } + + /* Copy the home directory */ + for (b = patbuf; b < eb && *h; *b++ = *h++) + ; + + /* Append the rest of the pattern */ + while (b < eb && (*b++ = *p++) != EOS) + ; + *b = EOS; + + return patbuf; +} + +static int +g_strncmp(const Char *s1, const char *s2, size_t n) +{ + int rv = 0; + + while (n--) { + rv = *(Char *)s1 - *(const unsigned char *)s2++; + if (rv) + break; + if (*s1++ == '\0') + break; + } + return rv; +} + +static int +g_charclass(const Char **patternp, Char **bufnextp) +{ + const Char *pattern = *patternp + 1; + Char *bufnext = *bufnextp; + const Char *colon; + struct cclass *cc; + size_t len; + + if ((colon = g_strchr(pattern, ':')) == NULL || colon[1] != ']') + return 1; /* not a character class */ + + len = (size_t)(colon - pattern); + for (cc = cclasses; cc->name != NULL; cc++) { + if (!g_strncmp(pattern, cc->name, len) && cc->name[len] == '\0') + break; + } + if (cc->name == NULL) + return -1; /* invalid character class */ + *bufnext++ = M_CLASS; + *bufnext++ = (Char)(cc - &cclasses[0]); + *bufnextp = bufnext; + *patternp += len + 3; + + return 0; +} + +/* + * The main glob() routine: compiles the pattern (optionally processing + * quotes), calls glob1() to do the real pattern matching, and finally + * sorts the list (unless unsorted operation is requested). Returns 0 + * if things went well, nonzero if errors occurred. It is not an error + * to find no matches. + */ +static int +glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp) +{ + const Char *qpatnext; + int c, err, oldpathc; + Char *bufnext, patbuf[MAXPATHLEN]; + + qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob); + oldpathc = pglob->gl_pathc; + bufnext = patbuf; + + /* We don't need to check for buffer overflow any more. */ + while ((c = *qpatnext++) != EOS) { + switch (c) { + case LBRACKET: + c = *qpatnext; + if (c == NOT) + ++qpatnext; + if (*qpatnext == EOS || + g_strchr(qpatnext+1, RBRACKET) == NULL) { + *bufnext++ = LBRACKET; + if (c == NOT) + --qpatnext; + break; + } + *bufnext++ = M_SET; + if (c == NOT) + *bufnext++ = M_NOT; + c = *qpatnext++; + do { + if (c == LBRACKET && *qpatnext == ':') { + do { + err = g_charclass(&qpatnext, + &bufnext); + if (err) + break; + c = *qpatnext++; + } while (c == LBRACKET && *qpatnext == ':'); + if (err == -1 && + !(pglob->gl_flags & GLOB_NOCHECK)) + return GLOB_NOMATCH; + if (c == RBRACKET) + break; + } + *bufnext++ = CHAR(c); + if (*qpatnext == RANGE && + (c = qpatnext[1]) != RBRACKET) { + *bufnext++ = M_RNG; + *bufnext++ = CHAR(c); + qpatnext += 2; + } + } while ((c = *qpatnext++) != RBRACKET); + pglob->gl_flags |= GLOB_MAGCHAR; + *bufnext++ = M_END; + break; + case QUESTION: + pglob->gl_flags |= GLOB_MAGCHAR; + *bufnext++ = M_ONE; + break; + case STAR: + pglob->gl_flags |= GLOB_MAGCHAR; + /* collapse adjacent stars to one, + * to avoid exponential behavior + */ + if (bufnext == patbuf || bufnext[-1] != M_ALL) + *bufnext++ = M_ALL; + break; + default: + *bufnext++ = CHAR(c); + break; + } + } + *bufnext = EOS; +#ifdef DEBUG + qprintf("glob0:", patbuf); +#endif + + if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, limitp)) != 0) + return(err); + + /* + * If there was no match we are going to append the pattern + * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified + * and the pattern did not contain any magic characters + * GLOB_NOMAGIC is there just for compatibility with csh. + */ + if (pglob->gl_pathc == oldpathc) { + if ((pglob->gl_flags & GLOB_NOCHECK) || + ((pglob->gl_flags & GLOB_NOMAGIC) && + !(pglob->gl_flags & GLOB_MAGCHAR))) + return(globextend(pattern, pglob, limitp, NULL)); + else + return(GLOB_NOMATCH); + } + if (!(pglob->gl_flags & GLOB_NOSORT)) { + if ((pglob->gl_flags & GLOB_KEEPSTAT)) { + /* Keep the paths and stat info synced during sort */ + struct glob_path_stat *path_stat; + int i; + int n = pglob->gl_pathc - oldpathc; + int o = pglob->gl_offs + oldpathc; + + if ((path_stat = calloc(n, sizeof(*path_stat))) == NULL) + return GLOB_NOSPACE; + for (i = 0; i < n; i++) { + path_stat[i].gps_path = pglob->gl_pathv[o + i]; + path_stat[i].gps_stat = pglob->gl_statv[o + i]; + } + qsort(path_stat, n, sizeof(*path_stat), compare_gps); + for (i = 0; i < n; i++) { + pglob->gl_pathv[o + i] = path_stat[i].gps_path; + pglob->gl_statv[o + i] = path_stat[i].gps_stat; + } + free(path_stat); + } else { + qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, + pglob->gl_pathc - oldpathc, sizeof(char *), + compare); + } + } + return(0); +} + +static int +compare(const void *p, const void *q) +{ + return(strcmp(*(char **)p, *(char **)q)); +} + +static int +compare_gps(const void *_p, const void *_q) +{ + const struct glob_path_stat *p = (const struct glob_path_stat *)_p; + const struct glob_path_stat *q = (const struct glob_path_stat *)_q; + + return(strcmp(p->gps_path, q->gps_path)); +} + +static int +glob1(Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp) +{ + Char pathbuf[MAXPATHLEN]; + + /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ + if (*pattern == EOS) + return(0); + return(glob2(pathbuf, pathbuf+MAXPATHLEN-1, + pathbuf, pathbuf+MAXPATHLEN-1, + pattern, pattern_last, pglob, limitp)); +} + +/* + * The functions glob2 and glob3 are mutually recursive; there is one level + * of recursion for each segment in the pattern that contains one or more + * meta characters. + */ +static int +glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, + Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp) +{ + struct stat sb; + Char *p, *q; + int anymeta; + + /* + * Loop over pattern segments until end of pattern or until + * segment with meta character found. + */ + for (anymeta = 0;;) { + if (*pattern == EOS) { /* End of pattern? */ + *pathend = EOS; + if (g_lstat(pathbuf, &sb, pglob)) + return(0); + + if ((pglob->gl_flags & GLOB_LIMIT) && + limitp->glim_stat++ >= GLOB_LIMIT_STAT) { + errno = 0; + *pathend++ = SEP; + *pathend = EOS; + return(GLOB_NOSPACE); + } + + if (((pglob->gl_flags & GLOB_MARK) && + pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) || + (S_ISLNK(sb.st_mode) && + (g_stat(pathbuf, &sb, pglob) == 0) && + S_ISDIR(sb.st_mode)))) { + if (pathend+1 > pathend_last) + return (1); + *pathend++ = SEP; + *pathend = EOS; + } + ++pglob->gl_matchc; + return(globextend(pathbuf, pglob, limitp, &sb)); + } + + /* Find end of next segment, copy tentatively to pathend. */ + q = pathend; + p = pattern; + while (*p != EOS && *p != SEP) { + if (ismeta(*p)) + anymeta = 1; + if (q+1 > pathend_last) + return (1); + *q++ = *p++; + } + + if (!anymeta) { /* No expansion, do next segment. */ + pathend = q; + pattern = p; + while (*pattern == SEP) { + if (pathend+1 > pathend_last) + return (1); + *pathend++ = *pattern++; + } + } else + /* Need expansion, recurse. */ + return(glob3(pathbuf, pathbuf_last, pathend, + pathend_last, pattern, p, pattern_last, + pglob, limitp)); + } + /* NOTREACHED */ +} + +static int +glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, + Char *pattern, Char *restpattern, Char *restpattern_last, glob_t *pglob, + struct glob_lim *limitp) +{ + struct dirent *dp; + DIR *dirp; + int err; + char buf[MAXPATHLEN]; + + /* + * The readdirfunc declaration can't be prototyped, because it is + * assigned, below, to two functions which are prototyped in glob.h + * and dirent.h as taking pointers to differently typed opaque + * structures. + */ + struct dirent *(*readdirfunc)(void *); + + if (pathend > pathend_last) + return (1); + *pathend = EOS; + errno = 0; + + if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { + /* TODO: don't call for ENOENT or ENOTDIR? */ + if (pglob->gl_errfunc) { + if (g_Ctoc(pathbuf, buf, sizeof(buf))) + return(GLOB_ABORTED); + if (pglob->gl_errfunc(buf, errno) || + pglob->gl_flags & GLOB_ERR) + return(GLOB_ABORTED); + } + return(0); + } + + err = 0; + + /* Search directory for matching names. */ + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + readdirfunc = pglob->gl_readdir; + else + readdirfunc = (struct dirent *(*)(void *))readdir; + while ((dp = (*readdirfunc)(dirp))) { + u_char *sc; + Char *dc; + + if ((pglob->gl_flags & GLOB_LIMIT) && + limitp->glim_readdir++ >= GLOB_LIMIT_READDIR) { + errno = 0; + *pathend++ = SEP; + *pathend = EOS; + err = GLOB_NOSPACE; + break; + } + + /* Initial DOT must be matched literally. */ + if (dp->d_name[0] == DOT && *pattern != DOT) + continue; + dc = pathend; + sc = (u_char *) dp->d_name; + while (dc < pathend_last && (*dc++ = *sc++) != EOS) + ; + if (dc >= pathend_last) { + *dc = EOS; + err = 1; + break; + } + + if (!match(pathend, pattern, restpattern, GLOB_LIMIT_RECUR)) { + *pathend = EOS; + continue; + } + err = glob2(pathbuf, pathbuf_last, --dc, pathend_last, + restpattern, restpattern_last, pglob, limitp); + if (err) + break; + } + + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + (*pglob->gl_closedir)(dirp); + else + closedir(dirp); + return(err); +} + + +/* + * Extend the gl_pathv member of a glob_t structure to accommodate a new item, + * add the new item, and update gl_pathc. + * + * This assumes the BSD realloc, which only copies the block when its size + * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic + * behavior. + * + * Return 0 if new item added, error code if memory couldn't be allocated. + * + * Invariant of the glob_t structure: + * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and + * gl_pathv points to (gl_offs + gl_pathc + 1) items. + */ +static int +globextend(const Char *path, glob_t *pglob, struct glob_lim *limitp, + struct stat *sb) +{ + char **pathv; + ssize_t i; + size_t newn, len; + char *copy = NULL; + const Char *p; + struct stat **statv; + + newn = 2 + pglob->gl_pathc + pglob->gl_offs; + if (pglob->gl_offs >= INT_MAX || + pglob->gl_pathc >= INT_MAX || + newn >= INT_MAX || + SIZE_MAX / sizeof(*pathv) <= newn || + SIZE_MAX / sizeof(*statv) <= newn) { + nospace: + for (i = pglob->gl_offs; i < (ssize_t)(newn - 2); i++) { + if (pglob->gl_pathv && pglob->gl_pathv[i]) + free(pglob->gl_pathv[i]); + if ((pglob->gl_flags & GLOB_KEEPSTAT) != 0 && + pglob->gl_pathv && pglob->gl_pathv[i]) + free(pglob->gl_statv[i]); + } + if (pglob->gl_pathv) { + free(pglob->gl_pathv); + pglob->gl_pathv = NULL; + } + if (pglob->gl_statv) { + free(pglob->gl_statv); + pglob->gl_statv = NULL; + } + return(GLOB_NOSPACE); + } + + pathv = realloc(pglob->gl_pathv, newn * sizeof(*pathv)); + if (pathv == NULL) + goto nospace; + if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { + /* first time around -- clear initial gl_offs items */ + pathv += pglob->gl_offs; + for (i = pglob->gl_offs; --i >= 0; ) + *--pathv = NULL; + } + pglob->gl_pathv = pathv; + + if ((pglob->gl_flags & GLOB_KEEPSTAT) != 0) { + statv = realloc(pglob->gl_statv, newn * sizeof(*statv)); + if (statv == NULL) + goto nospace; + if (pglob->gl_statv == NULL && pglob->gl_offs > 0) { + /* first time around -- clear initial gl_offs items */ + statv += pglob->gl_offs; + for (i = pglob->gl_offs; --i >= 0; ) + *--statv = NULL; + } + pglob->gl_statv = statv; + if (sb == NULL) + statv[pglob->gl_offs + pglob->gl_pathc] = NULL; + else { + limitp->glim_malloc += sizeof(**statv); + if ((pglob->gl_flags & GLOB_LIMIT) && + limitp->glim_malloc >= GLOB_LIMIT_MALLOC) { + errno = 0; + return(GLOB_NOSPACE); + } + if ((statv[pglob->gl_offs + pglob->gl_pathc] = + malloc(sizeof(**statv))) == NULL) + goto copy_error; + memcpy(statv[pglob->gl_offs + pglob->gl_pathc], sb, + sizeof(*sb)); + } + statv[pglob->gl_offs + pglob->gl_pathc + 1] = NULL; + } + + for (p = path; *p++;) + ; + len = (size_t)(p - path); + limitp->glim_malloc += len; + if ((copy = malloc(len)) != NULL) { + if (g_Ctoc(path, copy, len)) { + free(copy); + return(GLOB_NOSPACE); + } + pathv[pglob->gl_offs + pglob->gl_pathc++] = copy; + } + pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; + + if ((pglob->gl_flags & GLOB_LIMIT) && + (newn * sizeof(*pathv)) + limitp->glim_malloc > + GLOB_LIMIT_MALLOC) { + errno = 0; + return(GLOB_NOSPACE); + } + copy_error: + return(copy == NULL ? GLOB_NOSPACE : 0); +} + + +/* + * pattern matching function for filenames. Each occurrence of the * + * pattern causes a recursion level. + */ +static int +match(Char *name, Char *pat, Char *patend, int recur) +{ + int ok, negate_range; + Char c, k; + + if (recur-- == 0) + return(GLOB_NOSPACE); + + while (pat < patend) { + c = *pat++; + switch (c & M_MASK) { + case M_ALL: + while (pat < patend && (*pat & M_MASK) == M_ALL) + pat++; /* eat consecutive '*' */ + if (pat == patend) + return(1); + do { + if (match(name, pat, patend, recur)) + return(1); + } while (*name++ != EOS); + return(0); + case M_ONE: + if (*name++ == EOS) + return(0); + break; + case M_SET: + ok = 0; + if ((k = *name++) == EOS) + return(0); + if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS) + ++pat; + while (((c = *pat++) & M_MASK) != M_END) { + if ((c & M_MASK) == M_CLASS) { + Char idx = *pat & M_MASK; + if (idx < NCCLASSES && + cclasses[idx].isctype(k)) + ok = 1; + ++pat; + } + if ((*pat & M_MASK) == M_RNG) { + if (c <= k && k <= pat[1]) + ok = 1; + pat += 2; + } else if (c == k) + ok = 1; + } + if (ok == negate_range) + return(0); + break; + default: + if (*name++ != c) + return(0); + break; + } + } + return(*name == EOS); +} + +/* Free allocated data belonging to a glob_t structure. */ +void +globfree(glob_t *pglob) +{ + int i; + char **pp; + + if (pglob->gl_pathv != NULL) { + pp = pglob->gl_pathv + pglob->gl_offs; + for (i = pglob->gl_pathc; i--; ++pp) + if (*pp) + free(*pp); + free(pglob->gl_pathv); + pglob->gl_pathv = NULL; + } + if (pglob->gl_statv != NULL) { + for (i = 0; i < pglob->gl_pathc; i++) { + if (pglob->gl_statv[i] != NULL) + free(pglob->gl_statv[i]); + } + free(pglob->gl_statv); + pglob->gl_statv = NULL; + } +} + +static DIR * +g_opendir(Char *str, glob_t *pglob) +{ + char buf[MAXPATHLEN]; + + if (!*str) + strlcpy(buf, ".", sizeof buf); + else { + if (g_Ctoc(str, buf, sizeof(buf))) + return(NULL); + } + + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + return((*pglob->gl_opendir)(buf)); + + return(opendir(buf)); +} + +static int +g_lstat(Char *fn, struct stat *sb, glob_t *pglob) +{ + char buf[MAXPATHLEN]; + + if (g_Ctoc(fn, buf, sizeof(buf))) + return(-1); + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + return((*pglob->gl_lstat)(buf, sb)); + return(lstat(buf, sb)); +} + +static int +g_stat(Char *fn, struct stat *sb, glob_t *pglob) +{ + char buf[MAXPATHLEN]; + + if (g_Ctoc(fn, buf, sizeof(buf))) + return(-1); + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + return((*pglob->gl_stat)(buf, sb)); + return(stat(buf, sb)); +} + +static Char * +g_strchr(const Char *str, int ch) +{ + do { + if (*str == ch) + return ((Char *)str); + } while (*str++); + return (NULL); +} + +static int +g_Ctoc(const Char *str, char *buf, u_int len) +{ + + while (len--) { + if ((*buf++ = *str++) == EOS) + return (0); + } + return (1); +} + +#ifdef DEBUG +static void +qprintf(const char *str, Char *s) +{ + Char *p; + + (void)printf("%s:\n", str); + for (p = s; *p; p++) + (void)printf("%c", CHAR(*p)); + (void)printf("\n"); + for (p = s; *p; p++) + (void)printf("%c", *p & M_PROTECT ? '"' : ' '); + (void)printf("\n"); + for (p = s; *p; p++) + (void)printf("%c", ismeta(*p) ? '_' : ' '); + (void)printf("\n"); +} +#endif + +#endif /* !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) || + !defined(GLOB_HAS_GL_MATCHC) || !defined(GLOB_HAS_GL_STATV) */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/glob.h b/crypto/external/bsd/openssh/dist/openbsd-compat/glob.h new file mode 100644 index 000000000..f8a7fa5ff --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/glob.h @@ -0,0 +1,103 @@ +/* $OpenBSD: glob.h,v 1.11 2010/09/24 13:32:55 djm Exp $ */ +/* $NetBSD: glob.h,v 1.5 1994/10/26 00:55:56 cgd Exp $ */ + +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * 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. 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. + * + * @(#)glob.h 8.1 (Berkeley) 6/2/93 + */ + +/* OPENBSD ORIGINAL: include/glob.h */ + +#if !defined(HAVE_GLOB_H) || !defined(GLOB_HAS_ALTDIRFUNC) || \ + !defined(GLOB_HAS_GL_MATCHC) || !defined(GLOB_HAS_GL_STATV) || \ + !defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \ + defined(BROKEN_GLOB) + +#ifndef _GLOB_H_ +#define _GLOB_H_ + +#include + +struct stat; +typedef struct { + int gl_pathc; /* Count of total paths so far. */ + int gl_matchc; /* Count of paths matching pattern. */ + int gl_offs; /* Reserved at beginning of gl_pathv. */ + int gl_flags; /* Copy of flags parameter to glob. */ + char **gl_pathv; /* List of paths matching pattern. */ + struct stat **gl_statv; /* Stat entries corresponding to gl_pathv */ + /* Copy of errfunc parameter to glob. */ + int (*gl_errfunc)(const char *, int); + + /* + * Alternate filesystem access methods for glob; replacement + * versions of closedir(3), readdir(3), opendir(3), stat(2) + * and lstat(2). + */ + void (*gl_closedir)(void *); + struct dirent *(*gl_readdir)(void *); + void *(*gl_opendir)(const char *); + int (*gl_lstat)(const char *, struct stat *); + int (*gl_stat)(const char *, struct stat *); +} glob_t; + +#define GLOB_APPEND 0x0001 /* Append to output from previous call. */ +#define GLOB_DOOFFS 0x0002 /* Use gl_offs. */ +#define GLOB_ERR 0x0004 /* Return on error. */ +#define GLOB_MARK 0x0008 /* Append / to matching directories. */ +#define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */ +#define GLOB_NOSORT 0x0020 /* Don't sort. */ +#define GLOB_NOESCAPE 0x1000 /* Disable backslash escaping. */ + +#define GLOB_NOSPACE (-1) /* Malloc call failed. */ +#define GLOB_ABORTED (-2) /* Unignored error. */ +#define GLOB_NOMATCH (-3) /* No match and GLOB_NOCHECK not set. */ +#define GLOB_NOSYS (-4) /* Function not supported. */ + +#define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */ +#define GLOB_BRACE 0x0080 /* Expand braces ala csh. */ +#define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */ +#define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */ +#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */ +#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */ +#define GLOB_LIMIT 0x2000 /* Limit pattern match output to ARG_MAX */ +#define GLOB_KEEPSTAT 0x4000 /* Retain stat data for paths in gl_statv. */ +#define GLOB_ABEND GLOB_ABORTED /* backward compatibility */ + +int glob(const char *, int, int (*)(const char *, int), glob_t *); +void globfree(glob_t *); + +#endif /* !_GLOB_H_ */ + +#endif /* !defined(HAVE_GLOB_H) || !defined(GLOB_HAS_ALTDIRFUNC) || + !defined(GLOB_HAS_GL_MATCHC) || !defined(GLOH_HAS_GL_STATV) */ + diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/inet_aton.c b/crypto/external/bsd/openssh/dist/openbsd-compat/inet_aton.c new file mode 100644 index 000000000..130597e14 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/inet_aton.c @@ -0,0 +1,179 @@ +/* $OpenBSD: inet_addr.c,v 1.9 2005/08/06 20:30:03 espie Exp $ */ + +/* + * Copyright (c) 1983, 1990, 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. 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. + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * - + * --Copyright-- + */ + +/* OPENBSD ORIGINAL: lib/libc/net/inet_addr.c */ + +#include "includes.h" + +#if !defined(HAVE_INET_ATON) + +#include +#include +#include +#include +#include + +#if 0 +/* + * Ascii internet address interpretation routine. + * The value returned is in network order. + */ +in_addr_t +inet_addr(const char *cp) +{ + struct in_addr val; + + if (inet_aton(cp, &val)) + return (val.s_addr); + return (INADDR_NONE); +} +#endif + +/* + * Check whether "cp" is a valid ascii representation + * of an Internet address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * This replaces inet_addr, the return value from which + * cannot distinguish between failure and a local broadcast address. + */ +int +inet_aton(const char *cp, struct in_addr *addr) +{ + u_int32_t val; + int base, n; + char c; + u_int parts[4]; + u_int *pp = parts; + + c = *cp; + for (;;) { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, isdigit=decimal. + */ + if (!isdigit(c)) + return (0); + val = 0; base = 10; + if (c == '0') { + c = *++cp; + if (c == 'x' || c == 'X') + base = 16, c = *++cp; + else + base = 8; + } + for (;;) { + if (isascii(c) && isdigit(c)) { + val = (val * base) + (c - '0'); + c = *++cp; + } else if (base == 16 && isascii(c) && isxdigit(c)) { + val = (val << 4) | + (c + 10 - (islower(c) ? 'a' : 'A')); + c = *++cp; + } else + break; + } + if (c == '.') { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3) + return (0); + *pp++ = val; + c = *++cp; + } else + break; + } + /* + * Check for trailing characters. + */ + if (c != '\0' && (!isascii(c) || !isspace(c))) + return (0); + /* + * Concoct the address according to + * the number of parts specified. + */ + n = pp - parts + 1; + switch (n) { + + case 0: + return (0); /* initial nondigit */ + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if ((val > 0xffffff) || (parts[0] > 0xff)) + return (0); + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff)) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff)) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + if (addr) + addr->s_addr = htonl(val); + return (1); +} + +#endif /* !defined(HAVE_INET_ATON) */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/inet_ntoa.c b/crypto/external/bsd/openssh/dist/openbsd-compat/inet_ntoa.c new file mode 100644 index 000000000..0eb7b3bd7 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/inet_ntoa.c @@ -0,0 +1,59 @@ +/* $OpenBSD: inet_ntoa.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */ +/* + * Copyright (c) 1983, 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. 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. + */ + +/* OPENBSD ORIGINAL: lib/libc/net/inet_ntoa.c */ + +#include "includes.h" + +#if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) + +/* + * Convert network-format internet address + * to base 256 d.d.d.d representation. + */ +#include +#include +#include +#include + +char * +inet_ntoa(struct in_addr in) +{ + static char b[18]; + char *p; + + p = (char *)∈ +#define UC(b) (((int)b)&0xff) + (void)snprintf(b, sizeof(b), + "%u.%u.%u.%u", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3])); + return (b); +} + +#endif /* defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/inet_ntop.c b/crypto/external/bsd/openssh/dist/openbsd-compat/inet_ntop.c new file mode 100644 index 000000000..3259037ba --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/inet_ntop.c @@ -0,0 +1,211 @@ +/* $OpenBSD: inet_ntop.c,v 1.8 2008/12/09 19:38:38 otto Exp $ */ + +/* Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/net/inet_ntop.c */ + +#include "includes.h" + +#ifndef HAVE_INET_NTOP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef IN6ADDRSZ +#define IN6ADDRSZ 16 /* IPv6 T_AAAA */ +#endif + +#ifndef INT16SZ +#define INT16SZ 2 /* for systems without 16-bit ints */ +#endif + +/* + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static const char *inet_ntop4(const u_char *src, char *dst, size_t size); +static const char *inet_ntop6(const u_char *src, char *dst, size_t size); + +/* char * + * inet_ntop(af, src, dst, size) + * convert a network format address to presentation format. + * return: + * pointer to presentation format address (`dst'), or NULL (see errno). + * author: + * Paul Vixie, 1996. + */ +const char * +inet_ntop(int af, const void *src, char *dst, socklen_t size) +{ + switch (af) { + case AF_INET: + return (inet_ntop4(src, dst, (size_t)size)); + case AF_INET6: + return (inet_ntop6(src, dst, (size_t)size)); + default: + errno = EAFNOSUPPORT; + return (NULL); + } + /* NOTREACHED */ +} + +/* const char * + * inet_ntop4(src, dst, size) + * format an IPv4 address, more or less like inet_ntoa() + * return: + * `dst' (as a const) + * notes: + * (1) uses no statics + * (2) takes a u_char* not an in_addr as input + * author: + * Paul Vixie, 1996. + */ +static const char * +inet_ntop4(const u_char *src, char *dst, size_t size) +{ + static const char fmt[] = "%u.%u.%u.%u"; + char tmp[sizeof "255.255.255.255"]; + int l; + + l = snprintf(tmp, size, fmt, src[0], src[1], src[2], src[3]); + if (l <= 0 || l >= size) { + errno = ENOSPC; + return (NULL); + } + strlcpy(dst, tmp, size); + return (dst); +} + +/* const char * + * inet_ntop6(src, dst, size) + * convert IPv6 binary address into presentation (printable) format + * author: + * Paul Vixie, 1996. + */ +static const char * +inet_ntop6(const u_char *src, char *dst, size_t size) +{ + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; + char *tp, *ep; + struct { int base, len; } best, cur; + u_int words[IN6ADDRSZ / INT16SZ]; + int i; + int advance; + + /* + * Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, '\0', sizeof words); + for (i = 0; i < IN6ADDRSZ; i++) + words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + best.base = -1; + cur.base = -1; + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { + if (words[i] == 0) { + if (cur.base == -1) + cur.base = i, cur.len = 1; + else + cur.len++; + } else { + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + } + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + } + if (best.base != -1 && best.len < 2) + best.base = -1; + + /* + * Format the result. + */ + tp = tmp; + ep = tmp + sizeof(tmp); + for (i = 0; i < (IN6ADDRSZ / INT16SZ) && tp < ep; i++) { + /* Are we inside the best run of 0x00's? */ + if (best.base != -1 && i >= best.base && + i < (best.base + best.len)) { + if (i == best.base) { + if (tp + 1 >= ep) + return (NULL); + *tp++ = ':'; + } + continue; + } + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) { + if (tp + 1 >= ep) + return (NULL); + *tp++ = ':'; + } + /* Is this address an encapsulated IPv4? */ + if (i == 6 && best.base == 0 && + (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { + if (!inet_ntop4(src+12, tp, (size_t)(ep - tp))) + return (NULL); + tp += strlen(tp); + break; + } + advance = snprintf(tp, ep - tp, "%x", words[i]); + if (advance <= 0 || advance >= ep - tp) + return (NULL); + tp += advance; + } + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) { + if (tp + 1 >= ep) + return (NULL); + *tp++ = ':'; + } + if (tp + 1 >= ep) + return (NULL); + *tp++ = '\0'; + + /* + * Check for overflow, copy, and we're done. + */ + if ((size_t)(tp - tmp) > size) { + errno = ENOSPC; + return (NULL); + } + strlcpy(dst, tmp, size); + return (dst); +} + +#endif /* !HAVE_INET_NTOP */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/kludge-fd_set.c b/crypto/external/bsd/openssh/dist/openbsd-compat/kludge-fd_set.c new file mode 100644 index 000000000..6c2ffb64b --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/kludge-fd_set.c @@ -0,0 +1,28 @@ +/* Placed in the public domain. */ + +/* + * _FORTIFY_SOURCE includes a misguided check for FD_SET(n)/FD_ISSET(b) + * where n > FD_SETSIZE. This breaks OpenSSH and other programs that + * explicitly allocate fd_sets. To avoid this, we wrap FD_SET in a + * function compiled without _FORTIFY_SOURCE. + */ + +#include "config.h" + +#if defined(HAVE_FEATURES_H) && defined(_FORTIFY_SOURCE) +# include +# if defined(__GNU_LIBRARY__) && defined(__GLIBC_PREREQ) +# if __GLIBC_PREREQ(2, 15) && (_FORTIFY_SOURCE > 0) +# undef _FORTIFY_SOURCE +# undef __USE_FORTIFY_LEVEL +# include +void kludge_FD_SET(int n, fd_set *set) { + FD_SET(n, set); +} +int kludge_FD_ISSET(int n, fd_set *set) { + return FD_ISSET(n, set); +} +# endif /* __GLIBC_PREREQ(2, 15) && (_FORTIFY_SOURCE > 0) */ +# endif /* __GNU_LIBRARY__ && __GLIBC_PREREQ */ +#endif /* HAVE_FEATURES_H && _FORTIFY_SOURCE */ + diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/md5.c b/crypto/external/bsd/openssh/dist/openbsd-compat/md5.c new file mode 100644 index 000000000..195ab515d --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/md5.c @@ -0,0 +1,251 @@ +/* $OpenBSD: md5.c,v 1.9 2014/01/08 06:14:57 tedu Exp $ */ + +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */ + +#include "includes.h" + +#ifndef WITH_OPENSSL + +#include +#include +#include "md5.h" + +#define PUT_64BIT_LE(cp, value) do { \ + (cp)[7] = (value) >> 56; \ + (cp)[6] = (value) >> 48; \ + (cp)[5] = (value) >> 40; \ + (cp)[4] = (value) >> 32; \ + (cp)[3] = (value) >> 24; \ + (cp)[2] = (value) >> 16; \ + (cp)[1] = (value) >> 8; \ + (cp)[0] = (value); } while (0) + +#define PUT_32BIT_LE(cp, value) do { \ + (cp)[3] = (value) >> 24; \ + (cp)[2] = (value) >> 16; \ + (cp)[1] = (value) >> 8; \ + (cp)[0] = (value); } while (0) + +static u_int8_t PADDING[MD5_BLOCK_LENGTH] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void +MD5Init(MD5_CTX *ctx) +{ + ctx->count = 0; + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xefcdab89; + ctx->state[2] = 0x98badcfe; + ctx->state[3] = 0x10325476; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +void +MD5Update(MD5_CTX *ctx, const unsigned char *input, size_t len) +{ + size_t have, need; + + /* Check how many bytes we already have and how many more we need. */ + have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1)); + need = MD5_BLOCK_LENGTH - have; + + /* Update bitcount */ + ctx->count += (u_int64_t)len << 3; + + if (len >= need) { + if (have != 0) { + memcpy(ctx->buffer + have, input, need); + MD5Transform(ctx->state, ctx->buffer); + input += need; + len -= need; + have = 0; + } + + /* Process data in MD5_BLOCK_LENGTH-byte chunks. */ + while (len >= MD5_BLOCK_LENGTH) { + MD5Transform(ctx->state, input); + input += MD5_BLOCK_LENGTH; + len -= MD5_BLOCK_LENGTH; + } + } + + /* Handle any remaining bytes of data. */ + if (len != 0) + memcpy(ctx->buffer + have, input, len); +} + +/* + * Pad pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +void +MD5Pad(MD5_CTX *ctx) +{ + u_int8_t count[8]; + size_t padlen; + + /* Convert count to 8 bytes in little endian order. */ + PUT_64BIT_LE(count, ctx->count); + + /* Pad out to 56 mod 64. */ + padlen = MD5_BLOCK_LENGTH - + ((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1)); + if (padlen < 1 + 8) + padlen += MD5_BLOCK_LENGTH; + MD5Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */ + MD5Update(ctx, count, 8); +} + +/* + * Final wrapup--call MD5Pad, fill in digest and zero out ctx. + */ +void +MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx) +{ + int i; + + MD5Pad(ctx); + for (i = 0; i < 4; i++) + PUT_32BIT_LE(digest + i * 4, ctx->state[i]); + memset(ctx, 0, sizeof(*ctx)); +} + + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +void +MD5Transform(u_int32_t state[4], const u_int8_t block[MD5_BLOCK_LENGTH]) +{ + u_int32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4]; + +#if BYTE_ORDER == LITTLE_ENDIAN + memcpy(in, block, sizeof(in)); +#else + for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) { + in[a] = (u_int32_t)( + (u_int32_t)(block[a * 4 + 0]) | + (u_int32_t)(block[a * 4 + 1]) << 8 | + (u_int32_t)(block[a * 4 + 2]) << 16 | + (u_int32_t)(block[a * 4 + 3]) << 24); + } +#endif + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + + MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21); + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; +} +#endif /* !WITH_OPENSSL */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/md5.h b/crypto/external/bsd/openssh/dist/openbsd-compat/md5.h new file mode 100644 index 000000000..c83c19dca --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/md5.h @@ -0,0 +1,51 @@ +/* $OpenBSD: md5.h,v 1.17 2012/12/05 23:19:57 deraadt Exp $ */ + +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + */ + +#ifndef _MD5_H_ +#define _MD5_H_ + +#ifndef WITH_OPENSSL + +#define MD5_BLOCK_LENGTH 64 +#define MD5_DIGEST_LENGTH 16 +#define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_LENGTH * 2 + 1) + +typedef struct MD5Context { + u_int32_t state[4]; /* state */ + u_int64_t count; /* number of bits, mod 2^64 */ + u_int8_t buffer[MD5_BLOCK_LENGTH]; /* input buffer */ +} MD5_CTX; + +void MD5Init(MD5_CTX *); +void MD5Update(MD5_CTX *, const u_int8_t *, size_t) + __attribute__((__bounded__(__string__,2,3))); +void MD5Pad(MD5_CTX *); +void MD5Final(u_int8_t [MD5_DIGEST_LENGTH], MD5_CTX *) + __attribute__((__bounded__(__minbytes__,1,MD5_DIGEST_LENGTH))); +void MD5Transform(u_int32_t [4], const u_int8_t [MD5_BLOCK_LENGTH]) + __attribute__((__bounded__(__minbytes__,1,4))) + __attribute__((__bounded__(__minbytes__,2,MD5_BLOCK_LENGTH))); +char *MD5End(MD5_CTX *, char *) + __attribute__((__bounded__(__minbytes__,2,MD5_DIGEST_STRING_LENGTH))); +char *MD5File(const char *, char *) + __attribute__((__bounded__(__minbytes__,2,MD5_DIGEST_STRING_LENGTH))); +char *MD5FileChunk(const char *, char *, off_t, off_t) + __attribute__((__bounded__(__minbytes__,2,MD5_DIGEST_STRING_LENGTH))); +char *MD5Data(const u_int8_t *, size_t, char *) + __attribute__((__bounded__(__string__,1,2))) + __attribute__((__bounded__(__minbytes__,3,MD5_DIGEST_STRING_LENGTH))); + +#endif /* !WITH_OPENSSL */ + +#endif /* _MD5_H_ */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/mktemp.c b/crypto/external/bsd/openssh/dist/openbsd-compat/mktemp.c new file mode 100644 index 000000000..4eb52f421 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/mktemp.c @@ -0,0 +1,141 @@ +/* THIS FILE HAS BEEN MODIFIED FROM THE ORIGINAL OPENBSD SOURCE */ +/* Changes: Removed mktemp */ + +/* $OpenBSD: mktemp.c,v 1.30 2010/03/21 23:09:30 schwarze Exp $ */ +/* + * Copyright (c) 1996-1998, 2008 Theo de Raadt + * Copyright (c) 1997, 2008-2009 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/stdio/mktemp.c */ + +#include "includes.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP) + +#define MKTEMP_NAME 0 +#define MKTEMP_FILE 1 +#define MKTEMP_DIR 2 + +#define TEMPCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" +#define NUM_CHARS (sizeof(TEMPCHARS) - 1) + +static int +mktemp_internal(char *path, int slen, int mode) +{ + char *start, *cp, *ep; + const char *tempchars = TEMPCHARS; + unsigned int r, tries; + struct stat sb; + size_t len; + int fd; + + len = strlen(path); + if (len == 0 || slen < 0 || (size_t)slen >= len) { + errno = EINVAL; + return(-1); + } + ep = path + len - slen; + + tries = 1; + for (start = ep; start > path && start[-1] == 'X'; start--) { + if (tries < INT_MAX / NUM_CHARS) + tries *= NUM_CHARS; + } + tries *= 2; + + do { + for (cp = start; cp != ep; cp++) { + r = arc4random_uniform(NUM_CHARS); + *cp = tempchars[r]; + } + + switch (mode) { + case MKTEMP_NAME: + if (lstat(path, &sb) != 0) + return(errno == ENOENT ? 0 : -1); + break; + case MKTEMP_FILE: + fd = open(path, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR); + if (fd != -1 || errno != EEXIST) + return(fd); + break; + case MKTEMP_DIR: + if (mkdir(path, S_IRUSR|S_IWUSR|S_IXUSR) == 0) + return(0); + if (errno != EEXIST) + return(-1); + break; + } + } while (--tries); + + errno = EEXIST; + return(-1); +} + +#if 0 +char *_mktemp(char *); + +char * +_mktemp(char *path) +{ + if (mktemp_internal(path, 0, MKTEMP_NAME) == -1) + return(NULL); + return(path); +} + +__warn_references(mktemp, + "warning: mktemp() possibly used unsafely; consider using mkstemp()"); + +char * +mktemp(char *path) +{ + return(_mktemp(path)); +} +#endif + +int +mkstemp(char *path) +{ + return(mktemp_internal(path, 0, MKTEMP_FILE)); +} + +int +mkstemps(char *path, int slen) +{ + return(mktemp_internal(path, slen, MKTEMP_FILE)); +} + +char * +mkdtemp(char *path) +{ + int error; + + error = mktemp_internal(path, 0, MKTEMP_DIR); + return(error ? NULL : path); +} + +#endif /* !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP) */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/openbsd-compat.h b/crypto/external/bsd/openssh/dist/openbsd-compat/openbsd-compat.h new file mode 100644 index 000000000..1ff7114ef --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/openbsd-compat.h @@ -0,0 +1,302 @@ +/* $Id: openbsd-compat.h,v 1.62 2014/09/30 23:43:08 djm Exp $ */ + +/* + * Copyright (c) 1999-2003 Damien Miller. All rights reserved. + * Copyright (c) 2003 Ben Lindstrom. All rights reserved. + * Copyright (c) 2002 Tim Rice. 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. + */ + +#ifndef _OPENBSD_COMPAT_H +#define _OPENBSD_COMPAT_H + +#include "includes.h" + +#include +#include + +#include + +/* OpenBSD function replacements */ +#include "base64.h" +#include "sigact.h" +#include "glob.h" +#include "readpassphrase.h" +#include "vis.h" +#include "getrrsetbyname.h" +#include "sha1.h" +#include "sha2.h" +#include "rmd160.h" +#include "md5.h" +#include "blf.h" + +#ifndef HAVE_BASENAME +char *basename(const char *path); +#endif + +#ifndef HAVE_BINDRESVPORT_SA +int bindresvport_sa(int sd, struct sockaddr *sa); +#endif + +#ifndef HAVE_CLOSEFROM +void closefrom(int); +#endif + +#ifndef HAVE_GETCWD +char *getcwd(char *pt, size_t size); +#endif + +#ifndef HAVE_REALLOCARRAY +void *reallocarray(void *, size_t, size_t); +#endif + +#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) +/* + * glibc's FORTIFY_SOURCE can redefine this and prevent us picking up the + * compat version. + */ +# ifdef BROKEN_REALPATH +# define realpath(x, y) _ssh_compat_realpath(x, y) +# endif + +char *realpath(const char *path, char *resolved); +#endif + +#ifndef HAVE_RRESVPORT_AF +int rresvport_af(int *alport, sa_family_t af); +#endif + +#ifndef HAVE_STRLCPY +/* #include XXX Still needed? */ +size_t strlcpy(char *dst, const char *src, size_t siz); +#endif + +#ifndef HAVE_STRLCAT +/* #include XXX Still needed? */ +size_t strlcat(char *dst, const char *src, size_t siz); +#endif + +#ifndef HAVE_SETENV +int setenv(register const char *name, register const char *value, int rewrite); +#endif + +#ifndef HAVE_STRMODE +void strmode(int mode, char *p); +#endif + +#ifndef HAVE_STRPTIME +#include +char *strptime(const char *buf, const char *fmt, struct tm *tm); +#endif + +#if !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP) +int mkstemps(char *path, int slen); +int mkstemp(char *path); +char *mkdtemp(char *path); +#endif + +#ifndef HAVE_DAEMON +int daemon(int nochdir, int noclose); +#endif + +#ifndef HAVE_DIRNAME +char *dirname(const char *path); +#endif + +#ifndef HAVE_FMT_SCALED +#define FMT_SCALED_STRSIZE 7 +int fmt_scaled(long long number, char *result); +#endif + +#ifndef HAVE_SCAN_SCALED +int scan_scaled(char *, long long *); +#endif + +#if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) +char *inet_ntoa(struct in_addr in); +#endif + +#ifndef HAVE_INET_NTOP +const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); +#endif + +#ifndef HAVE_INET_ATON +int inet_aton(const char *cp, struct in_addr *addr); +#endif + +#ifndef HAVE_STRSEP +char *strsep(char **stringp, const char *delim); +#endif + +#ifndef HAVE_SETPROCTITLE +void setproctitle(const char *fmt, ...); +void compat_init_setproctitle(int argc, char *argv[]); +#endif + +#ifndef HAVE_GETGROUPLIST +/* #include XXXX Still needed ? */ +int getgrouplist(const char *, gid_t, gid_t *, int *); +#endif + +#if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET) +int BSDgetopt(int argc, char * const *argv, const char *opts); +#include "openbsd-compat/getopt.h" +#endif + +#if defined(HAVE_DECL_WRITEV) && HAVE_DECL_WRITEV == 0 +# include +# include +int writev(int, struct iovec *, int); +#endif + +/* Home grown routines */ +#include "bsd-misc.h" +#include "bsd-setres_id.h" +#include "bsd-statvfs.h" +#include "bsd-waitpid.h" +#include "bsd-poll.h" + +#ifndef HAVE_GETPEEREID +int getpeereid(int , uid_t *, gid_t *); +#endif + +#ifdef HAVE_ARC4RANDOM +# ifndef HAVE_ARC4RANDOM_STIR +# define arc4random_stir() +# endif +#else +unsigned int arc4random(void); +void arc4random_stir(void); +#endif /* !HAVE_ARC4RANDOM */ + +#ifndef HAVE_ARC4RANDOM_BUF +void arc4random_buf(void *, size_t); +#endif + +#ifndef HAVE_ARC4RANDOM_UNIFORM +u_int32_t arc4random_uniform(u_int32_t); +#endif + +#ifndef HAVE_ASPRINTF +int asprintf(char **, const char *, ...); +#endif + +#ifndef HAVE_OPENPTY +# include /* for struct winsize */ +int openpty(int *, int *, char *, struct termios *, struct winsize *); +#endif /* HAVE_OPENPTY */ + +/* #include XXX needed? For size_t */ + +#ifndef HAVE_SNPRINTF +int snprintf(char *, size_t, SNPRINTF_CONST char *, ...); +#endif + +#ifndef HAVE_STRTOLL +long long strtoll(const char *, char **, int); +#endif + +#ifndef HAVE_STRTOUL +unsigned long strtoul(const char *, char **, int); +#endif + +#ifndef HAVE_STRTOULL +unsigned long long strtoull(const char *, char **, int); +#endif + +#ifndef HAVE_STRTONUM +long long strtonum(const char *, long long, long long, const char **); +#endif + +/* multibyte character support */ +#ifndef HAVE_MBLEN +# define mblen(x, y) (1) +#endif + +#if !defined(HAVE_VASPRINTF) || !defined(HAVE_VSNPRINTF) +# include +#endif + +#ifndef HAVE_VASPRINTF +int vasprintf(char **, const char *, va_list); +#endif + +#ifndef HAVE_VSNPRINTF +int vsnprintf(char *, size_t, const char *, va_list); +#endif + +#ifndef HAVE_USER_FROM_UID +char *user_from_uid(uid_t, int); +#endif + +#ifndef HAVE_GROUP_FROM_GID +char *group_from_gid(gid_t, int); +#endif + +#ifndef HAVE_TIMINGSAFE_BCMP +int timingsafe_bcmp(const void *, const void *, size_t); +#endif + +#ifndef HAVE_BCRYPT_PBKDF +int bcrypt_pbkdf(const char *, size_t, const u_int8_t *, size_t, + u_int8_t *, size_t, unsigned int); +#endif + +#ifndef HAVE_EXPLICIT_BZERO +void explicit_bzero(void *p, size_t n); +#endif + +void *xmmap(size_t size); +char *xcrypt(const char *password, const char *salt); +char *shadow_pw(struct passwd *pw); + +/* rfc2553 socket API replacements */ +#include "fake-rfc2553.h" + +/* Routines for a single OS platform */ +#include "bsd-cray.h" +#include "bsd-cygwin_util.h" + +#include "port-aix.h" +#include "port-irix.h" +#include "port-linux.h" +#include "port-solaris.h" +#include "port-tun.h" +#include "port-uw.h" + +/* _FORTIFY_SOURCE breaks FD_ISSET(n)/FD_SET(n) for n > FD_SETSIZE. Avoid. */ +#if defined(HAVE_FEATURES_H) && defined(_FORTIFY_SOURCE) +# include +# if defined(__GNU_LIBRARY__) && defined(__GLIBC_PREREQ) +# if __GLIBC_PREREQ(2, 15) && (_FORTIFY_SOURCE > 0) +# include /* Ensure include guard is defined */ +# undef FD_SET +# undef FD_ISSET +# define FD_SET(n, set) kludge_FD_SET(n, set) +# define FD_ISSET(n, set) kludge_FD_ISSET(n, set) +void kludge_FD_SET(int, fd_set *); +int kludge_FD_ISSET(int, fd_set *); +# endif /* __GLIBC_PREREQ(2, 15) && (_FORTIFY_SOURCE > 0) */ +# endif /* __GNU_LIBRARY__ && __GLIBC_PREREQ */ +#endif /* HAVE_FEATURES_H && _FORTIFY_SOURCE */ + +#endif /* _OPENBSD_COMPAT_H */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/openssl-compat.c b/crypto/external/bsd/openssh/dist/openbsd-compat/openssl-compat.c new file mode 100644 index 000000000..63a660c7a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/openssl-compat.c @@ -0,0 +1,84 @@ +/* $Id: openssl-compat.c,v 1.19 2014/07/02 05:28:07 djm Exp $ */ + +/* + * Copyright (c) 2005 Darren Tucker + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define SSH_DONT_OVERLOAD_OPENSSL_FUNCS +#include "includes.h" + +#ifdef WITH_OPENSSL + +#include +#include + +#ifdef USE_OPENSSL_ENGINE +# include +# include +#endif + +#include "log.h" + +#include "openssl-compat.h" + +/* + * OpenSSL version numbers: MNNFFPPS: major minor fix patch status + * We match major, minor, fix and status (not patch) for <1.0.0. + * After that, we acceptable compatible fix versions (so we + * allow 1.0.1 to work with 1.0.0). Going backwards is only allowed + * within a patch series. + */ + +int +ssh_compatible_openssl(long headerver, long libver) +{ + long mask, hfix, lfix; + + /* exact match is always OK */ + if (headerver == libver) + return 1; + + /* for versions < 1.0.0, major,minor,fix,status must match */ + if (headerver < 0x1000000f) { + mask = 0xfffff00fL; /* major,minor,fix,status */ + return (headerver & mask) == (libver & mask); + } + + /* + * For versions >= 1.0.0, major,minor,status must match and library + * fix version must be equal to or newer than the header. + */ + mask = 0xfff0000fL; /* major,minor,status */ + hfix = (headerver & 0x000ff000) >> 12; + lfix = (libver & 0x000ff000) >> 12; + if ( (headerver & mask) == (libver & mask) && lfix >= hfix) + return 1; + return 0; +} + +#ifdef USE_OPENSSL_ENGINE +void +ssh_OpenSSL_add_all_algorithms(void) +{ + OpenSSL_add_all_algorithms(); + + /* Enable use of crypto hardware */ + ENGINE_load_builtin_engines(); + ENGINE_register_all_complete(); + OPENSSL_config(NULL); +} +#endif + +#endif /* WITH_OPENSSL */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/openssl-compat.h b/crypto/external/bsd/openssh/dist/openbsd-compat/openssl-compat.h new file mode 100644 index 000000000..8917551d3 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/openssl-compat.h @@ -0,0 +1,96 @@ +/* $Id: openssl-compat.h,v 1.31 2014/08/29 18:18:29 djm Exp $ */ + +/* + * Copyright (c) 2005 Darren Tucker + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _OPENSSL_COMPAT_H +#define _OPENSSL_COMPAT_H + +#include "includes.h" +#ifdef WITH_OPENSSL + +#include +#include +#include +#include + +int ssh_compatible_openssl(long, long); + +#if (OPENSSL_VERSION_NUMBER <= 0x0090805fL) +# error OpenSSL 0.9.8f or greater is required +#endif + +#if OPENSSL_VERSION_NUMBER < 0x10000001L +# define LIBCRYPTO_EVP_INL_TYPE unsigned int +#else +# define LIBCRYPTO_EVP_INL_TYPE size_t +#endif + +#ifndef OPENSSL_RSA_MAX_MODULUS_BITS +# define OPENSSL_RSA_MAX_MODULUS_BITS 16384 +#endif +#ifndef OPENSSL_DSA_MAX_MODULUS_BITS +# define OPENSSL_DSA_MAX_MODULUS_BITS 10000 +#endif + +#ifndef OPENSSL_HAVE_EVPCTR +# define EVP_aes_128_ctr evp_aes_128_ctr +# define EVP_aes_192_ctr evp_aes_128_ctr +# define EVP_aes_256_ctr evp_aes_128_ctr +const EVP_CIPHER *evp_aes_128_ctr(void); +void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, size_t); +#endif + +/* Avoid some #ifdef. Code that uses these is unreachable without GCM */ +#if !defined(OPENSSL_HAVE_EVPGCM) && !defined(EVP_CTRL_GCM_SET_IV_FIXED) +# define EVP_CTRL_GCM_SET_IV_FIXED -1 +# define EVP_CTRL_GCM_IV_GEN -1 +# define EVP_CTRL_GCM_SET_TAG -1 +# define EVP_CTRL_GCM_GET_TAG -1 +#endif + +/* Replace missing EVP_CIPHER_CTX_ctrl() with something that returns failure */ +#ifndef HAVE_EVP_CIPHER_CTX_CTRL +# ifdef OPENSSL_HAVE_EVPGCM +# error AES-GCM enabled without EVP_CIPHER_CTX_ctrl /* shouldn't happen */ +# else +# define EVP_CIPHER_CTX_ctrl(a,b,c,d) (0) +# endif +#endif + +/* + * We overload some of the OpenSSL crypto functions with ssh_* equivalents + * to automatically handle OpenSSL engine initialisation. + * + * In order for the compat library to call the real functions, it must + * define SSH_DONT_OVERLOAD_OPENSSL_FUNCS before including this file and + * implement the ssh_* equivalents. + */ +#ifndef SSH_DONT_OVERLOAD_OPENSSL_FUNCS + +# ifdef USE_OPENSSL_ENGINE +# ifdef OpenSSL_add_all_algorithms +# undef OpenSSL_add_all_algorithms +# endif +# define OpenSSL_add_all_algorithms() ssh_OpenSSL_add_all_algorithms() +# endif + +void ssh_OpenSSL_add_all_algorithms(void); + +#endif /* SSH_DONT_OVERLOAD_OPENSSL_FUNCS */ + +#endif /* WITH_OPENSSL */ +#endif /* _OPENSSL_COMPAT_H */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/port-aix.c b/crypto/external/bsd/openssh/dist/openbsd-compat/port-aix.c new file mode 100644 index 000000000..8da367d48 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/port-aix.c @@ -0,0 +1,472 @@ +/* + * + * Copyright (c) 2001 Gert Doering. All rights reserved. + * Copyright (c) 2003,2004,2005,2006 Darren Tucker. 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" + +#include "xmalloc.h" +#include "buffer.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "ssh.h" +#include "log.h" + +#ifdef _AIX + +#include +#if defined(HAVE_NETDB_H) +# include +#endif +#include +#include +#include +#include +#include + +#ifdef WITH_AIXAUTHENTICATE +# include +# include +# if defined(HAVE_SYS_AUDIT_H) && defined(AIX_LOGINFAILED_4ARG) +# include +# endif +# include +#endif + +#include "port-aix.h" + +static char *lastlogin_msg = NULL; + +# ifdef HAVE_SETAUTHDB +static char old_registry[REGISTRY_SIZE] = ""; +# endif + +/* + * AIX has a "usrinfo" area where logname and other stuff is stored - + * a few applications actually use this and die if it's not set + * + * NOTE: TTY= should be set, but since no one uses it and it's hard to + * acquire due to privsep code. We will just drop support. + */ +void +aix_usrinfo(struct passwd *pw) +{ + u_int i; + size_t len; + char *cp; + + len = sizeof("LOGNAME= NAME= ") + (2 * strlen(pw->pw_name)); + cp = xmalloc(len); + + i = snprintf(cp, len, "LOGNAME=%s%cNAME=%s%c", pw->pw_name, '\0', + pw->pw_name, '\0'); + if (usrinfo(SETUINFO, cp, i) == -1) + fatal("Couldn't set usrinfo: %s", strerror(errno)); + debug3("AIX/UsrInfo: set len %d", i); + + free(cp); +} + +# ifdef WITH_AIXAUTHENTICATE +/* + * Remove embedded newlines in string (if any). + * Used before logging messages returned by AIX authentication functions + * so the message is logged on one line. + */ +void +aix_remove_embedded_newlines(char *p) +{ + if (p == NULL) + return; + + for (; *p; p++) { + if (*p == '\n') + *p = ' '; + } + /* Remove trailing whitespace */ + if (*--p == ' ') + *p = '\0'; +} + +/* + * Test specifically for the case where SYSTEM == NONE and AUTH1 contains + * anything other than NONE or SYSTEM, which indicates that the admin has + * configured the account for purely AUTH1-type authentication. + * + * Since authenticate() doesn't check AUTH1, and sshd can't sanely support + * AUTH1 itself, in such a case authenticate() will allow access without + * authentation, which is almost certainly not what the admin intends. + * + * (The native tools, eg login, will process the AUTH1 list in addition to + * the SYSTEM list by using ckuserID(), however ckuserID() and AUTH1 methods + * have been deprecated since AIX 4.2.x and would be very difficult for sshd + * to support. + * + * Returns 0 if an unsupportable combination is found, 1 otherwise. + */ +static int +aix_valid_authentications(const char *user) +{ + char *auth1, *sys, *p; + int valid = 1; + + if (getuserattr((char *)user, S_AUTHSYSTEM, &sys, SEC_CHAR) != 0) { + logit("Can't retrieve attribute SYSTEM for %s: %.100s", + user, strerror(errno)); + return 0; + } + + debug3("AIX SYSTEM attribute %s", sys); + if (strcmp(sys, "NONE") != 0) + return 1; /* not "NONE", so is OK */ + + if (getuserattr((char *)user, S_AUTH1, &auth1, SEC_LIST) != 0) { + logit("Can't retrieve attribute auth1 for %s: %.100s", + user, strerror(errno)); + return 0; + } + + p = auth1; + /* A SEC_LIST is concatenated strings, ending with two NULs. */ + while (p[0] != '\0' && p[1] != '\0') { + debug3("AIX auth1 attribute list member %s", p); + if (strcmp(p, "NONE") != 0 && strcmp(p, "SYSTEM")) { + logit("Account %s has unsupported auth1 value '%s'", + user, p); + valid = 0; + } + p += strlen(p) + 1; + } + + return (valid); +} + +/* + * Do authentication via AIX's authenticate routine. We loop until the + * reenter parameter is 0, but normally authenticate is called only once. + * + * Note: this function returns 1 on success, whereas AIX's authenticate() + * returns 0. + */ +int +sys_auth_passwd(Authctxt *ctxt, const char *password) +{ + char *authmsg = NULL, *msg = NULL, *name = ctxt->pw->pw_name; + int authsuccess = 0, expired, reenter, result; + + do { + result = authenticate((char *)name, (char *)password, &reenter, + &authmsg); + aix_remove_embedded_newlines(authmsg); + debug3("AIX/authenticate result %d, authmsg %.100s", result, + authmsg); + } while (reenter); + + if (!aix_valid_authentications(name)) + result = -1; + + if (result == 0) { + authsuccess = 1; + + /* + * Record successful login. We don't have a pty yet, so just + * label the line as "ssh" + */ + aix_setauthdb(name); + + /* + * Check if the user's password is expired. + */ + expired = passwdexpired(name, &msg); + if (msg && *msg) { + buffer_append(ctxt->loginmsg, msg, strlen(msg)); + aix_remove_embedded_newlines(msg); + } + debug3("AIX/passwdexpired returned %d msg %.100s", expired, msg); + + switch (expired) { + case 0: /* password not expired */ + break; + case 1: /* expired, password change required */ + ctxt->force_pwchange = 1; + break; + default: /* user can't change(2) or other error (-1) */ + logit("Password can't be changed for user %s: %.100s", + name, msg); + free(msg); + authsuccess = 0; + } + + aix_restoreauthdb(); + } + + free(authmsg); + + return authsuccess; +} + +/* + * Check if specified account is permitted to log in. + * Returns 1 if login is allowed, 0 if not allowed. + */ +int +sys_auth_allowed_user(struct passwd *pw, Buffer *loginmsg) +{ + char *msg = NULL; + int result, permitted = 0; + struct stat st; + + /* + * Don't perform checks for root account (PermitRootLogin controls + * logins via ssh) or if running as non-root user (since + * loginrestrictions will always fail due to insufficient privilege). + */ + if (pw->pw_uid == 0 || geteuid() != 0) { + debug3("%s: not checking", __func__); + return 1; + } + + result = loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &msg); + if (result == 0) + permitted = 1; + /* + * If restricted because /etc/nologin exists, the login will be denied + * in session.c after the nologin message is sent, so allow for now + * and do not append the returned message. + */ + if (result == -1 && errno == EPERM && stat(_PATH_NOLOGIN, &st) == 0) + permitted = 1; + else if (msg != NULL) + buffer_append(loginmsg, msg, strlen(msg)); + if (msg == NULL) + msg = xstrdup("(none)"); + aix_remove_embedded_newlines(msg); + debug3("AIX/loginrestrictions returned %d msg %.100s", result, msg); + + if (!permitted) + logit("Login restricted for %s: %.100s", pw->pw_name, msg); + free(msg); + return permitted; +} + +int +sys_auth_record_login(const char *user, const char *host, const char *ttynm, + Buffer *loginmsg) +{ + char *msg = NULL; + int success = 0; + + aix_setauthdb(user); + if (loginsuccess((char *)user, (char *)host, (char *)ttynm, &msg) == 0) { + success = 1; + if (msg != NULL) { + debug("AIX/loginsuccess: msg %s", msg); + if (lastlogin_msg == NULL) + lastlogin_msg = msg; + } + } + aix_restoreauthdb(); + return (success); +} + +char * +sys_auth_get_lastlogin_msg(const char *user, uid_t uid) +{ + char *msg = lastlogin_msg; + + lastlogin_msg = NULL; + return msg; +} + +# ifdef CUSTOM_FAILED_LOGIN +/* + * record_failed_login: generic "login failed" interface function + */ +void +record_failed_login(const char *user, const char *hostname, const char *ttyname) +{ + if (geteuid() != 0) + return; + + aix_setauthdb(user); +# ifdef AIX_LOGINFAILED_4ARG + loginfailed((char *)user, (char *)hostname, (char *)ttyname, + AUDIT_FAIL_AUTH); +# else + loginfailed((char *)user, (char *)hostname, (char *)ttyname); +# endif + aix_restoreauthdb(); +} +# endif /* CUSTOM_FAILED_LOGIN */ + +/* + * If we have setauthdb, retrieve the password registry for the user's + * account then feed it to setauthdb. This will mean that subsequent AIX auth + * functions will only use the specified loadable module. If we don't have + * setauthdb this is a no-op. + */ +void +aix_setauthdb(const char *user) +{ +# ifdef HAVE_SETAUTHDB + char *registry; + + if (setuserdb(S_READ) == -1) { + debug3("%s: Could not open userdb to read", __func__); + return; + } + + if (getuserattr((char *)user, S_REGISTRY, ®istry, SEC_CHAR) == 0) { + if (setauthdb(registry, old_registry) == 0) + debug3("AIX/setauthdb set registry '%s'", registry); + else + debug3("AIX/setauthdb set registry '%s' failed: %s", + registry, strerror(errno)); + } else + debug3("%s: Could not read S_REGISTRY for user: %s", __func__, + strerror(errno)); + enduserdb(); +# endif /* HAVE_SETAUTHDB */ +} + +/* + * Restore the user's registry settings from old_registry. + * Note that if the first aix_setauthdb fails, setauthdb("") is still safe + * (it restores the system default behaviour). If we don't have setauthdb, + * this is a no-op. + */ +void +aix_restoreauthdb(void) +{ +# ifdef HAVE_SETAUTHDB + if (setauthdb(old_registry, NULL) == 0) + debug3("%s: restoring old registry '%s'", __func__, + old_registry); + else + debug3("%s: failed to restore old registry %s", __func__, + old_registry); +# endif /* HAVE_SETAUTHDB */ +} + +# endif /* WITH_AIXAUTHENTICATE */ + +# ifdef USE_AIX_KRB_NAME +/* + * aix_krb5_get_principal_name: returns the user's kerberos client principal name if + * configured, otherwise NULL. Caller must free returned string. + */ +char * +aix_krb5_get_principal_name(char *pw_name) +{ + char *authname = NULL, *authdomain = NULL, *principal = NULL; + + setuserdb(S_READ); + if (getuserattr(pw_name, S_AUTHDOMAIN, &authdomain, SEC_CHAR) != 0) + debug("AIX getuserattr S_AUTHDOMAIN: %s", strerror(errno)); + if (getuserattr(pw_name, S_AUTHNAME, &authname, SEC_CHAR) != 0) + debug("AIX getuserattr S_AUTHNAME: %s", strerror(errno)); + + if (authdomain != NULL) + xasprintf(&principal, "%s@%s", authname ? authname : pw_name, authdomain); + else if (authname != NULL) + principal = xstrdup(authname); + enduserdb(); + return principal; +} +# endif /* USE_AIX_KRB_NAME */ + +# if defined(AIX_GETNAMEINFO_HACK) && !defined(BROKEN_ADDRINFO) +# undef getnameinfo +/* + * For some reason, AIX's getnameinfo will refuse to resolve the all-zeros + * IPv6 address into its textual representation ("::"), so we wrap it + * with a function that will. + */ +int +sshaix_getnameinfo(const struct sockaddr *sa, size_t salen, char *host, + size_t hostlen, char *serv, size_t servlen, int flags) +{ + struct sockaddr_in6 *sa6; + u_int32_t *a6; + + if (flags & (NI_NUMERICHOST|NI_NUMERICSERV) && + sa->sa_family == AF_INET6) { + sa6 = (struct sockaddr_in6 *)sa; + a6 = sa6->sin6_addr.u6_addr.u6_addr32; + + if (a6[0] == 0 && a6[1] == 0 && a6[2] == 0 && a6[3] == 0) { + strlcpy(host, "::", hostlen); + snprintf(serv, servlen, "%d", sa6->sin6_port); + return 0; + } + } + return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); +} +# endif /* AIX_GETNAMEINFO_HACK */ + +# if defined(USE_GETGRSET) +# include +int +getgrouplist(const char *user, gid_t pgid, gid_t *groups, int *grpcnt) +{ + char *cp, *grplist, *grp; + gid_t gid; + int ret = 0, ngroups = 0, maxgroups; + long l; + + maxgroups = *grpcnt; + + if ((cp = grplist = getgrset(user)) == NULL) + return -1; + + /* handle zero-length case */ + if (maxgroups <= 0) { + *grpcnt = 0; + return -1; + } + + /* copy primary group */ + groups[ngroups++] = pgid; + + /* copy each entry from getgrset into group list */ + while ((grp = strsep(&grplist, ",")) != NULL) { + l = strtol(grp, NULL, 10); + if (ngroups >= maxgroups || l == LONG_MIN || l == LONG_MAX) { + ret = -1; + goto out; + } + gid = (gid_t)l; + if (gid == pgid) + continue; /* we have already added primary gid */ + groups[ngroups++] = gid; + } +out: + free(cp); + *grpcnt = ngroups; + return ret; +} +# endif /* USE_GETGRSET */ + +#endif /* _AIX */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/port-aix.h b/crypto/external/bsd/openssh/dist/openbsd-compat/port-aix.h new file mode 100644 index 000000000..53e4e88a0 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/port-aix.h @@ -0,0 +1,127 @@ +/* $Id: port-aix.h,v 1.32 2009/12/20 23:49:22 dtucker Exp $ */ + +/* + * + * Copyright (c) 2001 Gert Doering. All rights reserved. + * Copyright (c) 2004,2005,2006 Darren Tucker. 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. + */ + +#ifdef _AIX + +#ifdef HAVE_SYS_SOCKET_H +# include +#endif + +#include "buffer.h" + +/* These should be in the system headers but are not. */ +int usrinfo(int, char *, int); +#if defined(HAVE_DECL_SETAUTHDB) && (HAVE_DECL_SETAUTHDB == 0) +int setauthdb(const char *, char *); +#endif +/* these may or may not be in the headers depending on the version */ +#if defined(HAVE_DECL_AUTHENTICATE) && (HAVE_DECL_AUTHENTICATE == 0) +int authenticate(char *, char *, int *, char **); +#endif +#if defined(HAVE_DECL_LOGINFAILED) && (HAVE_DECL_LOGINFAILED == 0) +int loginfailed(char *, char *, char *); +#endif +#if defined(HAVE_DECL_LOGINRESTRICTIONS) && (HAVE_DECL_LOGINRESTRICTIONS == 0) +int loginrestrictions(char *, int, char *, char **); +#endif +#if defined(HAVE_DECL_LOGINSUCCESS) && (HAVE_DECL_LOGINSUCCESS == 0) +int loginsuccess(char *, char *, char *, char **); +#endif +#if defined(HAVE_DECL_PASSWDEXPIRED) && (HAVE_DECL_PASSWDEXPIRED == 0) +int passwdexpired(char *, char **); +#endif + +/* Some versions define r_type in the above headers, which causes a conflict */ +#ifdef r_type +# undef r_type +#endif + +/* AIX 4.2.x doesn't have nanosleep but does have nsleep which is equivalent */ +#if !defined(HAVE_NANOSLEEP) && defined(HAVE_NSLEEP) +# define nanosleep(a,b) nsleep(a,b) +#endif + +/* For struct timespec on AIX 4.2.x */ +#ifdef HAVE_SYS_TIMERS_H +# include +#endif + +/* for setpcred and friends */ +#ifdef HAVE_USERSEC_H +# include +#endif + +/* + * According to the setauthdb man page, AIX password registries must be 15 + * chars or less plus terminating NUL. + */ +#ifdef HAVE_SETAUTHDB +# define REGISTRY_SIZE 16 +#endif + +void aix_usrinfo(struct passwd *); + +#ifdef WITH_AIXAUTHENTICATE +# define CUSTOM_SYS_AUTH_PASSWD 1 +# define CUSTOM_SYS_AUTH_ALLOWED_USER 1 +int sys_auth_allowed_user(struct passwd *, Buffer *); +# define CUSTOM_SYS_AUTH_RECORD_LOGIN 1 +int sys_auth_record_login(const char *, const char *, const char *, Buffer *); +# define CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG +char *sys_auth_get_lastlogin_msg(const char *, uid_t); +# define CUSTOM_FAILED_LOGIN 1 +# if defined(S_AUTHDOMAIN) && defined (S_AUTHNAME) +# define USE_AIX_KRB_NAME +char *aix_krb5_get_principal_name(char *); +# endif +#endif + +void aix_setauthdb(const char *); +void aix_restoreauthdb(void); +void aix_remove_embedded_newlines(char *); + +#if defined(AIX_GETNAMEINFO_HACK) && !defined(BROKEN_GETADDRINFO) +# ifdef getnameinfo +# undef getnameinfo +# endif +int sshaix_getnameinfo(const struct sockaddr *, size_t, char *, size_t, + char *, size_t, int); +# define getnameinfo(a,b,c,d,e,f,g) (sshaix_getnameinfo(a,b,c,d,e,f,g)) +#endif + +/* + * We use getgrset in preference to multiple getgrent calls for efficiency + * plus it supports NIS and LDAP groups. + */ +#if !defined(HAVE_GETGROUPLIST) && defined(HAVE_GETGRSET) +# define HAVE_GETGROUPLIST +# define USE_GETGRSET +int getgrouplist(const char *, gid_t, gid_t *, int *); +#endif + +#endif /* _AIX */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/port-irix.c b/crypto/external/bsd/openssh/dist/openbsd-compat/port-irix.c new file mode 100644 index 000000000..ba751a538 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/port-irix.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2000 Denis Parker. All rights reserved. + * Copyright (c) 2000 Michael Stone. 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" + +#if defined(WITH_IRIX_PROJECT) || \ + defined(WITH_IRIX_JOBS) || \ + defined(WITH_IRIX_ARRAY) + +#include +#include +#include + +#ifdef WITH_IRIX_PROJECT +# include +#endif /* WITH_IRIX_PROJECT */ +#ifdef WITH_IRIX_JOBS +# include +#endif +#ifdef WITH_IRIX_AUDIT +# include +#endif /* WITH_IRIX_AUDIT */ + +void +irix_setusercontext(struct passwd *pw) +{ +#ifdef WITH_IRIX_PROJECT + prid_t projid; +#endif +#ifdef WITH_IRIX_JOBS + jid_t jid = 0; +#elif defined(WITH_IRIX_ARRAY) + int jid = 0; +#endif + +#ifdef WITH_IRIX_JOBS + jid = jlimit_startjob(pw->pw_name, pw->pw_uid, "interactive"); + if (jid == -1) + fatal("Failed to create job container: %.100s", + strerror(errno)); +#endif /* WITH_IRIX_JOBS */ +#ifdef WITH_IRIX_ARRAY + /* initialize array session */ + if (jid == 0 && newarraysess() != 0) + fatal("Failed to set up new array session: %.100s", + strerror(errno)); +#endif /* WITH_IRIX_ARRAY */ +#ifdef WITH_IRIX_PROJECT + /* initialize irix project info */ + if ((projid = getdfltprojuser(pw->pw_name)) == -1) { + debug("Failed to get project id, using projid 0"); + projid = 0; + } + if (setprid(projid)) + fatal("Failed to initialize project %d for %s: %.100s", + (int)projid, pw->pw_name, strerror(errno)); +#endif /* WITH_IRIX_PROJECT */ +#ifdef WITH_IRIX_AUDIT + if (sysconf(_SC_AUDIT)) { + debug("Setting sat id to %d", (int) pw->pw_uid); + if (satsetid(pw->pw_uid)) + debug("error setting satid: %.100s", strerror(errno)); + } +#endif /* WITH_IRIX_AUDIT */ +} + + +#endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/port-irix.h b/crypto/external/bsd/openssh/dist/openbsd-compat/port-irix.h new file mode 100644 index 000000000..67c486307 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/port-irix.h @@ -0,0 +1,39 @@ +/* $Id: port-irix.h,v 1.4 2003/08/29 16:59:52 mouring Exp $ */ + +/* + * Copyright (c) 2000 Denis Parker. All rights reserved. + * Copyright (c) 2000 Michael Stone. 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. + */ + +#ifndef _PORT_IRIX_H +#define _PORT_IRIX_H + +#if defined(WITH_IRIX_PROJECT) || \ + defined(WITH_IRIX_JOBS) || \ + defined(WITH_IRIX_ARRAY) + +void irix_setusercontext(struct passwd *pw); + +#endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ + +#endif /* ! _PORT_IRIX_H */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/port-linux.c b/crypto/external/bsd/openssh/dist/openbsd-compat/port-linux.c new file mode 100644 index 000000000..f36999d7a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/port-linux.c @@ -0,0 +1,311 @@ +/* $Id: port-linux.c,v 1.18 2013/06/01 22:07:32 dtucker Exp $ */ + +/* + * Copyright (c) 2005 Daniel Walsh + * Copyright (c) 2006 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Linux-specific portability code - just SELinux support at present + */ + +#include "includes.h" + +#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) +#include +#include +#include +#include + +#include "log.h" +#include "xmalloc.h" +#include "port-linux.h" + +#ifdef WITH_SELINUX +#include +#include +#include + +#ifndef SSH_SELINUX_UNCONFINED_TYPE +# define SSH_SELINUX_UNCONFINED_TYPE ":unconfined_t:" +#endif + +/* Wrapper around is_selinux_enabled() to log its return value once only */ +int +ssh_selinux_enabled(void) +{ + static int enabled = -1; + + if (enabled == -1) { + enabled = (is_selinux_enabled() == 1); + debug("SELinux support %s", enabled ? "enabled" : "disabled"); + } + + return (enabled); +} + +/* Return the default security context for the given username */ +static security_context_t +ssh_selinux_getctxbyname(char *pwname) +{ + security_context_t sc = NULL; + char *sename = NULL, *lvl = NULL; + int r; + +#ifdef HAVE_GETSEUSERBYNAME + if (getseuserbyname(pwname, &sename, &lvl) != 0) + return NULL; +#else + sename = pwname; + lvl = NULL; +#endif + +#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL + r = get_default_context_with_level(sename, lvl, NULL, &sc); +#else + r = get_default_context(sename, NULL, &sc); +#endif + + if (r != 0) { + switch (security_getenforce()) { + case -1: + fatal("%s: ssh_selinux_getctxbyname: " + "security_getenforce() failed", __func__); + case 0: + error("%s: Failed to get default SELinux security " + "context for %s", __func__, pwname); + sc = NULL; + break; + default: + fatal("%s: Failed to get default SELinux security " + "context for %s (in enforcing mode)", + __func__, pwname); + } + } + +#ifdef HAVE_GETSEUSERBYNAME + free(sename); + free(lvl); +#endif + + return sc; +} + +/* Set the execution context to the default for the specified user */ +void +ssh_selinux_setup_exec_context(char *pwname) +{ + security_context_t user_ctx = NULL; + + if (!ssh_selinux_enabled()) + return; + + debug3("%s: setting execution context", __func__); + + user_ctx = ssh_selinux_getctxbyname(pwname); + if (setexeccon(user_ctx) != 0) { + switch (security_getenforce()) { + case -1: + fatal("%s: security_getenforce() failed", __func__); + case 0: + error("%s: Failed to set SELinux execution " + "context for %s", __func__, pwname); + break; + default: + fatal("%s: Failed to set SELinux execution context " + "for %s (in enforcing mode)", __func__, pwname); + } + } + if (user_ctx != NULL) + freecon(user_ctx); + + debug3("%s: done", __func__); +} + +/* Set the TTY context for the specified user */ +void +ssh_selinux_setup_pty(char *pwname, const char *tty) +{ + security_context_t new_tty_ctx = NULL; + security_context_t user_ctx = NULL; + security_context_t old_tty_ctx = NULL; + + if (!ssh_selinux_enabled()) + return; + + debug3("%s: setting TTY context on %s", __func__, tty); + + user_ctx = ssh_selinux_getctxbyname(pwname); + + /* XXX: should these calls fatal() upon failure in enforcing mode? */ + + if (getfilecon(tty, &old_tty_ctx) == -1) { + error("%s: getfilecon: %s", __func__, strerror(errno)); + goto out; + } + + if (security_compute_relabel(user_ctx, old_tty_ctx, + SECCLASS_CHR_FILE, &new_tty_ctx) != 0) { + error("%s: security_compute_relabel: %s", + __func__, strerror(errno)); + goto out; + } + + if (setfilecon(tty, new_tty_ctx) != 0) + error("%s: setfilecon: %s", __func__, strerror(errno)); + out: + if (new_tty_ctx != NULL) + freecon(new_tty_ctx); + if (old_tty_ctx != NULL) + freecon(old_tty_ctx); + if (user_ctx != NULL) + freecon(user_ctx); + debug3("%s: done", __func__); +} + +void +ssh_selinux_change_context(const char *newname) +{ + int len, newlen; + char *oldctx, *newctx, *cx; + void (*switchlog) (const char *fmt,...) = logit; + + if (!ssh_selinux_enabled()) + return; + + if (getcon((security_context_t *)&oldctx) < 0) { + logit("%s: getcon failed with %s", __func__, strerror(errno)); + return; + } + if ((cx = index(oldctx, ':')) == NULL || (cx = index(cx + 1, ':')) == + NULL) { + logit ("%s: unparseable context %s", __func__, oldctx); + return; + } + + /* + * Check whether we are attempting to switch away from an unconfined + * security context. + */ + if (strncmp(cx, SSH_SELINUX_UNCONFINED_TYPE, + sizeof(SSH_SELINUX_UNCONFINED_TYPE) - 1) == 0) + switchlog = debug3; + + newlen = strlen(oldctx) + strlen(newname) + 1; + newctx = xmalloc(newlen); + len = cx - oldctx + 1; + memcpy(newctx, oldctx, len); + strlcpy(newctx + len, newname, newlen - len); + if ((cx = index(cx + 1, ':'))) + strlcat(newctx, cx, newlen); + debug3("%s: setting context from '%s' to '%s'", __func__, + oldctx, newctx); + if (setcon(newctx) < 0) + switchlog("%s: setcon %s from %s failed with %s", __func__, + newctx, oldctx, strerror(errno)); + free(oldctx); + free(newctx); +} + +void +ssh_selinux_setfscreatecon(const char *path) +{ + security_context_t context; + + if (!ssh_selinux_enabled()) + return; + if (path == NULL) { + setfscreatecon(NULL); + return; + } + if (matchpathcon(path, 0700, &context) == 0) + setfscreatecon(context); +} + +#endif /* WITH_SELINUX */ + +#ifdef LINUX_OOM_ADJUST +/* + * The magic "don't kill me" values, old and new, as documented in eg: + * http://lxr.linux.no/#linux+v2.6.32/Documentation/filesystems/proc.txt + * http://lxr.linux.no/#linux+v2.6.36/Documentation/filesystems/proc.txt + */ + +static int oom_adj_save = INT_MIN; +static char *oom_adj_path = NULL; +struct { + char *path; + int value; +} oom_adjust[] = { + {"/proc/self/oom_score_adj", -1000}, /* kernels >= 2.6.36 */ + {"/proc/self/oom_adj", -17}, /* kernels <= 2.6.35 */ + {NULL, 0}, +}; + +/* + * Tell the kernel's out-of-memory killer to avoid sshd. + * Returns the previous oom_adj value or zero. + */ +void +oom_adjust_setup(void) +{ + int i, value; + FILE *fp; + + debug3("%s", __func__); + for (i = 0; oom_adjust[i].path != NULL; i++) { + oom_adj_path = oom_adjust[i].path; + value = oom_adjust[i].value; + if ((fp = fopen(oom_adj_path, "r+")) != NULL) { + if (fscanf(fp, "%d", &oom_adj_save) != 1) + verbose("error reading %s: %s", oom_adj_path, + strerror(errno)); + else { + rewind(fp); + if (fprintf(fp, "%d\n", value) <= 0) + verbose("error writing %s: %s", + oom_adj_path, strerror(errno)); + else + debug("Set %s from %d to %d", + oom_adj_path, oom_adj_save, value); + } + fclose(fp); + return; + } + } + oom_adj_path = NULL; +} + +/* Restore the saved OOM adjustment */ +void +oom_adjust_restore(void) +{ + FILE *fp; + + debug3("%s", __func__); + if (oom_adj_save == INT_MIN || oom_adj_path == NULL || + (fp = fopen(oom_adj_path, "w")) == NULL) + return; + + if (fprintf(fp, "%d\n", oom_adj_save) <= 0) + verbose("error writing %s: %s", oom_adj_path, strerror(errno)); + else + debug("Set %s to %d", oom_adj_path, oom_adj_save); + + fclose(fp); + return; +} +#endif /* LINUX_OOM_ADJUST */ +#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/port-linux.h b/crypto/external/bsd/openssh/dist/openbsd-compat/port-linux.h new file mode 100644 index 000000000..e3d1004aa --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/port-linux.h @@ -0,0 +1,35 @@ +/* $Id: port-linux.h,v 1.5 2011/01/25 01:16:18 djm Exp $ */ + +/* + * Copyright (c) 2006 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _PORT_LINUX_H +#define _PORT_LINUX_H + +#ifdef WITH_SELINUX +int ssh_selinux_enabled(void); +void ssh_selinux_setup_pty(char *, const char *); +void ssh_selinux_setup_exec_context(char *); +void ssh_selinux_change_context(const char *); +void ssh_selinux_setfscreatecon(const char *); +#endif + +#ifdef LINUX_OOM_ADJUST +void oom_adjust_restore(void); +void oom_adjust_setup(void); +#endif + +#endif /* ! _PORT_LINUX_H */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/port-solaris.c b/crypto/external/bsd/openssh/dist/openbsd-compat/port-solaris.c new file mode 100644 index 000000000..25382f1c9 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/port-solaris.c @@ -0,0 +1,229 @@ +/* $Id: port-solaris.c,v 1.4 2010/11/05 01:03:05 dtucker Exp $ */ + +/* + * Copyright (c) 2006 Chad Mynhier. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "config.h" +#include "includes.h" + +#ifdef USE_SOLARIS_PROCESS_CONTRACTS + +#include +#include +#include + +#include +#ifdef HAVE_FCNTL_H +# include +#endif +#include +#include +#include + +#include +#include +#include + +#include "log.h" + +#define CT_TEMPLATE CTFS_ROOT "/process/template" +#define CT_LATEST CTFS_ROOT "/process/latest" + +static int tmpl_fd = -1; + +/* Lookup the latest process contract */ +static ctid_t +get_active_process_contract_id(void) +{ + int stat_fd; + ctid_t ctid = -1; + ct_stathdl_t stathdl; + + if ((stat_fd = open64(CT_LATEST, O_RDONLY)) == -1) { + error("%s: Error opening 'latest' process " + "contract: %s", __func__, strerror(errno)); + return -1; + } + if (ct_status_read(stat_fd, CTD_COMMON, &stathdl) != 0) { + error("%s: Error reading process contract " + "status: %s", __func__, strerror(errno)); + goto out; + } + if ((ctid = ct_status_get_id(stathdl)) < 0) { + error("%s: Error getting process contract id: %s", + __func__, strerror(errno)); + goto out; + } + + ct_status_free(stathdl); + out: + close(stat_fd); + return ctid; +} + +void +solaris_contract_pre_fork(void) +{ + if ((tmpl_fd = open64(CT_TEMPLATE, O_RDWR)) == -1) { + error("%s: open %s: %s", __func__, + CT_TEMPLATE, strerror(errno)); + return; + } + + debug2("%s: setting up process contract template on fd %d", + __func__, tmpl_fd); + + /* First we set the template parameters and event sets. */ + if (ct_pr_tmpl_set_param(tmpl_fd, CT_PR_PGRPONLY) != 0) { + error("%s: Error setting process contract parameter set " + "(pgrponly): %s", __func__, strerror(errno)); + goto fail; + } + if (ct_pr_tmpl_set_fatal(tmpl_fd, CT_PR_EV_HWERR) != 0) { + error("%s: Error setting process contract template " + "fatal events: %s", __func__, strerror(errno)); + goto fail; + } + if (ct_tmpl_set_critical(tmpl_fd, 0) != 0) { + error("%s: Error setting process contract template " + "critical events: %s", __func__, strerror(errno)); + goto fail; + } + if (ct_tmpl_set_informative(tmpl_fd, CT_PR_EV_HWERR) != 0) { + error("%s: Error setting process contract template " + "informative events: %s", __func__, strerror(errno)); + goto fail; + } + + /* Now make this the active template for this process. */ + if (ct_tmpl_activate(tmpl_fd) != 0) { + error("%s: Error activating process contract " + "template: %s", __func__, strerror(errno)); + goto fail; + } + return; + + fail: + if (tmpl_fd != -1) { + close(tmpl_fd); + tmpl_fd = -1; + } +} + +void +solaris_contract_post_fork_child() +{ + debug2("%s: clearing process contract template on fd %d", + __func__, tmpl_fd); + + /* Clear the active template. */ + if (ct_tmpl_clear(tmpl_fd) != 0) + error("%s: Error clearing active process contract " + "template: %s", __func__, strerror(errno)); + + close(tmpl_fd); + tmpl_fd = -1; +} + +void +solaris_contract_post_fork_parent(pid_t pid) +{ + ctid_t ctid; + char ctl_path[256]; + int r, ctl_fd = -1, stat_fd = -1; + + debug2("%s: clearing template (fd %d)", __func__, tmpl_fd); + + if (tmpl_fd == -1) + return; + + /* First clear the active template. */ + if ((r = ct_tmpl_clear(tmpl_fd)) != 0) + error("%s: Error clearing active process contract " + "template: %s", __func__, strerror(errno)); + + close(tmpl_fd); + tmpl_fd = -1; + + /* + * If either the fork didn't succeed (pid < 0), or clearing + * th active contract failed (r != 0), then we have nothing + * more do. + */ + if (r != 0 || pid <= 0) + return; + + /* Now lookup and abandon the contract we've created. */ + ctid = get_active_process_contract_id(); + + debug2("%s: abandoning contract id %ld", __func__, ctid); + + snprintf(ctl_path, sizeof(ctl_path), + CTFS_ROOT "/process/%ld/ctl", ctid); + if ((ctl_fd = open64(ctl_path, O_WRONLY)) < 0) { + error("%s: Error opening process contract " + "ctl file: %s", __func__, strerror(errno)); + goto fail; + } + if (ct_ctl_abandon(ctl_fd) < 0) { + error("%s: Error abandoning process contract: %s", + __func__, strerror(errno)); + goto fail; + } + close(ctl_fd); + return; + + fail: + if (tmpl_fd != -1) { + close(tmpl_fd); + tmpl_fd = -1; + } + if (stat_fd != -1) + close(stat_fd); + if (ctl_fd != -1) + close(ctl_fd); +} +#endif + +#ifdef USE_SOLARIS_PROJECTS +#include +#include + +/* + * Get/set solaris default project. + * If we fail, just run along gracefully. + */ +void +solaris_set_default_project(struct passwd *pw) +{ + struct project *defaultproject; + struct project tempproject; + char buf[1024]; + + /* get default project, if we fail just return gracefully */ + if ((defaultproject = getdefaultproj(pw->pw_name, &tempproject, &buf, + sizeof(buf))) > 0) { + /* set default project */ + if (setproject(defaultproject->pj_name, pw->pw_name, + TASK_NORMAL) != 0) + debug("setproject(%s): %s", defaultproject->pj_name, + strerror(errno)); + } else { + /* debug on getdefaultproj() error */ + debug("getdefaultproj(%s): %s", pw->pw_name, strerror(errno)); + } +} +#endif /* USE_SOLARIS_PROJECTS */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/port-solaris.h b/crypto/external/bsd/openssh/dist/openbsd-compat/port-solaris.h new file mode 100644 index 000000000..cd442e78b --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/port-solaris.h @@ -0,0 +1,30 @@ +/* $Id: port-solaris.h,v 1.2 2010/11/05 01:03:05 dtucker Exp $ */ + +/* + * Copyright (c) 2006 Chad Mynhier. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _PORT_SOLARIS_H + +#include + +#include + +void solaris_contract_pre_fork(void); +void solaris_contract_post_fork_child(void); +void solaris_contract_post_fork_parent(pid_t pid); +void solaris_set_default_project(struct passwd *); + +#endif diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/port-tun.c b/crypto/external/bsd/openssh/dist/openbsd-compat/port-tun.c new file mode 100644 index 000000000..49e7b4d99 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/port-tun.c @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2005 Reyk Floeter + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "openbsd-compat/sys-queue.h" +#include "log.h" +#include "misc.h" +#include "sshbuf.h" +#include "channels.h" +#include "ssherr.h" + +/* + * This is the portable version of the SSH tunnel forwarding, it + * uses some preprocessor definitions for various platform-specific + * settings. + * + * SSH_TUN_LINUX Use the (newer) Linux tun/tap device + * SSH_TUN_FREEBSD Use the FreeBSD tun/tap device + * SSH_TUN_COMPAT_AF Translate the OpenBSD address family + * SSH_TUN_PREPEND_AF Prepend/remove the address family + */ + +/* + * System-specific tunnel open function + */ + +#if defined(SSH_TUN_LINUX) +#include +#include + +int +sys_tun_open(int tun, int mode) +{ + struct ifreq ifr; + int fd = -1; + const char *name = NULL; + + if ((fd = open("/dev/net/tun", O_RDWR)) == -1) { + debug("%s: failed to open tunnel control interface: %s", + __func__, strerror(errno)); + return (-1); + } + + bzero(&ifr, sizeof(ifr)); + + if (mode == SSH_TUNMODE_ETHERNET) { + ifr.ifr_flags = IFF_TAP; + name = "tap%d"; + } else { + ifr.ifr_flags = IFF_TUN; + name = "tun%d"; + } + ifr.ifr_flags |= IFF_NO_PI; + + if (tun != SSH_TUNID_ANY) { + if (tun > SSH_TUNID_MAX) { + debug("%s: invalid tunnel id %x: %s", __func__, + tun, strerror(errno)); + goto failed; + } + snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), name, tun); + } + + if (ioctl(fd, TUNSETIFF, &ifr) == -1) { + debug("%s: failed to configure tunnel (mode %d): %s", __func__, + mode, strerror(errno)); + goto failed; + } + + if (tun == SSH_TUNID_ANY) + debug("%s: tunnel mode %d fd %d", __func__, mode, fd); + else + debug("%s: %s mode %d fd %d", __func__, ifr.ifr_name, mode, fd); + + return (fd); + + failed: + close(fd); + return (-1); +} +#endif /* SSH_TUN_LINUX */ + +#ifdef SSH_TUN_FREEBSD +#include +#include + +#ifdef HAVE_NET_IF_TUN_H +#include +#endif + +int +sys_tun_open(int tun, int mode) +{ + struct ifreq ifr; + char name[100]; + int fd = -1, sock, flag; + const char *tunbase = "tun"; + + if (mode == SSH_TUNMODE_ETHERNET) { +#ifdef SSH_TUN_NO_L2 + debug("%s: no layer 2 tunnelling support", __func__); + return (-1); +#else + tunbase = "tap"; +#endif + } + + /* Open the tunnel device */ + if (tun <= SSH_TUNID_MAX) { + snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun); + fd = open(name, O_RDWR); + } else if (tun == SSH_TUNID_ANY) { + for (tun = 100; tun >= 0; tun--) { + snprintf(name, sizeof(name), "/dev/%s%d", + tunbase, tun); + if ((fd = open(name, O_RDWR)) >= 0) + break; + } + } else { + debug("%s: invalid tunnel %u\n", __func__, tun); + return (-1); + } + + if (fd < 0) { + debug("%s: %s open failed: %s", __func__, name, + strerror(errno)); + return (-1); + } + + /* Turn on tunnel headers */ + flag = 1; +#if defined(TUNSIFHEAD) && !defined(SSH_TUN_PREPEND_AF) + if (mode != SSH_TUNMODE_ETHERNET && + ioctl(fd, TUNSIFHEAD, &flag) == -1) { + debug("%s: ioctl(%d, TUNSIFHEAD, 1): %s", __func__, fd, + strerror(errno)); + close(fd); + } +#endif + + debug("%s: %s mode %d fd %d", __func__, name, mode, fd); + + /* Set the tunnel device operation mode */ + snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun); + if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) + goto failed; + + if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) + goto failed; + if ((ifr.ifr_flags & IFF_UP) == 0) { + ifr.ifr_flags |= IFF_UP; + if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) + goto failed; + } + + close(sock); + return (fd); + + failed: + if (fd >= 0) + close(fd); + if (sock >= 0) + close(sock); + debug("%s: failed to set %s mode %d: %s", __func__, name, + mode, strerror(errno)); + return (-1); +} +#endif /* SSH_TUN_FREEBSD */ + +/* + * System-specific channel filters + */ + +#if defined(SSH_TUN_FILTER) +#define OPENBSD_AF_INET 2 +#define OPENBSD_AF_INET6 24 + +int +sys_tun_infilter(struct Channel *c, char *buf, int len) +{ +#if defined(SSH_TUN_PREPEND_AF) + char rbuf[CHAN_RBUF]; + struct ip *iph; +#endif + u_int32_t *af; + char *ptr = buf; + int r; + +#if defined(SSH_TUN_PREPEND_AF) + if (len <= 0 || len > (int)(sizeof(rbuf) - sizeof(*af))) + return (-1); + ptr = (char *)&rbuf[0]; + bcopy(buf, ptr + sizeof(u_int32_t), len); + len += sizeof(u_int32_t); + af = (u_int32_t *)ptr; + + iph = (struct ip *)(ptr + sizeof(u_int32_t)); + switch (iph->ip_v) { + case 6: + *af = AF_INET6; + break; + case 4: + default: + *af = AF_INET; + break; + } +#endif + +#if defined(SSH_TUN_COMPAT_AF) + if (len < (int)sizeof(u_int32_t)) + return (-1); + + af = (u_int32_t *)ptr; + if (*af == htonl(AF_INET6)) + *af = htonl(OPENBSD_AF_INET6); + else + *af = htonl(OPENBSD_AF_INET); +#endif + + if ((r = sshbuf_put_string(&c->input, ptr, len)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + return (0); +} + +u_char * +sys_tun_outfilter(struct Channel *c, u_char **data, u_int *dlen) +{ + u_char *buf; + u_int32_t *af; + int r; + size_t xxx_dlen; + + /* XXX new API is incompatible with this signature. */ + if ((r = sshbuf_get_string(&c->output, data, &xxx_dlen)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + if (dlen != NULL) + *dlen = xxx_dlen; + if (*dlen < sizeof(*af)) + return (NULL); + buf = *data; + +#if defined(SSH_TUN_PREPEND_AF) + *dlen -= sizeof(u_int32_t); + buf = *data + sizeof(u_int32_t); +#elif defined(SSH_TUN_COMPAT_AF) + af = ntohl(*(u_int32_t *)buf); + if (*af == OPENBSD_AF_INET6) + *af = htonl(AF_INET6); + else + *af = htonl(AF_INET); +#endif + + return (buf); +} +#endif /* SSH_TUN_FILTER */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/port-tun.h b/crypto/external/bsd/openssh/dist/openbsd-compat/port-tun.h new file mode 100644 index 000000000..c53df01fc --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/port-tun.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2005 Reyk Floeter + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _PORT_TUN_H +#define _PORT_TUN_H + +struct Channel; + +#if defined(SSH_TUN_LINUX) || defined(SSH_TUN_FREEBSD) +# define CUSTOM_SYS_TUN_OPEN +int sys_tun_open(int, int); +#endif + +#if defined(SSH_TUN_COMPAT_AF) || defined(SSH_TUN_PREPEND_AF) +# define SSH_TUN_FILTER +int sys_tun_infilter(struct Channel *, char *, int); +u_char *sys_tun_outfilter(struct Channel *, u_char **, u_int *); +#endif + +#endif diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/port-uw.c b/crypto/external/bsd/openssh/dist/openbsd-compat/port-uw.c new file mode 100644 index 000000000..db24dbb94 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/port-uw.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2005 The SCO Group. All rights reserved. + * Copyright (c) 2005 Tim Rice. 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" + +#if defined(HAVE_LIBIAF) && !defined(HAVE_SECUREWARE) +#include +#ifdef HAVE_CRYPT_H +# include +#endif +#include +#include +#include +#include +#include + +#include "xmalloc.h" +#include "packet.h" +#include "buffer.h" +#include "key.h" +#include "auth-options.h" +#include "log.h" +#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ +#include "servconf.h" +#include "hostfile.h" +#include "auth.h" +#include "ssh.h" + +int nischeck(char *); + +int +sys_auth_passwd(Authctxt *authctxt, const char *password) +{ + struct passwd *pw = authctxt->pw; + char *salt; + int result; + + /* Just use the supplied fake password if authctxt is invalid */ + char *pw_password = authctxt->valid ? shadow_pw(pw) : pw->pw_passwd; + + /* Check for users with no password. */ + if (strcmp(pw_password, "") == 0 && strcmp(password, "") == 0) + return (1); + + /* Encrypt the candidate password using the proper salt. */ + salt = (pw_password[0] && pw_password[1]) ? pw_password : "xx"; + + /* + * Authentication is accepted if the encrypted passwords + * are identical. + */ +#ifdef UNIXWARE_LONG_PASSWORDS + if (!nischeck(pw->pw_name)) { + result = ((strcmp(bigcrypt(password, salt), pw_password) == 0) + || (strcmp(osr5bigcrypt(password, salt), pw_password) == 0)); + } + else +#endif /* UNIXWARE_LONG_PASSWORDS */ + result = (strcmp(xcrypt(password, salt), pw_password) == 0); + +#ifdef USE_LIBIAF + if (authctxt->valid) + free(pw_password); +#endif + return(result); +} + +#ifdef UNIXWARE_LONG_PASSWORDS +int +nischeck(char *namep) +{ + char password_file[] = "/etc/passwd"; + FILE *fd; + struct passwd *ent = NULL; + + if ((fd = fopen (password_file, "r")) == NULL) { + /* + * If the passwd file has dissapeared we are in a bad state. + * However, returning 0 will send us back through the + * authentication scheme that has checked the ia database for + * passwords earlier. + */ + return(0); + } + + /* + * fgetpwent() only reads from password file, so we know for certain + * that the user is local. + */ + while (ent = fgetpwent(fd)) { + if (strcmp (ent->pw_name, namep) == 0) { + /* Local user */ + fclose (fd); + return(0); + } + } + + fclose (fd); + return (1); +} + +#endif /* UNIXWARE_LONG_PASSWORDS */ + +/* + NOTE: ia_get_logpwd() allocates memory for arg 2 + functions that call shadow_pw() will need to free + */ + +#ifdef USE_LIBIAF +char * +get_iaf_password(struct passwd *pw) +{ + char *pw_password = NULL; + + uinfo_t uinfo; + if (!ia_openinfo(pw->pw_name,&uinfo)) { + ia_get_logpwd(uinfo, &pw_password); + if (pw_password == NULL) + fatal("ia_get_logpwd: Unable to get the shadow passwd"); + ia_closeinfo(uinfo); + return pw_password; + } + else + fatal("ia_openinfo: Unable to open the shadow passwd file"); +} +#endif /* USE_LIBIAF */ +#endif /* HAVE_LIBIAF and not HAVE_SECUREWARE */ + diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/port-uw.h b/crypto/external/bsd/openssh/dist/openbsd-compat/port-uw.h new file mode 100644 index 000000000..263d8b5a7 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/port-uw.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2005 Tim Rice. 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" + +#ifdef USE_LIBIAF +char * get_iaf_password(struct passwd *pw); +#endif + diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/pwcache.c b/crypto/external/bsd/openssh/dist/openbsd-compat/pwcache.c new file mode 100644 index 000000000..5a8b78801 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/pwcache.c @@ -0,0 +1,114 @@ +/* $OpenBSD: pwcache.c,v 1.9 2005/08/08 08:05:34 espie Exp $ */ +/* + * 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. 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. + */ + +/* OPENBSD ORIGINAL: lib/libc/gen/pwcache.c */ + +#include "includes.h" + +#include + +#include +#include +#include +#include +#include + +#define NCACHE 64 /* power of 2 */ +#define MASK (NCACHE - 1) /* bits to store with */ + +#ifndef HAVE_USER_FROM_UID +char * +user_from_uid(uid_t uid, int nouser) +{ + static struct ncache { + uid_t uid; + char *name; + } c_uid[NCACHE]; + static int pwopen; + static char nbuf[15]; /* 32 bits == 10 digits */ + struct passwd *pw; + struct ncache *cp; + + cp = c_uid + (uid & MASK); + if (cp->uid != uid || cp->name == NULL) { + if (pwopen == 0) { +#ifdef HAVE_SETPASSENT + setpassent(1); +#endif + pwopen = 1; + } + if ((pw = getpwuid(uid)) == NULL) { + if (nouser) + return (NULL); + (void)snprintf(nbuf, sizeof(nbuf), "%u", uid); + } + cp->uid = uid; + if (cp->name != NULL) + free(cp->name); + cp->name = strdup(pw ? pw->pw_name : nbuf); + } + return (cp->name); +} +#endif + +#ifndef HAVE_GROUP_FROM_GID +char * +group_from_gid(gid_t gid, int nogroup) +{ + static struct ncache { + gid_t gid; + char *name; + } c_gid[NCACHE]; + static int gropen; + static char nbuf[15]; /* 32 bits == 10 digits */ + struct group *gr; + struct ncache *cp; + + cp = c_gid + (gid & MASK); + if (cp->gid != gid || cp->name == NULL) { + if (gropen == 0) { +#ifdef HAVE_SETGROUPENT + setgroupent(1); +#endif + gropen = 1; + } + if ((gr = getgrgid(gid)) == NULL) { + if (nogroup) + return (NULL); + (void)snprintf(nbuf, sizeof(nbuf), "%u", gid); + } + cp->gid = gid; + if (cp->name != NULL) + free(cp->name); + cp->name = strdup(gr ? gr->gr_name : nbuf); + } + return (cp->name); +} +#endif diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/readpassphrase.c b/crypto/external/bsd/openssh/dist/openbsd-compat/readpassphrase.c new file mode 100644 index 000000000..d63cdf2f0 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/readpassphrase.c @@ -0,0 +1,213 @@ +/* $OpenBSD: readpassphrase.c,v 1.22 2010/01/13 10:20:54 dtucker Exp $ */ + +/* + * Copyright (c) 2000-2002, 2007 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ + +/* OPENBSD ORIGINAL: lib/libc/gen/readpassphrase.c */ + +#include "includes.h" + +#ifndef HAVE_READPASSPHRASE + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef TCSASOFT +# define _T_FLUSH (TCSAFLUSH|TCSASOFT) +#else +# define _T_FLUSH (TCSAFLUSH) +#endif + +/* SunOS 4.x which lacks _POSIX_VDISABLE, but has VDISABLE */ +#if !defined(_POSIX_VDISABLE) && defined(VDISABLE) +# define _POSIX_VDISABLE VDISABLE +#endif + +#ifndef _NSIG +# ifdef NSIG +# define _NSIG NSIG +# else +# define _NSIG 128 +# endif +#endif + +static volatile sig_atomic_t signo[_NSIG]; + +static void handler(int); + +char * +readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) +{ + ssize_t nr; + int input, output, save_errno, i, need_restart; + char ch, *p, *end; + struct termios term, oterm; + struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm; + struct sigaction savetstp, savettin, savettou, savepipe; + + /* I suppose we could alloc on demand in this case (XXX). */ + if (bufsiz == 0) { + errno = EINVAL; + return(NULL); + } + +restart: + for (i = 0; i < _NSIG; i++) + signo[i] = 0; + nr = -1; + save_errno = 0; + need_restart = 0; + /* + * Read and write to /dev/tty if available. If not, read from + * stdin and write to stderr unless a tty is required. + */ + if ((flags & RPP_STDIN) || + (input = output = open(_PATH_TTY, O_RDWR)) == -1) { + if (flags & RPP_REQUIRE_TTY) { + errno = ENOTTY; + return(NULL); + } + input = STDIN_FILENO; + output = STDERR_FILENO; + } + + /* + * Catch signals that would otherwise cause the user to end + * up with echo turned off in the shell. Don't worry about + * things like SIGXCPU and SIGVTALRM for now. + */ + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; /* don't restart system calls */ + sa.sa_handler = handler; + (void)sigaction(SIGALRM, &sa, &savealrm); + (void)sigaction(SIGHUP, &sa, &savehup); + (void)sigaction(SIGINT, &sa, &saveint); + (void)sigaction(SIGPIPE, &sa, &savepipe); + (void)sigaction(SIGQUIT, &sa, &savequit); + (void)sigaction(SIGTERM, &sa, &saveterm); + (void)sigaction(SIGTSTP, &sa, &savetstp); + (void)sigaction(SIGTTIN, &sa, &savettin); + (void)sigaction(SIGTTOU, &sa, &savettou); + + /* Turn off echo if possible. */ + if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) { + memcpy(&term, &oterm, sizeof(term)); + if (!(flags & RPP_ECHO_ON)) + term.c_lflag &= ~(ECHO | ECHONL); +#ifdef VSTATUS + if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) + term.c_cc[VSTATUS] = _POSIX_VDISABLE; +#endif + (void)tcsetattr(input, _T_FLUSH, &term); + } else { + memset(&term, 0, sizeof(term)); + term.c_lflag |= ECHO; + memset(&oterm, 0, sizeof(oterm)); + oterm.c_lflag |= ECHO; + } + + /* No I/O if we are already backgrounded. */ + if (signo[SIGTTOU] != 1 && signo[SIGTTIN] != 1) { + if (!(flags & RPP_STDIN)) + (void)write(output, prompt, strlen(prompt)); + end = buf + bufsiz - 1; + p = buf; + while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') { + if (p < end) { + if ((flags & RPP_SEVENBIT)) + ch &= 0x7f; + if (isalpha(ch)) { + if ((flags & RPP_FORCELOWER)) + ch = (char)tolower(ch); + if ((flags & RPP_FORCEUPPER)) + ch = (char)toupper(ch); + } + *p++ = ch; + } + } + *p = '\0'; + save_errno = errno; + if (!(term.c_lflag & ECHO)) + (void)write(output, "\n", 1); + } + + /* Restore old terminal settings and signals. */ + if (memcmp(&term, &oterm, sizeof(term)) != 0) { + while (tcsetattr(input, _T_FLUSH, &oterm) == -1 && + errno == EINTR) + continue; + } + (void)sigaction(SIGALRM, &savealrm, NULL); + (void)sigaction(SIGHUP, &savehup, NULL); + (void)sigaction(SIGINT, &saveint, NULL); + (void)sigaction(SIGQUIT, &savequit, NULL); + (void)sigaction(SIGPIPE, &savepipe, NULL); + (void)sigaction(SIGTERM, &saveterm, NULL); + (void)sigaction(SIGTSTP, &savetstp, NULL); + (void)sigaction(SIGTTIN, &savettin, NULL); + (void)sigaction(SIGTTOU, &savettou, NULL); + if (input != STDIN_FILENO) + (void)close(input); + + /* + * If we were interrupted by a signal, resend it to ourselves + * now that we have restored the signal handlers. + */ + for (i = 0; i < _NSIG; i++) { + if (signo[i]) { + kill(getpid(), i); + switch (i) { + case SIGTSTP: + case SIGTTIN: + case SIGTTOU: + need_restart = 1; + } + } + } + if (need_restart) + goto restart; + + if (save_errno) + errno = save_errno; + return(nr == -1 ? NULL : buf); +} + +#if 0 +char * +getpass(const char *prompt) +{ + static char buf[_PASSWORD_LEN + 1]; + + return(readpassphrase(prompt, buf, sizeof(buf), RPP_ECHO_OFF)); +} +#endif + +static void handler(int s) +{ + + signo[s] = 1; +} +#endif /* HAVE_READPASSPHRASE */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/readpassphrase.h b/crypto/external/bsd/openssh/dist/openbsd-compat/readpassphrase.h new file mode 100644 index 000000000..5fd7c5d77 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/readpassphrase.h @@ -0,0 +1,44 @@ +/* $OpenBSD: readpassphrase.h,v 1.5 2003/06/17 21:56:23 millert Exp $ */ + +/* + * Copyright (c) 2000, 2002 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ + +/* OPENBSD ORIGINAL: include/readpassphrase.h */ + +#ifndef _READPASSPHRASE_H_ +#define _READPASSPHRASE_H_ + +#include "includes.h" + +#ifndef HAVE_READPASSPHRASE + +#define RPP_ECHO_OFF 0x00 /* Turn off echo (default). */ +#define RPP_ECHO_ON 0x01 /* Leave echo on. */ +#define RPP_REQUIRE_TTY 0x02 /* Fail if there is no tty. */ +#define RPP_FORCELOWER 0x04 /* Force input to lower case. */ +#define RPP_FORCEUPPER 0x08 /* Force input to upper case. */ +#define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */ +#define RPP_STDIN 0x20 /* Read from stdin, not /dev/tty */ + +char * readpassphrase(const char *, char *, size_t, int); + +#endif /* HAVE_READPASSPHRASE */ + +#endif /* !_READPASSPHRASE_H_ */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/reallocarray.c b/crypto/external/bsd/openssh/dist/openbsd-compat/reallocarray.c new file mode 100644 index 000000000..1a52acc62 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/reallocarray.c @@ -0,0 +1,46 @@ +/* $OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $ */ +/* + * Copyright (c) 2008 Otto Moerbeek + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/stdlib/reallocarray.c */ + +#include "includes.h" +#ifndef HAVE_REALLOCARRAY + +#include +#include +#ifdef HAVE_STDINT_H +#include +#endif +#include + +/* + * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX + * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW + */ +#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) + +void * +reallocarray(void *optr, size_t nmemb, size_t size) +{ + if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && + nmemb > 0 && SIZE_MAX / nmemb < size) { + errno = ENOMEM; + return NULL; + } + return realloc(optr, size * nmemb); +} +#endif /* HAVE_REALLOCARRAY */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/realpath.c b/crypto/external/bsd/openssh/dist/openbsd-compat/realpath.c new file mode 100644 index 000000000..ba4cea938 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/realpath.c @@ -0,0 +1,200 @@ +/* $OpenBSD: realpath.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */ +/* + * Copyright (c) 2003 Constantin S. Svintsoff + * + * 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 names of the authors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +/* OPENBSD ORIGINAL: lib/libc/stdlib/realpath.c */ + +#include "includes.h" + +#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) + +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * char *realpath(const char *path, char resolved[PATH_MAX]); + * + * Find the real name of path, by removing all ".", ".." and symlink + * components. Returns (resolved) on success, or (NULL) on failure, + * in which case the path which caused trouble is left in (resolved). + */ +char * +realpath(const char *path, char resolved[PATH_MAX]) +{ + struct stat sb; + char *p, *q, *s; + size_t left_len, resolved_len; + unsigned symlinks; + int serrno, slen; + char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; + + serrno = errno; + symlinks = 0; + if (path[0] == '/') { + resolved[0] = '/'; + resolved[1] = '\0'; + if (path[1] == '\0') + return (resolved); + resolved_len = 1; + left_len = strlcpy(left, path + 1, sizeof(left)); + } else { + if (getcwd(resolved, PATH_MAX) == NULL) { + strlcpy(resolved, ".", PATH_MAX); + return (NULL); + } + resolved_len = strlen(resolved); + left_len = strlcpy(left, path, sizeof(left)); + } + if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { + errno = ENAMETOOLONG; + return (NULL); + } + + /* + * Iterate over path components in `left'. + */ + while (left_len != 0) { + /* + * Extract the next path component and adjust `left' + * and its length. + */ + p = strchr(left, '/'); + s = p ? p : left + left_len; + if (s - left >= (ptrdiff_t)sizeof(next_token)) { + errno = ENAMETOOLONG; + return (NULL); + } + memcpy(next_token, left, s - left); + next_token[s - left] = '\0'; + left_len -= s - left; + if (p != NULL) + memmove(left, s + 1, left_len + 1); + if (resolved[resolved_len - 1] != '/') { + if (resolved_len + 1 >= PATH_MAX) { + errno = ENAMETOOLONG; + return (NULL); + } + resolved[resolved_len++] = '/'; + resolved[resolved_len] = '\0'; + } + if (next_token[0] == '\0') + continue; + else if (strcmp(next_token, ".") == 0) + continue; + else if (strcmp(next_token, "..") == 0) { + /* + * Strip the last path component except when we have + * single "/" + */ + if (resolved_len > 1) { + resolved[resolved_len - 1] = '\0'; + q = strrchr(resolved, '/') + 1; + *q = '\0'; + resolved_len = q - resolved; + } + continue; + } + + /* + * Append the next path component and lstat() it. If + * lstat() fails we still can return successfully if + * there are no more path components left. + */ + resolved_len = strlcat(resolved, next_token, PATH_MAX); + if (resolved_len >= PATH_MAX) { + errno = ENAMETOOLONG; + return (NULL); + } + if (lstat(resolved, &sb) != 0) { + if (errno == ENOENT && p == NULL) { + errno = serrno; + return (resolved); + } + return (NULL); + } + if (S_ISLNK(sb.st_mode)) { + if (symlinks++ > MAXSYMLINKS) { + errno = ELOOP; + return (NULL); + } + slen = readlink(resolved, symlink, sizeof(symlink) - 1); + if (slen < 0) + return (NULL); + symlink[slen] = '\0'; + if (symlink[0] == '/') { + resolved[1] = 0; + resolved_len = 1; + } else if (resolved_len > 1) { + /* Strip the last path component. */ + resolved[resolved_len - 1] = '\0'; + q = strrchr(resolved, '/') + 1; + *q = '\0'; + resolved_len = q - resolved; + } + + /* + * If there are any path components left, then + * append them to symlink. The result is placed + * in `left'. + */ + if (p != NULL) { + if (symlink[slen - 1] != '/') { + if (slen + 1 >= + (ptrdiff_t)sizeof(symlink)) { + errno = ENAMETOOLONG; + return (NULL); + } + symlink[slen] = '/'; + symlink[slen + 1] = 0; + } + left_len = strlcat(symlink, left, sizeof(left)); + if (left_len >= sizeof(left)) { + errno = ENAMETOOLONG; + return (NULL); + } + } + left_len = strlcpy(left, symlink, sizeof(left)); + } + } + + /* + * Remove trailing slash except when the resolved pathname + * is a single "/". + */ + if (resolved_len > 1 && resolved[resolved_len - 1] == '/') + resolved[resolved_len - 1] = '\0'; + return (resolved); +} +#endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/regress/.cvsignore b/crypto/external/bsd/openssh/dist/openbsd-compat/regress/.cvsignore new file mode 100644 index 000000000..33074f4a3 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/regress/.cvsignore @@ -0,0 +1,6 @@ +Makefile +snprintftest +strduptest +strtonumtest +closefromtest +opensslvertest diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/regress/Makefile b/crypto/external/bsd/openssh/dist/openbsd-compat/regress/Makefile new file mode 100644 index 000000000..6a524e0ad --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/regress/Makefile @@ -0,0 +1,38 @@ +# $Id: Makefile.in,v 1.5 2014/06/17 13:06:08 dtucker Exp $ + +sysconfdir=${prefix}/etc +piddir=/var/run +srcdir=. +top_srcdir=../.. + + +CC=cc +LD=cc +CFLAGS=-g -O2 -Qunused-arguments -Wunknown-warning-option -Wall -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-result -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -ftrapv -fno-builtin-memset -fstack-protector-strong +CPPFLAGS=-I. -I.. -I$(srcdir) -I$(srcdir)/.. -DHAVE_CONFIG_H +EXEEXT= +LIBCOMPAT=../libopenbsd-compat.a +LIBS=-lcrypto -lutil -lz +LDFLAGS= -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -fstack-protector-strong $(LIBCOMPAT) + +TESTPROGS=closefromtest$(EXEEXT) snprintftest$(EXEEXT) strduptest$(EXEEXT) \ + strtonumtest$(EXEEXT) opensslvertest$(EXEEXT) + +all: t-exec ${OTHERTESTS} + +%$(EXEEXT): %.c $(LIBCOMPAT) + $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $< $(LIBCOMPAT) $(LIBS) + +t-exec: $(TESTPROGS) + @echo running compat regress tests + @for TEST in ""$?; do \ + echo "run test $${TEST}" ... 1>&2; \ + ./$${TEST}$(EXEEXT) || exit $$? ; \ + done + @echo finished compat regress tests + +clean: + rm -f *.o *.a core $(TESTPROGS) valid.out + +distclean: clean + rm -f Makefile *~ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/regress/Makefile.in b/crypto/external/bsd/openssh/dist/openbsd-compat/regress/Makefile.in new file mode 100644 index 000000000..dabdb0912 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/regress/Makefile.in @@ -0,0 +1,38 @@ +# $Id: Makefile.in,v 1.5 2014/06/17 13:06:08 dtucker Exp $ + +sysconfdir=@sysconfdir@ +piddir=@piddir@ +srcdir=@srcdir@ +top_srcdir=@top_srcdir@ + +VPATH=@srcdir@ +CC=@CC@ +LD=@LD@ +CFLAGS=@CFLAGS@ +CPPFLAGS=-I. -I.. -I$(srcdir) -I$(srcdir)/.. @CPPFLAGS@ @DEFS@ +EXEEXT=@EXEEXT@ +LIBCOMPAT=../libopenbsd-compat.a +LIBS=@LIBS@ +LDFLAGS=@LDFLAGS@ $(LIBCOMPAT) + +TESTPROGS=closefromtest$(EXEEXT) snprintftest$(EXEEXT) strduptest$(EXEEXT) \ + strtonumtest$(EXEEXT) opensslvertest$(EXEEXT) + +all: t-exec ${OTHERTESTS} + +%$(EXEEXT): %.c $(LIBCOMPAT) + $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $< $(LIBCOMPAT) $(LIBS) + +t-exec: $(TESTPROGS) + @echo running compat regress tests + @for TEST in ""$?; do \ + echo "run test $${TEST}" ... 1>&2; \ + ./$${TEST}$(EXEEXT) || exit $$? ; \ + done + @echo finished compat regress tests + +clean: + rm -f *.o *.a core $(TESTPROGS) valid.out + +distclean: clean + rm -f Makefile *~ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/regress/closefromtest.c b/crypto/external/bsd/openssh/dist/openbsd-compat/regress/closefromtest.c new file mode 100644 index 000000000..82ffeb9a7 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/regress/closefromtest.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2006 Darren Tucker + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include + +#define NUM_OPENS 10 + +int closefrom(int); + +void +fail(char *msg) +{ + fprintf(stderr, "closefrom: %s\n", msg); + exit(1); +} + +int +main(void) +{ + int i, max, fds[NUM_OPENS]; + char buf[512]; + + for (i = 0; i < NUM_OPENS; i++) + if ((fds[i] = open("/dev/null", O_RDONLY)) == -1) + exit(0); /* can't test */ + max = i - 1; + + /* should close last fd only */ + closefrom(fds[max]); + if (close(fds[max]) != -1) + fail("failed to close highest fd"); + + /* make sure we can still use remaining descriptors */ + for (i = 0; i < max; i++) + if (read(fds[i], buf, sizeof(buf)) == -1) + fail("closed descriptors it should not have"); + + /* should close all fds */ + closefrom(fds[0]); + for (i = 0; i < NUM_OPENS; i++) + if (close(fds[i]) != -1) + fail("failed to close from lowest fd"); + return 0; +} diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/regress/opensslvertest.c b/crypto/external/bsd/openssh/dist/openbsd-compat/regress/opensslvertest.c new file mode 100644 index 000000000..5d019b598 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/regress/opensslvertest.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2014 Darren Tucker + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +int ssh_compatible_openssl(long, long); + +struct version_test { + long headerver; + long libver; + int result; +} version_tests[] = { + /* built with 0.9.8b release headers */ + { 0x0090802fL, 0x0090802fL, 1}, /* exact match */ + { 0x0090802fL, 0x0090804fL, 1}, /* newer library fix version: ok */ + { 0x0090802fL, 0x0090801fL, 1}, /* older library fix version: ok */ + { 0x0090802fL, 0x0090702fL, 0}, /* older library minor version: NO */ + { 0x0090802fL, 0x0090902fL, 0}, /* newer library minor version: NO */ + { 0x0090802fL, 0x0080802fL, 0}, /* older library major version: NO */ + { 0x0090802fL, 0x1000100fL, 0}, /* newer library major version: NO */ + + /* built with 1.0.1b release headers */ + { 0x1000101fL, 0x1000101fL, 1},/* exact match */ + { 0x1000101fL, 0x1000102fL, 1}, /* newer library patch version: ok */ + { 0x1000101fL, 0x1000100fL, 1}, /* older library patch version: ok */ + { 0x1000101fL, 0x1000201fL, 1}, /* newer library fix version: ok */ + { 0x1000101fL, 0x1000001fL, 0}, /* older library fix version: NO */ + { 0x1000101fL, 0x1010101fL, 0}, /* newer library minor version: NO */ + { 0x1000101fL, 0x0000101fL, 0}, /* older library major version: NO */ + { 0x1000101fL, 0x2000101fL, 0}, /* newer library major version: NO */ +}; + +void +fail(long hver, long lver, int result) +{ + fprintf(stderr, "opensslver: header %lx library %lx != %d \n", hver, lver, result); + exit(1); +} + +int +main(void) +{ + unsigned int i; + int res; + long hver, lver; + + for (i = 0; i < sizeof(version_tests) / sizeof(version_tests[0]); i++) { + hver = version_tests[i].headerver; + lver = version_tests[i].libver; + res = version_tests[i].result; + if (ssh_compatible_openssl(hver, lver) != res) + fail(hver, lver, res); + } + exit(0); +} diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/regress/snprintftest.c b/crypto/external/bsd/openssh/dist/openbsd-compat/regress/snprintftest.c new file mode 100644 index 000000000..4ca63e180 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/regress/snprintftest.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2005 Darren Tucker + * Copyright (c) 2005 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define BUFSZ 2048 + +#include +#include +#include +#include +#include + +static int failed = 0; + +static void +fail(const char *m) +{ + fprintf(stderr, "snprintftest: %s\n", m); + failed = 1; +} + +int x_snprintf(char *str, size_t count, const char *fmt, ...) +{ + size_t ret; + va_list ap; + + va_start(ap, fmt); + ret = vsnprintf(str, count, fmt, ap); + va_end(ap); + return ret; +} + +int +main(void) +{ + char b[5]; + char *src; + + snprintf(b,5,"123456789"); + if (b[4] != '\0') + fail("snprintf does not correctly terminate long strings"); + + /* check for read overrun on unterminated string */ + if ((src = malloc(BUFSZ)) == NULL) { + fail("malloc failed"); + } else { + memset(src, 'a', BUFSZ); + snprintf(b, sizeof(b), "%.*s", 1, src); + if (strcmp(b, "a") != 0) + fail("failed with length limit '%%.s'"); + } + + /* check that snprintf and vsnprintf return sane values */ + if (snprintf(b, 1, "%s %d", "hello", 12345) != 11) + fail("snprintf does not return required length"); + if (x_snprintf(b, 1, "%s %d", "hello", 12345) != 11) + fail("vsnprintf does not return required length"); + + return failed; +} diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/regress/strduptest.c b/crypto/external/bsd/openssh/dist/openbsd-compat/regress/strduptest.c new file mode 100644 index 000000000..7f6d779be --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/regress/strduptest.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2005 Darren Tucker + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +static int fail = 0; + +void +test(const char *a) +{ + char *b; + + b = strdup(a); + if (b == 0) { + fail = 1; + return; + } + if (strcmp(a, b) != 0) + fail = 1; + free(b); +} + +int +main(void) +{ + test(""); + test("a"); + test("\0"); + test("abcdefghijklmnopqrstuvwxyz"); + return fail; +} diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/regress/strtonumtest.c b/crypto/external/bsd/openssh/dist/openbsd-compat/regress/strtonumtest.c new file mode 100644 index 000000000..50ca5bd22 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/regress/strtonumtest.c @@ -0,0 +1,80 @@ +/* $OpenBSD: strtonumtest.c,v 1.1 2004/08/03 20:38:36 otto Exp $ */ +/* + * Copyright (c) 2004 Otto Moerbeek + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: regress/lib/libc/strtonum/strtonumtest.c */ + +#include +#include +#include + +/* LLONG_MAX is known as LONGLONG_MAX on AIX */ +#if defined(LONGLONG_MAX) && !defined(LLONG_MAX) +# define LLONG_MAX LONGLONG_MAX +# define LLONG_MIN LONGLONG_MIN +#endif + +/* LLONG_MAX is known as LONG_LONG_MAX on HP-UX */ +#if defined(LONG_LONG_MAX) && !defined(LLONG_MAX) +# define LLONG_MAX LONG_LONG_MAX +# define LLONG_MIN LONG_LONG_MIN +#endif + +long long strtonum(const char *, long long, long long, const char **); + +int fail; + +void +test(const char *p, long long lb, long long ub, int ok) +{ + long long val; + const char *q; + + val = strtonum(p, lb, ub, &q); + if (ok && q != NULL) { + fprintf(stderr, "%s [%lld-%lld] ", p, lb, ub); + fprintf(stderr, "NUMBER NOT ACCEPTED %s\n", q); + fail = 1; + } else if (!ok && q == NULL) { + fprintf(stderr, "%s [%lld-%lld] %lld ", p, lb, ub, val); + fprintf(stderr, "NUMBER ACCEPTED\n"); + fail = 1; + } +} + +int main(int argc, char *argv[]) +{ + test("1", 0, 10, 1); + test("0", -2, 5, 1); + test("0", 2, 5, 0); + test("0", 2, LLONG_MAX, 0); + test("-2", 0, LLONG_MAX, 0); + test("0", -5, LLONG_MAX, 1); + test("-3", -3, LLONG_MAX, 1); + test("-9223372036854775808", LLONG_MIN, LLONG_MAX, 1); + test("9223372036854775807", LLONG_MIN, LLONG_MAX, 1); + test("-9223372036854775809", LLONG_MIN, LLONG_MAX, 0); + test("9223372036854775808", LLONG_MIN, LLONG_MAX, 0); + test("1000000000000000000000000", LLONG_MIN, LLONG_MAX, 0); + test("-1000000000000000000000000", LLONG_MIN, LLONG_MAX, 0); + test("-2", 10, -1, 0); + test("-2", -10, -1, 1); + test("-20", -10, -1, 0); + test("20", -10, -1, 0); + + return (fail); +} + diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/rmd160.c b/crypto/external/bsd/openssh/dist/openbsd-compat/rmd160.c new file mode 100644 index 000000000..e915141a5 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/rmd160.c @@ -0,0 +1,378 @@ +/* + * 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. + */ +/* + * Preneel, Bosselaers, Dobbertin, "The Cryptographic Hash Function RIPEMD-160", + * RSA Laboratories, CryptoBytes, Volume 3, Number 2, Autumn 1997, + * ftp://ftp.rsasecurity.com/pub/cryptobytes/crypto3n2.pdf + */ + +#include "includes.h" + +#ifndef WITH_OPENSSL + +#include +#ifdef HAVE_ENDIAN_H +#include +#endif +#include +#include + +#define PUT_64BIT_LE(cp, value) do { \ + (cp)[7] = (value) >> 56; \ + (cp)[6] = (value) >> 48; \ + (cp)[5] = (value) >> 40; \ + (cp)[4] = (value) >> 32; \ + (cp)[3] = (value) >> 24; \ + (cp)[2] = (value) >> 16; \ + (cp)[1] = (value) >> 8; \ + (cp)[0] = (value); } while (0) + +#define PUT_32BIT_LE(cp, value) do { \ + (cp)[3] = (value) >> 24; \ + (cp)[2] = (value) >> 16; \ + (cp)[1] = (value) >> 8; \ + (cp)[0] = (value); } while (0) + +#define H0 0x67452301U +#define H1 0xEFCDAB89U +#define H2 0x98BADCFEU +#define H3 0x10325476U +#define H4 0xC3D2E1F0U + +#define K0 0x00000000U +#define K1 0x5A827999U +#define K2 0x6ED9EBA1U +#define K3 0x8F1BBCDCU +#define K4 0xA953FD4EU + +#define KK0 0x50A28BE6U +#define KK1 0x5C4DD124U +#define KK2 0x6D703EF3U +#define KK3 0x7A6D76E9U +#define KK4 0x00000000U + +/* rotate x left n bits. */ +#define ROL(n, x) (((x) << (n)) | ((x) >> (32-(n)))) + +#define F0(x, y, z) ((x) ^ (y) ^ (z)) +#define F1(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define F2(x, y, z) (((x) | (~y)) ^ (z)) +#define F3(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define F4(x, y, z) ((x) ^ ((y) | (~z))) + +#define R(a, b, c, d, e, Fj, Kj, sj, rj) \ + do { \ + a = ROL(sj, a + Fj(b,c,d) + X(rj) + Kj) + e; \ + c = ROL(10, c); \ + } while(0) + +#define X(i) x[i] + +static u_int8_t PADDING[RMD160_BLOCK_LENGTH] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +void +RMD160Init(RMD160_CTX *ctx) +{ + ctx->count = 0; + ctx->state[0] = H0; + ctx->state[1] = H1; + ctx->state[2] = H2; + ctx->state[3] = H3; + ctx->state[4] = H4; +} + +void +RMD160Update(RMD160_CTX *ctx, const u_int8_t *input, size_t len) +{ + size_t have, off, need; + + have = (ctx->count / 8) % RMD160_BLOCK_LENGTH; + need = RMD160_BLOCK_LENGTH - have; + ctx->count += 8 * len; + off = 0; + + if (len >= need) { + if (have) { + memcpy(ctx->buffer + have, input, need); + RMD160Transform(ctx->state, ctx->buffer); + off = need; + have = 0; + } + /* now the buffer is empty */ + while (off + RMD160_BLOCK_LENGTH <= len) { + RMD160Transform(ctx->state, input+off); + off += RMD160_BLOCK_LENGTH; + } + } + if (off < len) + memcpy(ctx->buffer + have, input+off, len-off); +} + +void +RMD160Pad(RMD160_CTX *ctx) +{ + u_int8_t size[8]; + size_t padlen; + + PUT_64BIT_LE(size, ctx->count); + + /* + * pad to RMD160_BLOCK_LENGTH byte blocks, at least one byte from + * PADDING plus 8 bytes for the size + */ + padlen = RMD160_BLOCK_LENGTH - ((ctx->count / 8) % RMD160_BLOCK_LENGTH); + if (padlen < 1 + 8) + padlen += RMD160_BLOCK_LENGTH; + RMD160Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */ + RMD160Update(ctx, size, 8); +} + +void +RMD160Final(u_int8_t digest[RMD160_DIGEST_LENGTH], RMD160_CTX *ctx) +{ + int i; + + RMD160Pad(ctx); + for (i = 0; i < 5; i++) + PUT_32BIT_LE(digest + i*4, ctx->state[i]); + memset(ctx, 0, sizeof (*ctx)); +} + +void +RMD160Transform(u_int32_t state[5], const u_int8_t block[RMD160_BLOCK_LENGTH]) +{ + u_int32_t a, b, c, d, e, aa, bb, cc, dd, ee, t, x[16]; + +#if BYTE_ORDER == LITTLE_ENDIAN + memcpy(x, block, RMD160_BLOCK_LENGTH); +#else + int i; + + for (i = 0; i < 16; i++) + x[i] = (u_int32_t)( + (u_int32_t)(block[i*4 + 0]) | + (u_int32_t)(block[i*4 + 1]) << 8 | + (u_int32_t)(block[i*4 + 2]) << 16 | + (u_int32_t)(block[i*4 + 3]) << 24); +#endif + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + + /* Round 1 */ + R(a, b, c, d, e, F0, K0, 11, 0); + R(e, a, b, c, d, F0, K0, 14, 1); + R(d, e, a, b, c, F0, K0, 15, 2); + R(c, d, e, a, b, F0, K0, 12, 3); + R(b, c, d, e, a, F0, K0, 5, 4); + R(a, b, c, d, e, F0, K0, 8, 5); + R(e, a, b, c, d, F0, K0, 7, 6); + R(d, e, a, b, c, F0, K0, 9, 7); + R(c, d, e, a, b, F0, K0, 11, 8); + R(b, c, d, e, a, F0, K0, 13, 9); + R(a, b, c, d, e, F0, K0, 14, 10); + R(e, a, b, c, d, F0, K0, 15, 11); + R(d, e, a, b, c, F0, K0, 6, 12); + R(c, d, e, a, b, F0, K0, 7, 13); + R(b, c, d, e, a, F0, K0, 9, 14); + R(a, b, c, d, e, F0, K0, 8, 15); /* #15 */ + /* Round 2 */ + R(e, a, b, c, d, F1, K1, 7, 7); + R(d, e, a, b, c, F1, K1, 6, 4); + R(c, d, e, a, b, F1, K1, 8, 13); + R(b, c, d, e, a, F1, K1, 13, 1); + R(a, b, c, d, e, F1, K1, 11, 10); + R(e, a, b, c, d, F1, K1, 9, 6); + R(d, e, a, b, c, F1, K1, 7, 15); + R(c, d, e, a, b, F1, K1, 15, 3); + R(b, c, d, e, a, F1, K1, 7, 12); + R(a, b, c, d, e, F1, K1, 12, 0); + R(e, a, b, c, d, F1, K1, 15, 9); + R(d, e, a, b, c, F1, K1, 9, 5); + R(c, d, e, a, b, F1, K1, 11, 2); + R(b, c, d, e, a, F1, K1, 7, 14); + R(a, b, c, d, e, F1, K1, 13, 11); + R(e, a, b, c, d, F1, K1, 12, 8); /* #31 */ + /* Round 3 */ + R(d, e, a, b, c, F2, K2, 11, 3); + R(c, d, e, a, b, F2, K2, 13, 10); + R(b, c, d, e, a, F2, K2, 6, 14); + R(a, b, c, d, e, F2, K2, 7, 4); + R(e, a, b, c, d, F2, K2, 14, 9); + R(d, e, a, b, c, F2, K2, 9, 15); + R(c, d, e, a, b, F2, K2, 13, 8); + R(b, c, d, e, a, F2, K2, 15, 1); + R(a, b, c, d, e, F2, K2, 14, 2); + R(e, a, b, c, d, F2, K2, 8, 7); + R(d, e, a, b, c, F2, K2, 13, 0); + R(c, d, e, a, b, F2, K2, 6, 6); + R(b, c, d, e, a, F2, K2, 5, 13); + R(a, b, c, d, e, F2, K2, 12, 11); + R(e, a, b, c, d, F2, K2, 7, 5); + R(d, e, a, b, c, F2, K2, 5, 12); /* #47 */ + /* Round 4 */ + R(c, d, e, a, b, F3, K3, 11, 1); + R(b, c, d, e, a, F3, K3, 12, 9); + R(a, b, c, d, e, F3, K3, 14, 11); + R(e, a, b, c, d, F3, K3, 15, 10); + R(d, e, a, b, c, F3, K3, 14, 0); + R(c, d, e, a, b, F3, K3, 15, 8); + R(b, c, d, e, a, F3, K3, 9, 12); + R(a, b, c, d, e, F3, K3, 8, 4); + R(e, a, b, c, d, F3, K3, 9, 13); + R(d, e, a, b, c, F3, K3, 14, 3); + R(c, d, e, a, b, F3, K3, 5, 7); + R(b, c, d, e, a, F3, K3, 6, 15); + R(a, b, c, d, e, F3, K3, 8, 14); + R(e, a, b, c, d, F3, K3, 6, 5); + R(d, e, a, b, c, F3, K3, 5, 6); + R(c, d, e, a, b, F3, K3, 12, 2); /* #63 */ + /* Round 5 */ + R(b, c, d, e, a, F4, K4, 9, 4); + R(a, b, c, d, e, F4, K4, 15, 0); + R(e, a, b, c, d, F4, K4, 5, 5); + R(d, e, a, b, c, F4, K4, 11, 9); + R(c, d, e, a, b, F4, K4, 6, 7); + R(b, c, d, e, a, F4, K4, 8, 12); + R(a, b, c, d, e, F4, K4, 13, 2); + R(e, a, b, c, d, F4, K4, 12, 10); + R(d, e, a, b, c, F4, K4, 5, 14); + R(c, d, e, a, b, F4, K4, 12, 1); + R(b, c, d, e, a, F4, K4, 13, 3); + R(a, b, c, d, e, F4, K4, 14, 8); + R(e, a, b, c, d, F4, K4, 11, 11); + R(d, e, a, b, c, F4, K4, 8, 6); + R(c, d, e, a, b, F4, K4, 5, 15); + R(b, c, d, e, a, F4, K4, 6, 13); /* #79 */ + + aa = a ; bb = b; cc = c; dd = d; ee = e; + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + + /* Parallel round 1 */ + R(a, b, c, d, e, F4, KK0, 8, 5); + R(e, a, b, c, d, F4, KK0, 9, 14); + R(d, e, a, b, c, F4, KK0, 9, 7); + R(c, d, e, a, b, F4, KK0, 11, 0); + R(b, c, d, e, a, F4, KK0, 13, 9); + R(a, b, c, d, e, F4, KK0, 15, 2); + R(e, a, b, c, d, F4, KK0, 15, 11); + R(d, e, a, b, c, F4, KK0, 5, 4); + R(c, d, e, a, b, F4, KK0, 7, 13); + R(b, c, d, e, a, F4, KK0, 7, 6); + R(a, b, c, d, e, F4, KK0, 8, 15); + R(e, a, b, c, d, F4, KK0, 11, 8); + R(d, e, a, b, c, F4, KK0, 14, 1); + R(c, d, e, a, b, F4, KK0, 14, 10); + R(b, c, d, e, a, F4, KK0, 12, 3); + R(a, b, c, d, e, F4, KK0, 6, 12); /* #15 */ + /* Parallel round 2 */ + R(e, a, b, c, d, F3, KK1, 9, 6); + R(d, e, a, b, c, F3, KK1, 13, 11); + R(c, d, e, a, b, F3, KK1, 15, 3); + R(b, c, d, e, a, F3, KK1, 7, 7); + R(a, b, c, d, e, F3, KK1, 12, 0); + R(e, a, b, c, d, F3, KK1, 8, 13); + R(d, e, a, b, c, F3, KK1, 9, 5); + R(c, d, e, a, b, F3, KK1, 11, 10); + R(b, c, d, e, a, F3, KK1, 7, 14); + R(a, b, c, d, e, F3, KK1, 7, 15); + R(e, a, b, c, d, F3, KK1, 12, 8); + R(d, e, a, b, c, F3, KK1, 7, 12); + R(c, d, e, a, b, F3, KK1, 6, 4); + R(b, c, d, e, a, F3, KK1, 15, 9); + R(a, b, c, d, e, F3, KK1, 13, 1); + R(e, a, b, c, d, F3, KK1, 11, 2); /* #31 */ + /* Parallel round 3 */ + R(d, e, a, b, c, F2, KK2, 9, 15); + R(c, d, e, a, b, F2, KK2, 7, 5); + R(b, c, d, e, a, F2, KK2, 15, 1); + R(a, b, c, d, e, F2, KK2, 11, 3); + R(e, a, b, c, d, F2, KK2, 8, 7); + R(d, e, a, b, c, F2, KK2, 6, 14); + R(c, d, e, a, b, F2, KK2, 6, 6); + R(b, c, d, e, a, F2, KK2, 14, 9); + R(a, b, c, d, e, F2, KK2, 12, 11); + R(e, a, b, c, d, F2, KK2, 13, 8); + R(d, e, a, b, c, F2, KK2, 5, 12); + R(c, d, e, a, b, F2, KK2, 14, 2); + R(b, c, d, e, a, F2, KK2, 13, 10); + R(a, b, c, d, e, F2, KK2, 13, 0); + R(e, a, b, c, d, F2, KK2, 7, 4); + R(d, e, a, b, c, F2, KK2, 5, 13); /* #47 */ + /* Parallel round 4 */ + R(c, d, e, a, b, F1, KK3, 15, 8); + R(b, c, d, e, a, F1, KK3, 5, 6); + R(a, b, c, d, e, F1, KK3, 8, 4); + R(e, a, b, c, d, F1, KK3, 11, 1); + R(d, e, a, b, c, F1, KK3, 14, 3); + R(c, d, e, a, b, F1, KK3, 14, 11); + R(b, c, d, e, a, F1, KK3, 6, 15); + R(a, b, c, d, e, F1, KK3, 14, 0); + R(e, a, b, c, d, F1, KK3, 6, 5); + R(d, e, a, b, c, F1, KK3, 9, 12); + R(c, d, e, a, b, F1, KK3, 12, 2); + R(b, c, d, e, a, F1, KK3, 9, 13); + R(a, b, c, d, e, F1, KK3, 12, 9); + R(e, a, b, c, d, F1, KK3, 5, 7); + R(d, e, a, b, c, F1, KK3, 15, 10); + R(c, d, e, a, b, F1, KK3, 8, 14); /* #63 */ + /* Parallel round 5 */ + R(b, c, d, e, a, F0, KK4, 8, 12); + R(a, b, c, d, e, F0, KK4, 5, 15); + R(e, a, b, c, d, F0, KK4, 12, 10); + R(d, e, a, b, c, F0, KK4, 9, 4); + R(c, d, e, a, b, F0, KK4, 12, 1); + R(b, c, d, e, a, F0, KK4, 5, 5); + R(a, b, c, d, e, F0, KK4, 14, 8); + R(e, a, b, c, d, F0, KK4, 6, 7); + R(d, e, a, b, c, F0, KK4, 8, 6); + R(c, d, e, a, b, F0, KK4, 13, 2); + R(b, c, d, e, a, F0, KK4, 6, 13); + R(a, b, c, d, e, F0, KK4, 5, 14); + R(e, a, b, c, d, F0, KK4, 15, 0); + R(d, e, a, b, c, F0, KK4, 13, 3); + R(c, d, e, a, b, F0, KK4, 11, 9); + R(b, c, d, e, a, F0, KK4, 11, 11); /* #79 */ + + t = state[1] + cc + d; + state[1] = state[2] + dd + e; + state[2] = state[3] + ee + a; + state[3] = state[4] + aa + b; + state[4] = state[0] + bb + c; + state[0] = t; +} + +#endif /* !WITH_OPENSSL */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/rmd160.h b/crypto/external/bsd/openssh/dist/openbsd-compat/rmd160.h new file mode 100644 index 000000000..99c1dcdc0 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/rmd160.h @@ -0,0 +1,61 @@ +/* $OpenBSD: rmd160.h,v 1.17 2012/12/05 23:19:57 deraadt Exp $ */ +/* + * 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. + */ +#ifndef _RMD160_H +#define _RMD160_H + +#ifndef WITH_OPENSSL + +#define RMD160_BLOCK_LENGTH 64 +#define RMD160_DIGEST_LENGTH 20 +#define RMD160_DIGEST_STRING_LENGTH (RMD160_DIGEST_LENGTH * 2 + 1) + +/* RMD160 context. */ +typedef struct RMD160Context { + u_int32_t state[5]; /* state */ + u_int64_t count; /* number of bits, mod 2^64 */ + u_int8_t buffer[RMD160_BLOCK_LENGTH]; /* input buffer */ +} RMD160_CTX; + +void RMD160Init(RMD160_CTX *); +void RMD160Transform(u_int32_t [5], const u_int8_t [RMD160_BLOCK_LENGTH]) + __attribute__((__bounded__(__minbytes__,1,5))) + __attribute__((__bounded__(__minbytes__,2,RMD160_BLOCK_LENGTH))); +void RMD160Update(RMD160_CTX *, const u_int8_t *, size_t) + __attribute__((__bounded__(__string__,2,3))); +void RMD160Pad(RMD160_CTX *); +void RMD160Final(u_int8_t [RMD160_DIGEST_LENGTH], RMD160_CTX *) + __attribute__((__bounded__(__minbytes__,1,RMD160_DIGEST_LENGTH))); +char *RMD160End(RMD160_CTX *, char *) + __attribute__((__bounded__(__minbytes__,2,RMD160_DIGEST_STRING_LENGTH))); +char *RMD160File(const char *, char *) + __attribute__((__bounded__(__minbytes__,2,RMD160_DIGEST_STRING_LENGTH))); +char *RMD160FileChunk(const char *, char *, off_t, off_t) + __attribute__((__bounded__(__minbytes__,2,RMD160_DIGEST_STRING_LENGTH))); +char *RMD160Data(const u_int8_t *, size_t, char *) + __attribute__((__bounded__(__string__,1,2))) + __attribute__((__bounded__(__minbytes__,3,RMD160_DIGEST_STRING_LENGTH))); + +#endif /* !WITH_OPENSSL */ +#endif /* _RMD160_H */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/rresvport.c b/crypto/external/bsd/openssh/dist/openbsd-compat/rresvport.c new file mode 100644 index 000000000..1cd61e58d --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/rresvport.c @@ -0,0 +1,108 @@ +/* $OpenBSD: rresvport.c,v 1.9 2005/11/10 10:00:17 espie Exp $ */ +/* + * Copyright (c) 1995, 1996, 1998 Theo de Raadt. All rights reserved. + * Copyright (c) 1983, 1993, 1994 + * 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. 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. + */ + +/* OPENBSD ORIGINAL: lib/libc/net/rresvport.c */ + +#include "includes.h" + +#ifndef HAVE_RRESVPORT_AF + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#if 0 +int +rresvport(int *alport) +{ + return rresvport_af(alport, AF_INET); +} +#endif + +int +rresvport_af(int *alport, sa_family_t af) +{ + struct sockaddr_storage ss; + struct sockaddr *sa; + u_int16_t *portp; + int s; + socklen_t salen; + + memset(&ss, '\0', sizeof ss); + sa = (struct sockaddr *)&ss; + + switch (af) { + case AF_INET: + salen = sizeof(struct sockaddr_in); + portp = &((struct sockaddr_in *)sa)->sin_port; + break; + case AF_INET6: + salen = sizeof(struct sockaddr_in6); + portp = &((struct sockaddr_in6 *)sa)->sin6_port; + break; + default: + errno = EPFNOSUPPORT; + return (-1); + } + sa->sa_family = af; + + s = socket(af, SOCK_STREAM, 0); + if (s < 0) + return (-1); + + *portp = htons(*alport); + if (*alport < IPPORT_RESERVED - 1) { + if (bind(s, sa, salen) >= 0) + return (s); + if (errno != EADDRINUSE) { + (void)close(s); + return (-1); + } + } + + *portp = 0; + sa->sa_family = af; + if (bindresvport_sa(s, sa) == -1) { + (void)close(s); + return (-1); + } + *alport = ntohs(*portp); + return (s); +} + +#endif /* HAVE_RRESVPORT_AF */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/setenv.c b/crypto/external/bsd/openssh/dist/openbsd-compat/setenv.c new file mode 100644 index 000000000..373b701d9 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/setenv.c @@ -0,0 +1,226 @@ +/* $OpenBSD: setenv.c,v 1.13 2010/08/23 22:31:50 millert Exp $ */ +/* + * Copyright (c) 1987 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. 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. + */ + +/* OPENBSD ORIGINAL: lib/libc/stdlib/setenv.c */ + +#include "includes.h" + +#if !defined(HAVE_SETENV) || !defined(HAVE_UNSETENV) + +#include +#include +#include + +extern char **environ; +static char **lastenv; /* last value of environ */ + +/* OpenSSH Portable: __findenv is from getenv.c rev 1.8, made static */ +/* + * __findenv -- + * Returns pointer to value associated with name, if any, else NULL. + * Starts searching within the environmental array at offset. + * Sets offset to be the offset of the name/value combination in the + * environmental array, for use by putenv(3), setenv(3) and unsetenv(3). + * Explicitly removes '=' in argument name. + * + * This routine *should* be a static; don't use it. + */ +static char * +__findenv(const char *name, int len, int *offset) +{ + extern char **environ; + int i; + const char *np; + char **p, *cp; + + if (name == NULL || environ == NULL) + return (NULL); + for (p = environ + *offset; (cp = *p) != NULL; ++p) { + for (np = name, i = len; i && *cp; i--) + if (*cp++ != *np++) + break; + if (i == 0 && *cp++ == '=') { + *offset = p - environ; + return (cp); + } + } + return (NULL); +} + +#if 0 /* nothing uses putenv */ +/* + * putenv -- + * Add a name=value string directly to the environmental, replacing + * any current value. + */ +int +putenv(char *str) +{ + char **P, *cp; + size_t cnt; + int offset = 0; + + for (cp = str; *cp && *cp != '='; ++cp) + ; + if (*cp != '=') { + errno = EINVAL; + return (-1); /* missing `=' in string */ + } + + if (__findenv(str, (int)(cp - str), &offset) != NULL) { + environ[offset++] = str; + /* could be set multiple times */ + while (__findenv(str, (int)(cp - str), &offset)) { + for (P = &environ[offset];; ++P) + if (!(*P = *(P + 1))) + break; + } + return (0); + } + + /* create new slot for string */ + for (P = environ; *P != NULL; P++) + ; + cnt = P - environ; + P = (char **)realloc(lastenv, sizeof(char *) * (cnt + 2)); + if (!P) + return (-1); + if (lastenv != environ) + memcpy(P, environ, cnt * sizeof(char *)); + lastenv = environ = P; + environ[cnt] = str; + environ[cnt + 1] = NULL; + return (0); +} + +#endif + +#ifndef HAVE_SETENV +/* + * setenv -- + * Set the value of the environmental variable "name" to be + * "value". If rewrite is set, replace any current value. + */ +int +setenv(const char *name, const char *value, int rewrite) +{ + char *C, **P; + const char *np; + int l_value, offset = 0; + + for (np = name; *np && *np != '='; ++np) + ; +#ifdef notyet + if (*np) { + errno = EINVAL; + return (-1); /* has `=' in name */ + } +#endif + + l_value = strlen(value); + if ((C = __findenv(name, (int)(np - name), &offset)) != NULL) { + int tmpoff = offset + 1; + if (!rewrite) + return (0); +#if 0 /* XXX - existing entry may not be writable */ + if (strlen(C) >= l_value) { /* old larger; copy over */ + while ((*C++ = *value++)) + ; + return (0); + } +#endif + /* could be set multiple times */ + while (__findenv(name, (int)(np - name), &tmpoff)) { + for (P = &environ[tmpoff];; ++P) + if (!(*P = *(P + 1))) + break; + } + } else { /* create new slot */ + size_t cnt; + + for (P = environ; *P != NULL; P++) + ; + cnt = P - environ; + P = (char **)realloc(lastenv, sizeof(char *) * (cnt + 2)); + if (!P) + return (-1); + if (lastenv != environ) + memcpy(P, environ, cnt * sizeof(char *)); + lastenv = environ = P; + offset = cnt; + environ[cnt + 1] = NULL; + } + if (!(environ[offset] = /* name + `=' + value */ + malloc((size_t)((int)(np - name) + l_value + 2)))) + return (-1); + for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) + ; + for (*C++ = '='; (*C++ = *value++); ) + ; + return (0); +} + +#endif /* HAVE_SETENV */ + +#ifndef HAVE_UNSETENV +/* + * unsetenv(name) -- + * Delete environmental variable "name". + */ +int +unsetenv(const char *name) +{ + char **P; + const char *np; + int offset = 0; + + if (!name || !*name) { + errno = EINVAL; + return (-1); + } + for (np = name; *np && *np != '='; ++np) + ; + if (*np) { + errno = EINVAL; + return (-1); /* has `=' in name */ + } + + /* could be set multiple times */ + while (__findenv(name, (int)(np - name), &offset)) { + for (P = &environ[offset];; ++P) + if (!(*P = *(P + 1))) + break; + } + return (0); +} +#endif /* HAVE_UNSETENV */ + +#endif /* !defined(HAVE_SETENV) || !defined(HAVE_UNSETENV) */ + diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/setproctitle.c b/crypto/external/bsd/openssh/dist/openbsd-compat/setproctitle.c new file mode 100644 index 000000000..9f7ca14c2 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/setproctitle.c @@ -0,0 +1,169 @@ +/* Based on conf.c from UCB sendmail 8.8.8 */ + +/* + * Copyright 2003 Damien Miller + * Copyright (c) 1983, 1995-1997 Eric P. Allman + * Copyright (c) 1988, 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. 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" + +#ifndef HAVE_SETPROCTITLE + +#include +#include +#include +#ifdef HAVE_SYS_PSTAT_H +#include +#endif +#include + +#include + +#define SPT_NONE 0 /* don't use it at all */ +#define SPT_PSTAT 1 /* use pstat(PSTAT_SETCMD, ...) */ +#define SPT_REUSEARGV 2 /* cover argv with title information */ + +#ifndef SPT_TYPE +# define SPT_TYPE SPT_NONE +#endif + +#ifndef SPT_PADCHAR +# define SPT_PADCHAR '\0' +#endif + +#if SPT_TYPE == SPT_REUSEARGV +static char *argv_start = NULL; +static size_t argv_env_len = 0; +#endif + +#endif /* HAVE_SETPROCTITLE */ + +void +compat_init_setproctitle(int argc, char *argv[]) +{ +#if !defined(HAVE_SETPROCTITLE) && \ + defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV + extern char **environ; + char *lastargv = NULL; + char **envp = environ; + int i; + + /* + * NB: This assumes that argv has already been copied out of the + * way. This is true for sshd, but may not be true for other + * programs. Beware. + */ + + if (argc == 0 || argv[0] == NULL) + return; + + /* Fail if we can't allocate room for the new environment */ + for (i = 0; envp[i] != NULL; i++) + ; + if ((environ = calloc(i + 1, sizeof(*environ))) == NULL) { + environ = envp; /* put it back */ + return; + } + + /* + * Find the last argv string or environment variable within + * our process memory area. + */ + for (i = 0; i < argc; i++) { + if (lastargv == NULL || lastargv + 1 == argv[i]) + lastargv = argv[i] + strlen(argv[i]); + } + for (i = 0; envp[i] != NULL; i++) { + if (lastargv + 1 == envp[i]) + lastargv = envp[i] + strlen(envp[i]); + } + + argv[1] = NULL; + argv_start = argv[0]; + argv_env_len = lastargv - argv[0] - 1; + + /* + * Copy environment + * XXX - will truncate env on strdup fail + */ + for (i = 0; envp[i] != NULL; i++) + environ[i] = strdup(envp[i]); + environ[i] = NULL; +#endif /* SPT_REUSEARGV */ +} + +#ifndef HAVE_SETPROCTITLE +void +setproctitle(const char *fmt, ...) +{ +#if SPT_TYPE != SPT_NONE + va_list ap; + char buf[1024], ptitle[1024]; + size_t len; + int r; + extern char *__progname; +#if SPT_TYPE == SPT_PSTAT + union pstun pst; +#endif + +#if SPT_TYPE == SPT_REUSEARGV + if (argv_env_len <= 0) + return; +#endif + + strlcpy(buf, __progname, sizeof(buf)); + + r = -1; + va_start(ap, fmt); + if (fmt != NULL) { + len = strlcat(buf, ": ", sizeof(buf)); + if (len < sizeof(buf)) + r = vsnprintf(buf + len, sizeof(buf) - len , fmt, ap); + } + va_end(ap); + if (r == -1 || (size_t)r >= sizeof(buf) - len) + return; + strnvis(ptitle, buf, sizeof(ptitle), + VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL); + +#if SPT_TYPE == SPT_PSTAT + pst.pst_command = ptitle; + pstat(PSTAT_SETCMD, pst, strlen(ptitle), 0, 0); +#elif SPT_TYPE == SPT_REUSEARGV +/* debug("setproctitle: copy \"%s\" into len %d", + buf, argv_env_len); */ + len = strlcpy(argv_start, ptitle, argv_env_len); + for(; len < argv_env_len; len++) + argv_start[len] = SPT_PADCHAR; +#endif + +#endif /* SPT_NONE */ +} + +#endif /* HAVE_SETPROCTITLE */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/sha1.c b/crypto/external/bsd/openssh/dist/openbsd-compat/sha1.c new file mode 100644 index 000000000..4b5381f87 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/sha1.c @@ -0,0 +1,177 @@ +/* $OpenBSD: sha1.c,v 1.23 2014/01/08 06:14:57 tedu Exp $ */ + +/* + * SHA-1 in C + * By Steve Reid + * 100% Public Domain + * + * Test Vectors (from FIPS PUB 180-1) + * "abc" + * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D + * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 + * A million repetitions of "a" + * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F + */ + +#include "includes.h" + +#ifndef WITH_OPENSSL + +#include +#include + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* + * blk0() and blk() perform the initial expand. + * I got the idea of expanding during the round function from SSLeay + */ +#if BYTE_ORDER == LITTLE_ENDIAN +# define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ + |(rol(block->l[i],8)&0x00FF00FF)) +#else +# define blk0(i) block->l[i] +#endif +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ + ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* + * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 + */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + +typedef union { + u_int8_t c[64]; + u_int32_t l[16]; +} CHAR64LONG16; + +/* + * Hash a single 512-bit block. This is the core of the algorithm. + */ +void +SHA1Transform(u_int32_t state[5], const u_int8_t buffer[SHA1_BLOCK_LENGTH]) +{ + u_int32_t a, b, c, d, e; + u_int8_t workspace[SHA1_BLOCK_LENGTH]; + CHAR64LONG16 *block = (CHAR64LONG16 *)workspace; + + (void)memcpy(block, buffer, SHA1_BLOCK_LENGTH); + + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + + /* Wipe variables */ + a = b = c = d = e = 0; +} + + +/* + * SHA1Init - Initialize new context + */ +void +SHA1Init(SHA1_CTX *context) +{ + + /* SHA1 initialization constants */ + context->count = 0; + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; +} + + +/* + * Run your data through this. + */ +void +SHA1Update(SHA1_CTX *context, const u_int8_t *data, size_t len) +{ + size_t i, j; + + j = (size_t)((context->count >> 3) & 63); + context->count += (len << 3); + if ((j + len) > 63) { + (void)memcpy(&context->buffer[j], data, (i = 64-j)); + SHA1Transform(context->state, context->buffer); + for ( ; i + 63 < len; i += 64) + SHA1Transform(context->state, (u_int8_t *)&data[i]); + j = 0; + } else { + i = 0; + } + (void)memcpy(&context->buffer[j], &data[i], len - i); +} + + +/* + * Add padding and return the message digest. + */ +void +SHA1Pad(SHA1_CTX *context) +{ + u_int8_t finalcount[8]; + u_int i; + + for (i = 0; i < 8; i++) { + finalcount[i] = (u_int8_t)((context->count >> + ((7 - (i & 7)) * 8)) & 255); /* Endian independent */ + } + SHA1Update(context, (u_int8_t *)"\200", 1); + while ((context->count & 504) != 448) + SHA1Update(context, (u_int8_t *)"\0", 1); + SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ +} + +void +SHA1Final(u_int8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context) +{ + u_int i; + + SHA1Pad(context); + for (i = 0; i < SHA1_DIGEST_LENGTH; i++) { + digest[i] = (u_int8_t) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + memset(context, 0, sizeof(*context)); +} +#endif /* !WITH_OPENSSL */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/sha1.h b/crypto/external/bsd/openssh/dist/openbsd-compat/sha1.h new file mode 100644 index 000000000..327d94cd5 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/sha1.h @@ -0,0 +1,58 @@ +/* $OpenBSD: sha1.h,v 1.24 2012/12/05 23:19:57 deraadt Exp $ */ + +/* + * SHA-1 in C + * By Steve Reid + * 100% Public Domain + */ + +#ifndef _SHA1_H +#define _SHA1_H + +#ifndef WITH_OPENSSL + +#define SHA1_BLOCK_LENGTH 64 +#define SHA1_DIGEST_LENGTH 20 +#define SHA1_DIGEST_STRING_LENGTH (SHA1_DIGEST_LENGTH * 2 + 1) + +typedef struct { + u_int32_t state[5]; + u_int64_t count; + u_int8_t buffer[SHA1_BLOCK_LENGTH]; +} SHA1_CTX; + +void SHA1Init(SHA1_CTX *); +void SHA1Pad(SHA1_CTX *); +void SHA1Transform(u_int32_t [5], const u_int8_t [SHA1_BLOCK_LENGTH]) + __attribute__((__bounded__(__minbytes__,1,5))) + __attribute__((__bounded__(__minbytes__,2,SHA1_BLOCK_LENGTH))); +void SHA1Update(SHA1_CTX *, const u_int8_t *, size_t) + __attribute__((__bounded__(__string__,2,3))); +void SHA1Final(u_int8_t [SHA1_DIGEST_LENGTH], SHA1_CTX *) + __attribute__((__bounded__(__minbytes__,1,SHA1_DIGEST_LENGTH))); +char *SHA1End(SHA1_CTX *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA1_DIGEST_STRING_LENGTH))); +char *SHA1File(const char *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA1_DIGEST_STRING_LENGTH))); +char *SHA1FileChunk(const char *, char *, off_t, off_t) + __attribute__((__bounded__(__minbytes__,2,SHA1_DIGEST_STRING_LENGTH))); +char *SHA1Data(const u_int8_t *, size_t, char *) + __attribute__((__bounded__(__string__,1,2))) + __attribute__((__bounded__(__minbytes__,3,SHA1_DIGEST_STRING_LENGTH))); + +#define HTONDIGEST(x) do { \ + x[0] = htonl(x[0]); \ + x[1] = htonl(x[1]); \ + x[2] = htonl(x[2]); \ + x[3] = htonl(x[3]); \ + x[4] = htonl(x[4]); } while (0) + +#define NTOHDIGEST(x) do { \ + x[0] = ntohl(x[0]); \ + x[1] = ntohl(x[1]); \ + x[2] = ntohl(x[2]); \ + x[3] = ntohl(x[3]); \ + x[4] = ntohl(x[4]); } while (0) + +#endif /* !WITH_OPENSSL */ +#endif /* _SHA1_H */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/sha2.c b/crypto/external/bsd/openssh/dist/openbsd-compat/sha2.c new file mode 100644 index 000000000..737935d46 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/sha2.c @@ -0,0 +1,904 @@ +/* from OpenBSD: sha2.c,v 1.11 2005/08/08 08:05:35 espie Exp */ + +/* + * FILE: sha2.c + * AUTHOR: Aaron D. Gifford + * + * Copyright (c) 2000-2001, Aaron D. Gifford + * 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. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 OR CONTRIBUTOR(S) 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. + * + * $From: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $ + */ + +/* OPENBSD ORIGINAL: lib/libc/hash/sha2.c */ + +#include "includes.h" + +#ifdef WITH_OPENSSL +# include +# if !defined(HAVE_EVP_SHA256) && (OPENSSL_VERSION_NUMBER >= 0x00907000L) +# define _NEED_SHA2 1 +# endif +#else +# define _NEED_SHA2 1 +#endif + +#if defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) + +#include + +/* + * UNROLLED TRANSFORM LOOP NOTE: + * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform + * loop version for the hash transform rounds (defined using macros + * later in this file). Either define on the command line, for example: + * + * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c + * + * or define below: + * + * #define SHA2_UNROLL_TRANSFORM + * + */ + +/*** SHA-256/384/512 Machine Architecture Definitions *****************/ +/* + * BYTE_ORDER NOTE: + * + * Please make sure that your system defines BYTE_ORDER. If your + * architecture is little-endian, make sure it also defines + * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are + * equivilent. + * + * If your system does not define the above, then you can do so by + * hand like this: + * + * #define LITTLE_ENDIAN 1234 + * #define BIG_ENDIAN 4321 + * + * And for little-endian machines, add: + * + * #define BYTE_ORDER LITTLE_ENDIAN + * + * Or for big-endian machines: + * + * #define BYTE_ORDER BIG_ENDIAN + * + * The FreeBSD machine this was written on defines BYTE_ORDER + * appropriately by including (which in turn includes + * where the appropriate definitions are actually + * made). + */ +#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) +#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN +#endif + + +/*** SHA-256/384/512 Various Length Definitions ***********************/ +/* NOTE: Most of these are in sha2.h */ +#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) +#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16) +#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) + +/*** ENDIAN SPECIFIC COPY MACROS **************************************/ +#define BE_8_TO_32(dst, cp) do { \ + (dst) = (u_int32_t)(cp)[3] | ((u_int32_t)(cp)[2] << 8) | \ + ((u_int32_t)(cp)[1] << 16) | ((u_int32_t)(cp)[0] << 24); \ +} while(0) + +#define BE_8_TO_64(dst, cp) do { \ + (dst) = (u_int64_t)(cp)[7] | ((u_int64_t)(cp)[6] << 8) | \ + ((u_int64_t)(cp)[5] << 16) | ((u_int64_t)(cp)[4] << 24) | \ + ((u_int64_t)(cp)[3] << 32) | ((u_int64_t)(cp)[2] << 40) | \ + ((u_int64_t)(cp)[1] << 48) | ((u_int64_t)(cp)[0] << 56); \ +} while (0) + +#define BE_64_TO_8(cp, src) do { \ + (cp)[0] = (src) >> 56; \ + (cp)[1] = (src) >> 48; \ + (cp)[2] = (src) >> 40; \ + (cp)[3] = (src) >> 32; \ + (cp)[4] = (src) >> 24; \ + (cp)[5] = (src) >> 16; \ + (cp)[6] = (src) >> 8; \ + (cp)[7] = (src); \ +} while (0) + +#define BE_32_TO_8(cp, src) do { \ + (cp)[0] = (src) >> 24; \ + (cp)[1] = (src) >> 16; \ + (cp)[2] = (src) >> 8; \ + (cp)[3] = (src); \ +} while (0) + +/* + * Macro for incrementally adding the unsigned 64-bit integer n to the + * unsigned 128-bit integer (represented using a two-element array of + * 64-bit words): + */ +#define ADDINC128(w,n) do { \ + (w)[0] += (u_int64_t)(n); \ + if ((w)[0] < (n)) { \ + (w)[1]++; \ + } \ +} while (0) + +/*** THE SIX LOGICAL FUNCTIONS ****************************************/ +/* + * Bit shifting and rotation (used by the six SHA-XYZ logical functions: + * + * NOTE: The naming of R and S appears backwards here (R is a SHIFT and + * S is a ROTATION) because the SHA-256/384/512 description document + * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this + * same "backwards" definition. + */ +/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ +#define R(b,x) ((x) >> (b)) +/* 32-bit Rotate-right (used in SHA-256): */ +#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) +/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ +#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) + +/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ +#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +/* Four of six logical functions used in SHA-256: */ +#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) +#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) +#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) +#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) + +/* Four of six logical functions used in SHA-384 and SHA-512: */ +#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) +#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) +#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) +#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) + + +/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ +/* Hash constant words K for SHA-256: */ +const static u_int32_t K256[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, + 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, + 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, + 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, + 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + +/* Initial hash value H for SHA-256: */ +const static u_int32_t sha256_initial_hash_value[8] = { + 0x6a09e667UL, + 0xbb67ae85UL, + 0x3c6ef372UL, + 0xa54ff53aUL, + 0x510e527fUL, + 0x9b05688cUL, + 0x1f83d9abUL, + 0x5be0cd19UL +}; + +/* Hash constant words K for SHA-384 and SHA-512: */ +const static u_int64_t K512[80] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, + 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, + 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, + 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, + 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, + 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, + 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, + 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, + 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, + 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, + 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, + 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, + 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, + 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, + 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, + 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, + 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, + 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, + 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, + 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, + 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, + 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, + 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, + 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, + 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, + 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, + 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, + 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, + 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, + 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, + 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, + 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, + 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, + 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL +}; + +/* Initial hash value H for SHA-384 */ +const static u_int64_t sha384_initial_hash_value[8] = { + 0xcbbb9d5dc1059ed8ULL, + 0x629a292a367cd507ULL, + 0x9159015a3070dd17ULL, + 0x152fecd8f70e5939ULL, + 0x67332667ffc00b31ULL, + 0x8eb44a8768581511ULL, + 0xdb0c2e0d64f98fa7ULL, + 0x47b5481dbefa4fa4ULL +}; + +/* Initial hash value H for SHA-512 */ +const static u_int64_t sha512_initial_hash_value[8] = { + 0x6a09e667f3bcc908ULL, + 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, + 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, + 0x5be0cd19137e2179ULL +}; + + +/*** SHA-256: *********************************************************/ +void +SHA256_Init(SHA256_CTX *context) +{ + if (context == NULL) + return; + memcpy(context->state, sha256_initial_hash_value, + sizeof(sha256_initial_hash_value)); + memset(context->buffer, 0, sizeof(context->buffer)); + context->bitcount = 0; +} + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-256 round macros: */ + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) do { \ + BE_8_TO_32(W256[j], data); \ + data += 4; \ + T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + W256[j]; \ + (d) += T1; \ + (h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c)); \ + j++; \ +} while(0) + +#define ROUND256(a,b,c,d,e,f,g,h) do { \ + s0 = W256[(j+1)&0x0f]; \ + s0 = sigma0_256(s0); \ + s1 = W256[(j+14)&0x0f]; \ + s1 = sigma1_256(s1); \ + T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + \ + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c)); \ + j++; \ +} while(0) + +void +SHA256_Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH]) +{ + u_int32_t a, b, c, d, e, f, g, h, s0, s1; + u_int32_t T1, W256[16]; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + + j = 0; + do { + /* Rounds 0 to 15 (unrolled): */ + ROUND256_0_TO_15(a,b,c,d,e,f,g,h); + ROUND256_0_TO_15(h,a,b,c,d,e,f,g); + ROUND256_0_TO_15(g,h,a,b,c,d,e,f); + ROUND256_0_TO_15(f,g,h,a,b,c,d,e); + ROUND256_0_TO_15(e,f,g,h,a,b,c,d); + ROUND256_0_TO_15(d,e,f,g,h,a,b,c); + ROUND256_0_TO_15(c,d,e,f,g,h,a,b); + ROUND256_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds up to 63: */ + do { + ROUND256(a,b,c,d,e,f,g,h); + ROUND256(h,a,b,c,d,e,f,g); + ROUND256(g,h,a,b,c,d,e,f); + ROUND256(f,g,h,a,b,c,d,e); + ROUND256(e,f,g,h,a,b,c,d); + ROUND256(d,e,f,g,h,a,b,c); + ROUND256(c,d,e,f,g,h,a,b); + ROUND256(b,c,d,e,f,g,h,a); + } while (j < 64); + + /* Compute the current intermediate hash value */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +void +SHA256_Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH]) +{ + u_int32_t a, b, c, d, e, f, g, h, s0, s1; + u_int32_t T1, T2, W256[16]; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + + j = 0; + do { + BE_8_TO_32(W256[j], data); + data += 4; + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W256[(j+1)&0x0f]; + s0 = sigma0_256(s0); + s1 = W256[(j+14)&0x0f]; + s1 = sigma1_256(s1); + + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 64); + + /* Compute the current intermediate hash value */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ + +void +SHA256_Update(SHA256_CTX *context, const u_int8_t *data, size_t len) +{ + size_t freespace, usedspace; + + /* Calling with no data is valid (we do nothing) */ + if (len == 0) + return; + + usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA256_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + memcpy(&context->buffer[usedspace], data, freespace); + context->bitcount += freespace << 3; + len -= freespace; + data += freespace; + SHA256_Transform(context->state, context->buffer); + } else { + /* The buffer is not yet full */ + memcpy(&context->buffer[usedspace], data, len); + context->bitcount += len << 3; + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA256_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + SHA256_Transform(context->state, data); + context->bitcount += SHA256_BLOCK_LENGTH << 3; + len -= SHA256_BLOCK_LENGTH; + data += SHA256_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + memcpy(context->buffer, data, len); + context->bitcount += len << 3; + } + /* Clean up: */ + usedspace = freespace = 0; +} + +void +SHA256_Pad(SHA256_CTX *context) +{ + unsigned int usedspace; + + usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->buffer[usedspace++] = 0x80; + + if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { + /* Set-up for the last transform: */ + memset(&context->buffer[usedspace], 0, + SHA256_SHORT_BLOCK_LENGTH - usedspace); + } else { + if (usedspace < SHA256_BLOCK_LENGTH) { + memset(&context->buffer[usedspace], 0, + SHA256_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + SHA256_Transform(context->state, context->buffer); + + /* Prepare for last transform: */ + memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH); + } + } else { + /* Set-up for the last transform: */ + memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } + /* Store the length of input data (in bits) in big endian format: */ + BE_64_TO_8(&context->buffer[SHA256_SHORT_BLOCK_LENGTH], + context->bitcount); + + /* Final transform: */ + SHA256_Transform(context->state, context->buffer); + + /* Clean up: */ + usedspace = 0; +} + +void +SHA256_Final(u_int8_t digest[SHA256_DIGEST_LENGTH], SHA256_CTX *context) +{ + SHA256_Pad(context); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != NULL) { +#if BYTE_ORDER == LITTLE_ENDIAN + int i; + + /* Convert TO host byte order */ + for (i = 0; i < 8; i++) + BE_32_TO_8(digest + i * 4, context->state[i]); +#else + memcpy(digest, context->state, SHA256_DIGEST_LENGTH); +#endif + memset(context, 0, sizeof(*context)); + } +} + + +/*** SHA-512: *********************************************************/ +void +SHA512_Init(SHA512_CTX *context) +{ + if (context == NULL) + return; + memcpy(context->state, sha512_initial_hash_value, + sizeof(sha512_initial_hash_value)); + memset(context->buffer, 0, sizeof(context->buffer)); + context->bitcount[0] = context->bitcount[1] = 0; +} + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-512 round macros: */ + +#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) do { \ + BE_8_TO_64(W512[j], data); \ + data += 8; \ + T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + W512[j]; \ + (d) += T1; \ + (h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c)); \ + j++; \ +} while(0) + + +#define ROUND512(a,b,c,d,e,f,g,h) do { \ + s0 = W512[(j+1)&0x0f]; \ + s0 = sigma0_512(s0); \ + s1 = W512[(j+14)&0x0f]; \ + s1 = sigma1_512(s1); \ + T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + \ + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c)); \ + j++; \ +} while(0) + +void +SHA512_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) +{ + u_int64_t a, b, c, d, e, f, g, h, s0, s1; + u_int64_t T1, W512[16]; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + + j = 0; + do { + /* Rounds 0 to 15 (unrolled): */ + ROUND512_0_TO_15(a,b,c,d,e,f,g,h); + ROUND512_0_TO_15(h,a,b,c,d,e,f,g); + ROUND512_0_TO_15(g,h,a,b,c,d,e,f); + ROUND512_0_TO_15(f,g,h,a,b,c,d,e); + ROUND512_0_TO_15(e,f,g,h,a,b,c,d); + ROUND512_0_TO_15(d,e,f,g,h,a,b,c); + ROUND512_0_TO_15(c,d,e,f,g,h,a,b); + ROUND512_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds up to 79: */ + do { + ROUND512(a,b,c,d,e,f,g,h); + ROUND512(h,a,b,c,d,e,f,g); + ROUND512(g,h,a,b,c,d,e,f); + ROUND512(f,g,h,a,b,c,d,e); + ROUND512(e,f,g,h,a,b,c,d); + ROUND512(d,e,f,g,h,a,b,c); + ROUND512(c,d,e,f,g,h,a,b); + ROUND512(b,c,d,e,f,g,h,a); + } while (j < 80); + + /* Compute the current intermediate hash value */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +void +SHA512_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) +{ + u_int64_t a, b, c, d, e, f, g, h, s0, s1; + u_int64_t T1, T2, W512[16]; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + + j = 0; + do { + BE_8_TO_64(W512[j], data); + data += 8; + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W512[(j+1)&0x0f]; + s0 = sigma0_512(s0); + s1 = W512[(j+14)&0x0f]; + s1 = sigma1_512(s1); + + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 80); + + /* Compute the current intermediate hash value */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ + +void +SHA512_Update(SHA512_CTX *context, const u_int8_t *data, size_t len) +{ + size_t freespace, usedspace; + + /* Calling with no data is valid (we do nothing) */ + if (len == 0) + return; + + usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA512_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + memcpy(&context->buffer[usedspace], data, freespace); + ADDINC128(context->bitcount, freespace << 3); + len -= freespace; + data += freespace; + SHA512_Transform(context->state, context->buffer); + } else { + /* The buffer is not yet full */ + memcpy(&context->buffer[usedspace], data, len); + ADDINC128(context->bitcount, len << 3); + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA512_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + SHA512_Transform(context->state, data); + ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); + len -= SHA512_BLOCK_LENGTH; + data += SHA512_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + memcpy(context->buffer, data, len); + ADDINC128(context->bitcount, len << 3); + } + /* Clean up: */ + usedspace = freespace = 0; +} + +void +SHA512_Pad(SHA512_CTX *context) +{ + unsigned int usedspace; + + usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->buffer[usedspace++] = 0x80; + + if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { + /* Set-up for the last transform: */ + memset(&context->buffer[usedspace], 0, SHA512_SHORT_BLOCK_LENGTH - usedspace); + } else { + if (usedspace < SHA512_BLOCK_LENGTH) { + memset(&context->buffer[usedspace], 0, SHA512_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + SHA512_Transform(context->state, context->buffer); + + /* And set-up for the last transform: */ + memset(context->buffer, 0, SHA512_BLOCK_LENGTH - 2); + } + } else { + /* Prepare for final transform: */ + memset(context->buffer, 0, SHA512_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } + /* Store the length of input data (in bits) in big endian format: */ + BE_64_TO_8(&context->buffer[SHA512_SHORT_BLOCK_LENGTH], + context->bitcount[1]); + BE_64_TO_8(&context->buffer[SHA512_SHORT_BLOCK_LENGTH + 8], + context->bitcount[0]); + + /* Final transform: */ + SHA512_Transform(context->state, context->buffer); + + /* Clean up: */ + usedspace = 0; +} + +void +SHA512_Final(u_int8_t digest[SHA512_DIGEST_LENGTH], SHA512_CTX *context) +{ + SHA512_Pad(context); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != NULL) { +#if BYTE_ORDER == LITTLE_ENDIAN + int i; + + /* Convert TO host byte order */ + for (i = 0; i < 8; i++) + BE_64_TO_8(digest + i * 8, context->state[i]); +#else + memcpy(digest, context->state, SHA512_DIGEST_LENGTH); +#endif + memset(context, 0, sizeof(*context)); + } +} + + +/*** SHA-384: *********************************************************/ +void +SHA384_Init(SHA384_CTX *context) +{ + if (context == NULL) + return; + memcpy(context->state, sha384_initial_hash_value, + sizeof(sha384_initial_hash_value)); + memset(context->buffer, 0, sizeof(context->buffer)); + context->bitcount[0] = context->bitcount[1] = 0; +} + +#if 0 +__weak_alias(SHA384_Transform, SHA512_Transform); +__weak_alias(SHA384_Update, SHA512_Update); +__weak_alias(SHA384_Pad, SHA512_Pad); +#endif + +void +SHA384_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) +{ + return SHA512_Transform(state, data); +} + +void +SHA384_Update(SHA512_CTX *context, const u_int8_t *data, size_t len) +{ + SHA512_Update(context, data, len); +} + +void +SHA384_Pad(SHA512_CTX *context) +{ + SHA512_Pad(context); +} + +void +SHA384_Final(u_int8_t digest[SHA384_DIGEST_LENGTH], SHA384_CTX *context) +{ + SHA384_Pad(context); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != NULL) { +#if BYTE_ORDER == LITTLE_ENDIAN + int i; + + /* Convert TO host byte order */ + for (i = 0; i < 6; i++) + BE_64_TO_8(digest + i * 8, context->state[i]); +#else + memcpy(digest, context->state, SHA384_DIGEST_LENGTH); +#endif + } + + /* Zero out state data */ + memset(context, 0, sizeof(*context)); +} + +#endif /* defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/sha2.h b/crypto/external/bsd/openssh/dist/openbsd-compat/sha2.h new file mode 100644 index 000000000..c8bfc3cd1 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/sha2.h @@ -0,0 +1,134 @@ +/* OpenBSD: sha2.h,v 1.6 2004/06/22 01:57:30 jfb Exp */ + +/* + * FILE: sha2.h + * AUTHOR: Aaron D. Gifford + * + * Copyright (c) 2000-2001, Aaron D. Gifford + * 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. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 OR CONTRIBUTOR(S) 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. + * + * $From: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $ + */ + +/* OPENBSD ORIGINAL: include/sha2.h */ + +#ifndef _SSHSHA2_H +#define _SSHSHA2_H + +#include "includes.h" + +#ifdef WITH_OPENSSL +# include +# if !defined(HAVE_EVP_SHA256) && (OPENSSL_VERSION_NUMBER >= 0x00907000L) +# define _NEED_SHA2 1 +# endif +#else +# define _NEED_SHA2 1 +#endif + +#if defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) + +/*** SHA-256/384/512 Various Length Definitions ***********************/ +#define SHA256_BLOCK_LENGTH 64 +#define SHA256_DIGEST_LENGTH 32 +#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) +#define SHA384_BLOCK_LENGTH 128 +#define SHA384_DIGEST_LENGTH 48 +#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) +#define SHA512_BLOCK_LENGTH 128 +#define SHA512_DIGEST_LENGTH 64 +#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) + + +/*** SHA-256/384/512 Context Structures *******************************/ +typedef struct _SHA256_CTX { + u_int32_t state[8]; + u_int64_t bitcount; + u_int8_t buffer[SHA256_BLOCK_LENGTH]; +} SHA256_CTX; +typedef struct _SHA512_CTX { + u_int64_t state[8]; + u_int64_t bitcount[2]; + u_int8_t buffer[SHA512_BLOCK_LENGTH]; +} SHA512_CTX; + +typedef SHA512_CTX SHA384_CTX; + +void SHA256_Init(SHA256_CTX *); +void SHA256_Transform(u_int32_t state[8], const u_int8_t [SHA256_BLOCK_LENGTH]); +void SHA256_Update(SHA256_CTX *, const u_int8_t *, size_t) + __attribute__((__bounded__(__string__,2,3))); +void SHA256_Pad(SHA256_CTX *); +void SHA256_Final(u_int8_t [SHA256_DIGEST_LENGTH], SHA256_CTX *) + __attribute__((__bounded__(__minbytes__,1,SHA256_DIGEST_LENGTH))); +char *SHA256_End(SHA256_CTX *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA256_DIGEST_STRING_LENGTH))); +char *SHA256_File(const char *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA256_DIGEST_STRING_LENGTH))); +char *SHA256_FileChunk(const char *, char *, off_t, off_t) + __attribute__((__bounded__(__minbytes__,2,SHA256_DIGEST_STRING_LENGTH))); +char *SHA256_Data(const u_int8_t *, size_t, char *) + __attribute__((__bounded__(__string__,1,2))) + __attribute__((__bounded__(__minbytes__,3,SHA256_DIGEST_STRING_LENGTH))); + +void SHA384_Init(SHA384_CTX *); +void SHA384_Transform(u_int64_t state[8], const u_int8_t [SHA384_BLOCK_LENGTH]); +void SHA384_Update(SHA384_CTX *, const u_int8_t *, size_t) + __attribute__((__bounded__(__string__,2,3))); +void SHA384_Pad(SHA384_CTX *); +void SHA384_Final(u_int8_t [SHA384_DIGEST_LENGTH], SHA384_CTX *) + __attribute__((__bounded__(__minbytes__,1,SHA384_DIGEST_LENGTH))); +char *SHA384_End(SHA384_CTX *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA384_DIGEST_STRING_LENGTH))); +char *SHA384_File(const char *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA384_DIGEST_STRING_LENGTH))); +char *SHA384_FileChunk(const char *, char *, off_t, off_t) + __attribute__((__bounded__(__minbytes__,2,SHA384_DIGEST_STRING_LENGTH))); +char *SHA384_Data(const u_int8_t *, size_t, char *) + __attribute__((__bounded__(__string__,1,2))) + __attribute__((__bounded__(__minbytes__,3,SHA384_DIGEST_STRING_LENGTH))); + +void SHA512_Init(SHA512_CTX *); +void SHA512_Transform(u_int64_t state[8], const u_int8_t [SHA512_BLOCK_LENGTH]); +void SHA512_Update(SHA512_CTX *, const u_int8_t *, size_t) + __attribute__((__bounded__(__string__,2,3))); +void SHA512_Pad(SHA512_CTX *); +void SHA512_Final(u_int8_t [SHA512_DIGEST_LENGTH], SHA512_CTX *) + __attribute__((__bounded__(__minbytes__,1,SHA512_DIGEST_LENGTH))); +char *SHA512_End(SHA512_CTX *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA512_DIGEST_STRING_LENGTH))); +char *SHA512_File(const char *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA512_DIGEST_STRING_LENGTH))); +char *SHA512_FileChunk(const char *, char *, off_t, off_t) + __attribute__((__bounded__(__minbytes__,2,SHA512_DIGEST_STRING_LENGTH))); +char *SHA512_Data(const u_int8_t *, size_t, char *) + __attribute__((__bounded__(__string__,1,2))) + __attribute__((__bounded__(__minbytes__,3,SHA512_DIGEST_STRING_LENGTH))); + +#endif /* defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) */ + +#endif /* _SSHSHA2_H */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/sigact.c b/crypto/external/bsd/openssh/dist/openbsd-compat/sigact.c new file mode 100644 index 000000000..d67845cf1 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/sigact.c @@ -0,0 +1,132 @@ +/* $OpenBSD: sigaction.c,v 1.4 2001/01/22 18:01:48 millert Exp $ */ + +/**************************************************************************** + * Copyright (c) 1998,2000 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Zeyd M. Ben-Halim 1992,1995 * + * and: Eric S. Raymond * + ****************************************************************************/ + +/* OPENBSD ORIGINAL: lib/libcurses/base/sigaction.c */ + +#include "includes.h" +#include +#include +#include "sigact.h" + +/* This file provides sigaction() emulation using sigvec() */ +/* Use only if this is non POSIX system */ + +#if !HAVE_SIGACTION && HAVE_SIGVEC + +int +sigaction(int sig, struct sigaction *sigact, struct sigaction *osigact) +{ + return sigvec(sig, sigact ? &sigact->sv : NULL, + osigact ? &osigact->sv : NULL); +} + +int +sigemptyset (sigset_t *mask) +{ + if (!mask) { + errno = EINVAL; + return -1; + } + *mask = 0; + return 0; +} + +int +sigprocmask (int mode, sigset_t *mask, sigset_t *omask) +{ + sigset_t current = sigsetmask(0); + + if (!mask) { + errno = EINVAL; + return -1; + } + + if (omask) + *omask = current; + + if (mode == SIG_BLOCK) + current |= *mask; + else if (mode == SIG_UNBLOCK) + current &= ~*mask; + else if (mode == SIG_SETMASK) + current = *mask; + + sigsetmask(current); + return 0; +} + +int +sigsuspend (sigset_t *mask) +{ + if (!mask) { + errno = EINVAL; + return -1; + } + return sigpause(*mask); +} + +int +sigdelset (sigset_t *mask, int sig) +{ + if (!mask) { + errno = EINVAL; + return -1; + } + *mask &= ~sigmask(sig); + return 0; +} + +int +sigaddset (sigset_t *mask, int sig) +{ + if (!mask) { + errno = EINVAL; + return -1; + } + *mask |= sigmask(sig); + return 0; +} + +int +sigismember (sigset_t *mask, int sig) +{ + if (!mask) { + errno = EINVAL; + return -1; + } + return (*mask & sigmask(sig)) != 0; +} + +#endif diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/sigact.h b/crypto/external/bsd/openssh/dist/openbsd-compat/sigact.h new file mode 100644 index 000000000..db96d0a5c --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/sigact.h @@ -0,0 +1,90 @@ +/* $OpenBSD: SigAction.h,v 1.3 2001/01/22 18:01:32 millert Exp $ */ + +/**************************************************************************** + * Copyright (c) 1998,2000 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Zeyd M. Ben-Halim 1992,1995 * + * and: Eric S. Raymond * + ****************************************************************************/ + +/* + * $From: SigAction.h,v 1.6 2000/12/10 02:36:10 tom Exp $ + * + * This file exists to handle non-POSIX systems which don't have , + * and usually no sigaction() nor + */ + +/* OPENBSD ORIGINAL: lib/libcurses/SigAction.h */ + +#ifndef _SIGACTION_H +#define _SIGACTION_H + +#if !defined(HAVE_SIGACTION) && defined(HAVE_SIGVEC) + +#undef SIG_BLOCK +#define SIG_BLOCK 00 + +#undef SIG_UNBLOCK +#define SIG_UNBLOCK 01 + +#undef SIG_SETMASK +#define SIG_SETMASK 02 + +/* + * is in the Linux 1.2.8 + gcc 2.7.0 configuration, + * and is useful for testing this header file. + */ +#if HAVE_BSD_SIGNAL_H +# include +#endif + +struct sigaction +{ + struct sigvec sv; +}; + +typedef unsigned long sigset_t; + +#undef sa_mask +#define sa_mask sv.sv_mask +#undef sa_handler +#define sa_handler sv.sv_handler +#undef sa_flags +#define sa_flags sv.sv_flags + +int sigaction(int sig, struct sigaction *sigact, struct sigaction *osigact); +int sigprocmask (int how, sigset_t *mask, sigset_t *omask); +int sigemptyset (sigset_t *mask); +int sigsuspend (sigset_t *mask); +int sigdelset (sigset_t *mask, int sig); +int sigaddset (sigset_t *mask, int sig); + +#endif /* !defined(HAVE_SIGACTION) && defined(HAVE_SIGVEC) */ + +#endif /* !defined(_SIGACTION_H) */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/strlcat.c b/crypto/external/bsd/openssh/dist/openbsd-compat/strlcat.c new file mode 100644 index 000000000..bcc1b61ad --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/strlcat.c @@ -0,0 +1,62 @@ +/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/string/strlcat.c */ + +#include "includes.h" +#ifndef HAVE_STRLCAT + +#include +#include + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +size_t +strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} + +#endif /* !HAVE_STRLCAT */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/strlcpy.c b/crypto/external/bsd/openssh/dist/openbsd-compat/strlcpy.c new file mode 100644 index 000000000..b4b1b6015 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/strlcpy.c @@ -0,0 +1,58 @@ +/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/string/strlcpy.c */ + +#include "includes.h" +#ifndef HAVE_STRLCPY + +#include +#include + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t +strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0) { + while (--n != 0) { + if ((*d++ = *s++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +#endif /* !HAVE_STRLCPY */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/strmode.c b/crypto/external/bsd/openssh/dist/openbsd-compat/strmode.c new file mode 100644 index 000000000..4a8161422 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/strmode.c @@ -0,0 +1,148 @@ +/* $OpenBSD: strmode.c,v 1.7 2005/08/08 08:05:37 espie 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. 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. + */ + +/* OPENBSD ORIGINAL: lib/libc/string/strmode.c */ + +#include "includes.h" +#ifndef HAVE_STRMODE + +#include +#include +#include + +/* XXX mode should be mode_t */ + +void +strmode(int mode, char *p) +{ + /* print type */ + switch (mode & S_IFMT) { + case S_IFDIR: /* directory */ + *p++ = 'd'; + break; + case S_IFCHR: /* character special */ + *p++ = 'c'; + break; + case S_IFBLK: /* block special */ + *p++ = 'b'; + break; + case S_IFREG: /* regular */ + *p++ = '-'; + break; + case S_IFLNK: /* symbolic link */ + *p++ = 'l'; + break; +#ifdef S_IFSOCK + case S_IFSOCK: /* socket */ + *p++ = 's'; + break; +#endif +#ifdef S_IFIFO + case S_IFIFO: /* fifo */ + *p++ = 'p'; + break; +#endif + default: /* unknown */ + *p++ = '?'; + break; + } + /* usr */ + if (mode & S_IRUSR) + *p++ = 'r'; + else + *p++ = '-'; + if (mode & S_IWUSR) + *p++ = 'w'; + else + *p++ = '-'; + switch (mode & (S_IXUSR | S_ISUID)) { + case 0: + *p++ = '-'; + break; + case S_IXUSR: + *p++ = 'x'; + break; + case S_ISUID: + *p++ = 'S'; + break; + case S_IXUSR | S_ISUID: + *p++ = 's'; + break; + } + /* group */ + if (mode & S_IRGRP) + *p++ = 'r'; + else + *p++ = '-'; + if (mode & S_IWGRP) + *p++ = 'w'; + else + *p++ = '-'; + switch (mode & (S_IXGRP | S_ISGID)) { + case 0: + *p++ = '-'; + break; + case S_IXGRP: + *p++ = 'x'; + break; + case S_ISGID: + *p++ = 'S'; + break; + case S_IXGRP | S_ISGID: + *p++ = 's'; + break; + } + /* other */ + if (mode & S_IROTH) + *p++ = 'r'; + else + *p++ = '-'; + if (mode & S_IWOTH) + *p++ = 'w'; + else + *p++ = '-'; + switch (mode & (S_IXOTH | S_ISVTX)) { + case 0: + *p++ = '-'; + break; + case S_IXOTH: + *p++ = 'x'; + break; + case S_ISVTX: + *p++ = 'T'; + break; + case S_IXOTH | S_ISVTX: + *p++ = 't'; + break; + } + *p++ = ' '; /* will be a '+' if ACL's implemented */ + *p = '\0'; +} +#endif diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/strnlen.c b/crypto/external/bsd/openssh/dist/openbsd-compat/strnlen.c new file mode 100644 index 000000000..93d515595 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/strnlen.c @@ -0,0 +1,37 @@ +/* $OpenBSD: strnlen.c,v 1.3 2010/06/02 12:58:12 millert Exp $ */ + +/* + * Copyright (c) 2010 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/string/strnlen.c */ + +#include "config.h" +#ifndef HAVE_STRNLEN +#include + +#include + +size_t +strnlen(const char *str, size_t maxlen) +{ + const char *cp; + + for (cp = str; maxlen != 0 && *cp != '\0'; cp++, maxlen--) + ; + + return (size_t)(cp - str); +} +#endif diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/strptime.c b/crypto/external/bsd/openssh/dist/openbsd-compat/strptime.c new file mode 100644 index 000000000..d8d83d907 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/strptime.c @@ -0,0 +1,401 @@ +/* $OpenBSD: strptime.c,v 1.12 2008/06/26 05:42:05 ray Exp $ */ +/* $NetBSD: strptime.c,v 1.12 1998/01/20 21:39:40 mycroft Exp $ */ + +/*- + * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Klaus Klein. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* OPENBSD ORIGINAL: lib/libc/time/strptime.c */ + +#include "includes.h" + +#ifndef HAVE_STRPTIME + +#define TM_YEAR_BASE 1900 /* from tzfile.h */ + +#include +#include +#include +#include + +/* #define _ctloc(x) (_CurrentTimeLocale->x) */ + +/* + * We do not implement alternate representations. However, we always + * check whether a given modifier is allowed for a certain conversion. + */ +#define _ALT_E 0x01 +#define _ALT_O 0x02 +#define _LEGAL_ALT(x) { if (alt_format & ~(x)) return (0); } + + +static int _conv_num(const unsigned char **, int *, int, int); +static char *_strptime(const char *, const char *, struct tm *, int); + + +char * +strptime(const char *buf, const char *fmt, struct tm *tm) +{ + return(_strptime(buf, fmt, tm, 1)); +} + +static char * +_strptime(const char *buf, const char *fmt, struct tm *tm, int initialize) +{ + unsigned char c; + const unsigned char *bp; + size_t len; + int alt_format, i; + static int century, relyear; + + if (initialize) { + century = TM_YEAR_BASE; + relyear = -1; + } + + bp = (unsigned char *)buf; + while ((c = *fmt) != '\0') { + /* Clear `alternate' modifier prior to new conversion. */ + alt_format = 0; + + /* Eat up white-space. */ + if (isspace(c)) { + while (isspace(*bp)) + bp++; + + fmt++; + continue; + } + + if ((c = *fmt++) != '%') + goto literal; + + +again: switch (c = *fmt++) { + case '%': /* "%%" is converted to "%". */ +literal: + if (c != *bp++) + return (NULL); + + break; + + /* + * "Alternative" modifiers. Just set the appropriate flag + * and start over again. + */ + case 'E': /* "%E?" alternative conversion modifier. */ + _LEGAL_ALT(0); + alt_format |= _ALT_E; + goto again; + + case 'O': /* "%O?" alternative conversion modifier. */ + _LEGAL_ALT(0); + alt_format |= _ALT_O; + goto again; + + /* + * "Complex" conversion rules, implemented through recursion. + */ +#if 0 + case 'c': /* Date and time, using the locale's format. */ + _LEGAL_ALT(_ALT_E); + if (!(bp = _strptime(bp, _ctloc(d_t_fmt), tm, 0))) + return (NULL); + break; +#endif + case 'D': /* The date as "%m/%d/%y". */ + _LEGAL_ALT(0); + if (!(bp = _strptime(bp, "%m/%d/%y", tm, 0))) + return (NULL); + break; + + case 'R': /* The time as "%H:%M". */ + _LEGAL_ALT(0); + if (!(bp = _strptime(bp, "%H:%M", tm, 0))) + return (NULL); + break; + + case 'r': /* The time as "%I:%M:%S %p". */ + _LEGAL_ALT(0); + if (!(bp = _strptime(bp, "%I:%M:%S %p", tm, 0))) + return (NULL); + break; + + case 'T': /* The time as "%H:%M:%S". */ + _LEGAL_ALT(0); + if (!(bp = _strptime(bp, "%H:%M:%S", tm, 0))) + return (NULL); + break; +#if 0 + case 'X': /* The time, using the locale's format. */ + _LEGAL_ALT(_ALT_E); + if (!(bp = _strptime(bp, _ctloc(t_fmt), tm, 0))) + return (NULL); + break; + + case 'x': /* The date, using the locale's format. */ + _LEGAL_ALT(_ALT_E); + if (!(bp = _strptime(bp, _ctloc(d_fmt), tm, 0))) + return (NULL); + break; +#endif + /* + * "Elementary" conversion rules. + */ +#if 0 + case 'A': /* The day of week, using the locale's form. */ + case 'a': + _LEGAL_ALT(0); + for (i = 0; i < 7; i++) { + /* Full name. */ + len = strlen(_ctloc(day[i])); + if (strncasecmp(_ctloc(day[i]), bp, len) == 0) + break; + + /* Abbreviated name. */ + len = strlen(_ctloc(abday[i])); + if (strncasecmp(_ctloc(abday[i]), bp, len) == 0) + break; + } + + /* Nothing matched. */ + if (i == 7) + return (NULL); + + tm->tm_wday = i; + bp += len; + break; + + case 'B': /* The month, using the locale's form. */ + case 'b': + case 'h': + _LEGAL_ALT(0); + for (i = 0; i < 12; i++) { + /* Full name. */ + len = strlen(_ctloc(mon[i])); + if (strncasecmp(_ctloc(mon[i]), bp, len) == 0) + break; + + /* Abbreviated name. */ + len = strlen(_ctloc(abmon[i])); + if (strncasecmp(_ctloc(abmon[i]), bp, len) == 0) + break; + } + + /* Nothing matched. */ + if (i == 12) + return (NULL); + + tm->tm_mon = i; + bp += len; + break; +#endif + + case 'C': /* The century number. */ + _LEGAL_ALT(_ALT_E); + if (!(_conv_num(&bp, &i, 0, 99))) + return (NULL); + + century = i * 100; + break; + + case 'd': /* The day of month. */ + case 'e': + _LEGAL_ALT(_ALT_O); + if (!(_conv_num(&bp, &tm->tm_mday, 1, 31))) + return (NULL); + break; + + case 'k': /* The hour (24-hour clock representation). */ + _LEGAL_ALT(0); + /* FALLTHROUGH */ + case 'H': + _LEGAL_ALT(_ALT_O); + if (!(_conv_num(&bp, &tm->tm_hour, 0, 23))) + return (NULL); + break; + + case 'l': /* The hour (12-hour clock representation). */ + _LEGAL_ALT(0); + /* FALLTHROUGH */ + case 'I': + _LEGAL_ALT(_ALT_O); + if (!(_conv_num(&bp, &tm->tm_hour, 1, 12))) + return (NULL); + break; + + case 'j': /* The day of year. */ + _LEGAL_ALT(0); + if (!(_conv_num(&bp, &tm->tm_yday, 1, 366))) + return (NULL); + tm->tm_yday--; + break; + + case 'M': /* The minute. */ + _LEGAL_ALT(_ALT_O); + if (!(_conv_num(&bp, &tm->tm_min, 0, 59))) + return (NULL); + break; + + case 'm': /* The month. */ + _LEGAL_ALT(_ALT_O); + if (!(_conv_num(&bp, &tm->tm_mon, 1, 12))) + return (NULL); + tm->tm_mon--; + break; + +#if 0 + case 'p': /* The locale's equivalent of AM/PM. */ + _LEGAL_ALT(0); + /* AM? */ + len = strlen(_ctloc(am_pm[0])); + if (strncasecmp(_ctloc(am_pm[0]), bp, len) == 0) { + if (tm->tm_hour > 12) /* i.e., 13:00 AM ?! */ + return (NULL); + else if (tm->tm_hour == 12) + tm->tm_hour = 0; + + bp += len; + break; + } + /* PM? */ + len = strlen(_ctloc(am_pm[1])); + if (strncasecmp(_ctloc(am_pm[1]), bp, len) == 0) { + if (tm->tm_hour > 12) /* i.e., 13:00 PM ?! */ + return (NULL); + else if (tm->tm_hour < 12) + tm->tm_hour += 12; + + bp += len; + break; + } + + /* Nothing matched. */ + return (NULL); +#endif + case 'S': /* The seconds. */ + _LEGAL_ALT(_ALT_O); + if (!(_conv_num(&bp, &tm->tm_sec, 0, 61))) + return (NULL); + break; + + case 'U': /* The week of year, beginning on sunday. */ + case 'W': /* The week of year, beginning on monday. */ + _LEGAL_ALT(_ALT_O); + /* + * XXX This is bogus, as we can not assume any valid + * information present in the tm structure at this + * point to calculate a real value, so just check the + * range for now. + */ + if (!(_conv_num(&bp, &i, 0, 53))) + return (NULL); + break; + + case 'w': /* The day of week, beginning on sunday. */ + _LEGAL_ALT(_ALT_O); + if (!(_conv_num(&bp, &tm->tm_wday, 0, 6))) + return (NULL); + break; + + case 'Y': /* The year. */ + _LEGAL_ALT(_ALT_E); + if (!(_conv_num(&bp, &i, 0, 9999))) + return (NULL); + + relyear = -1; + tm->tm_year = i - TM_YEAR_BASE; + break; + + case 'y': /* The year within the century (2 digits). */ + _LEGAL_ALT(_ALT_E | _ALT_O); + if (!(_conv_num(&bp, &relyear, 0, 99))) + return (NULL); + break; + + /* + * Miscellaneous conversions. + */ + case 'n': /* Any kind of white-space. */ + case 't': + _LEGAL_ALT(0); + while (isspace(*bp)) + bp++; + break; + + + default: /* Unknown/unsupported conversion. */ + return (NULL); + } + + + } + + /* + * We need to evaluate the two digit year spec (%y) + * last as we can get a century spec (%C) at any time. + */ + if (relyear != -1) { + if (century == TM_YEAR_BASE) { + if (relyear <= 68) + tm->tm_year = relyear + 2000 - TM_YEAR_BASE; + else + tm->tm_year = relyear + 1900 - TM_YEAR_BASE; + } else { + tm->tm_year = relyear + century - TM_YEAR_BASE; + } + } + + return ((char *)bp); +} + + +static int +_conv_num(const unsigned char **buf, int *dest, int llim, int ulim) +{ + int result = 0; + int rulim = ulim; + + if (**buf < '0' || **buf > '9') + return (0); + + /* we use rulim to break out of the loop when we run out of digits */ + do { + result *= 10; + result += *(*buf)++ - '0'; + rulim /= 10; + } while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9'); + + if (result < llim || result > ulim) + return (0); + + *dest = result; + return (1); +} + +#endif /* HAVE_STRPTIME */ + diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/strsep.c b/crypto/external/bsd/openssh/dist/openbsd-compat/strsep.c new file mode 100644 index 000000000..b36eb8fda --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/strsep.c @@ -0,0 +1,79 @@ +/* $OpenBSD: strsep.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */ + +/*- + * Copyright (c) 1990, 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. 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. + */ + +/* OPENBSD ORIGINAL: lib/libc/string/strsep.c */ + +#include "includes.h" + +#if !defined(HAVE_STRSEP) + +#include +#include + +/* + * Get next token from string *stringp, where tokens are possibly-empty + * strings separated by characters from delim. + * + * Writes NULs into the string at *stringp to end tokens. + * delim need not remain constant from call to call. + * On return, *stringp points past the last NUL written (if there might + * be further tokens), or is NULL (if there are definitely no more tokens). + * + * If *stringp is NULL, strsep returns NULL. + */ +char * +strsep(char **stringp, const char *delim) +{ + char *s; + const char *spanp; + int c, sc; + char *tok; + + if ((s = *stringp) == NULL) + return (NULL); + for (tok = s;;) { + c = *s++; + spanp = delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *stringp = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} + +#endif /* !defined(HAVE_STRSEP) */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/strtoll.c b/crypto/external/bsd/openssh/dist/openbsd-compat/strtoll.c new file mode 100644 index 000000000..f62930388 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/strtoll.c @@ -0,0 +1,148 @@ +/* $OpenBSD: strtoll.c,v 1.6 2005/11/10 10:00:17 espie Exp $ */ +/*- + * Copyright (c) 1992 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. 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. + */ + +/* OPENBSD ORIGINAL: lib/libc/stdlib/strtoll.c */ + +#include "includes.h" +#ifndef HAVE_STRTOLL + +#include + +#include +#include +#include +#include + +/* + * Convert a string to a long long. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +long long +strtoll(const char *nptr, char **endptr, int base) +{ + const char *s; + long long acc, cutoff; + int c; + int neg, any, cutlim; + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + s = nptr; + do { + c = (unsigned char) *s++; + } while (isspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for long longs is + * [-9223372036854775808..9223372036854775807] and the input base + * is 10, cutoff will be set to 922337203685477580 and cutlim to + * either 7 (neg==0) or 8 (neg==1), meaning that if we have + * accumulated a value > 922337203685477580, or equal but the + * next digit is > 7 (or 8), the number is too big, and we will + * return a range error. + * + * Set any if any `digits' consumed; make it negative to indicate + * overflow. + */ + cutoff = neg ? LLONG_MIN : LLONG_MAX; + cutlim = cutoff % base; + cutoff /= base; + if (neg) { + if (cutlim > 0) { + cutlim -= base; + cutoff += 1; + } + cutlim = -cutlim; + } + for (acc = 0, any = 0;; c = (unsigned char) *s++) { + if (isdigit(c)) + c -= '0'; + else if (isalpha(c)) + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0) + continue; + if (neg) { + if (acc < cutoff || (acc == cutoff && c > cutlim)) { + any = -1; + acc = LLONG_MIN; + errno = ERANGE; + } else { + any = 1; + acc *= base; + acc -= c; + } + } else { + if (acc > cutoff || (acc == cutoff && c > cutlim)) { + any = -1; + acc = LLONG_MAX; + errno = ERANGE; + } else { + any = 1; + acc *= base; + acc += c; + } + } + } + if (endptr != 0) + *endptr = (char *) (any ? s - 1 : nptr); + return (acc); +} +#endif /* HAVE_STRTOLL */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/strtonum.c b/crypto/external/bsd/openssh/dist/openbsd-compat/strtonum.c new file mode 100644 index 000000000..87f2f24b2 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/strtonum.c @@ -0,0 +1,72 @@ +/* $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $ */ + +/* + * Copyright (c) 2004 Ted Unangst and Todd Miller + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/stdlib/strtonum.c */ + +#include "includes.h" + +#ifndef HAVE_STRTONUM +#include +#include +#include + +#define INVALID 1 +#define TOOSMALL 2 +#define TOOLARGE 3 + +long long +strtonum(const char *numstr, long long minval, long long maxval, + const char **errstrp) +{ + long long ll = 0; + char *ep; + int error = 0; + struct errval { + const char *errstr; + int err; + } ev[4] = { + { NULL, 0 }, + { "invalid", EINVAL }, + { "too small", ERANGE }, + { "too large", ERANGE }, + }; + + ev[0].err = errno; + errno = 0; + if (minval > maxval) + error = INVALID; + else { + ll = strtoll(numstr, &ep, 10); + if (numstr == ep || *ep != '\0') + error = INVALID; + else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) + error = TOOSMALL; + else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) + error = TOOLARGE; + } + if (errstrp != NULL) + *errstrp = ev[error].errstr; + errno = ev[error].err; + if (error) + ll = 0; + + return (ll); +} + +#endif /* HAVE_STRTONUM */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/strtoul.c b/crypto/external/bsd/openssh/dist/openbsd-compat/strtoul.c new file mode 100644 index 000000000..8219c8391 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/strtoul.c @@ -0,0 +1,108 @@ +/* $OpenBSD: strtoul.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */ +/* + * Copyright (c) 1990 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. 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. + */ + +/* OPENBSD ORIGINAL: lib/libc/stdlib/strtoul.c */ + +#include "includes.h" +#ifndef HAVE_STRTOUL + +#include +#include +#include +#include + +/* + * Convert a string to an unsigned long integer. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +unsigned long +strtoul(const char *nptr, char **endptr, int base) +{ + const char *s; + unsigned long acc, cutoff; + int c; + int neg, any, cutlim; + + /* + * See strtol for comments as to the logic used. + */ + s = nptr; + do { + c = (unsigned char) *s++; + } while (isspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + + cutoff = ULONG_MAX / (unsigned long)base; + cutlim = ULONG_MAX % (unsigned long)base; + for (acc = 0, any = 0;; c = (unsigned char) *s++) { + if (isdigit(c)) + c -= '0'; + else if (isalpha(c)) + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0) + continue; + if (acc > cutoff || acc == cutoff && c > cutlim) { + any = -1; + acc = ULONG_MAX; + errno = ERANGE; + } else { + any = 1; + acc *= (unsigned long)base; + acc += c; + } + } + if (neg && any > 0) + acc = -acc; + if (endptr != 0) + *endptr = (char *) (any ? s - 1 : nptr); + return (acc); +} +#endif /* !HAVE_STRTOUL */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/strtoull.c b/crypto/external/bsd/openssh/dist/openbsd-compat/strtoull.c new file mode 100644 index 000000000..f7c818c52 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/strtoull.c @@ -0,0 +1,110 @@ +/* $OpenBSD: strtoull.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */ +/*- + * Copyright (c) 1992 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. 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. + */ + +/* OPENBSD ORIGINAL: lib/libc/stdlib/strtoull.c */ + +#include "includes.h" +#ifndef HAVE_STRTOULL + +#include + +#include +#include +#include +#include + +/* + * Convert a string to an unsigned long long. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +unsigned long long +strtoull(const char *nptr, char **endptr, int base) +{ + const char *s; + unsigned long long acc, cutoff; + int c; + int neg, any, cutlim; + + /* + * See strtoq for comments as to the logic used. + */ + s = nptr; + do { + c = (unsigned char) *s++; + } while (isspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + + cutoff = ULLONG_MAX / (unsigned long long)base; + cutlim = ULLONG_MAX % (unsigned long long)base; + for (acc = 0, any = 0;; c = (unsigned char) *s++) { + if (isdigit(c)) + c -= '0'; + else if (isalpha(c)) + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0) + continue; + if (acc > cutoff || (acc == cutoff && c > cutlim)) { + any = -1; + acc = ULLONG_MAX; + errno = ERANGE; + } else { + any = 1; + acc *= (unsigned long long)base; + acc += c; + } + } + if (neg && any > 0) + acc = -acc; + if (endptr != 0) + *endptr = (char *) (any ? s - 1 : nptr); + return (acc); +} +#endif /* !HAVE_STRTOULL */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/sys-queue.h b/crypto/external/bsd/openssh/dist/openbsd-compat/sys-queue.h new file mode 100644 index 000000000..28aaaa37a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/sys-queue.h @@ -0,0 +1,653 @@ +/* $OpenBSD: queue.h,v 1.36 2012/04/11 13:29:14 naddy Exp $ */ +/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ + +/* + * Copyright (c) 1991, 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. 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. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + */ + +/* OPENBSD ORIGINAL: sys/sys/queue.h */ + +#ifndef _FAKE_QUEUE_H_ +#define _FAKE_QUEUE_H_ + +/* + * Require for OS/X and other platforms that have old/broken/incomplete + * . + */ +#undef SLIST_HEAD +#undef SLIST_HEAD_INITIALIZER +#undef SLIST_ENTRY +#undef SLIST_FOREACH_PREVPTR +#undef SLIST_FIRST +#undef SLIST_END +#undef SLIST_EMPTY +#undef SLIST_NEXT +#undef SLIST_FOREACH +#undef SLIST_INIT +#undef SLIST_INSERT_AFTER +#undef SLIST_INSERT_HEAD +#undef SLIST_REMOVE_HEAD +#undef SLIST_REMOVE +#undef SLIST_REMOVE_NEXT +#undef LIST_HEAD +#undef LIST_HEAD_INITIALIZER +#undef LIST_ENTRY +#undef LIST_FIRST +#undef LIST_END +#undef LIST_EMPTY +#undef LIST_NEXT +#undef LIST_FOREACH +#undef LIST_INIT +#undef LIST_INSERT_AFTER +#undef LIST_INSERT_BEFORE +#undef LIST_INSERT_HEAD +#undef LIST_REMOVE +#undef LIST_REPLACE +#undef SIMPLEQ_HEAD +#undef SIMPLEQ_HEAD_INITIALIZER +#undef SIMPLEQ_ENTRY +#undef SIMPLEQ_FIRST +#undef SIMPLEQ_END +#undef SIMPLEQ_EMPTY +#undef SIMPLEQ_NEXT +#undef SIMPLEQ_FOREACH +#undef SIMPLEQ_INIT +#undef SIMPLEQ_INSERT_HEAD +#undef SIMPLEQ_INSERT_TAIL +#undef SIMPLEQ_INSERT_AFTER +#undef SIMPLEQ_REMOVE_HEAD +#undef TAILQ_HEAD +#undef TAILQ_HEAD_INITIALIZER +#undef TAILQ_ENTRY +#undef TAILQ_FIRST +#undef TAILQ_END +#undef TAILQ_NEXT +#undef TAILQ_LAST +#undef TAILQ_PREV +#undef TAILQ_EMPTY +#undef TAILQ_FOREACH +#undef TAILQ_FOREACH_REVERSE +#undef TAILQ_INIT +#undef TAILQ_INSERT_HEAD +#undef TAILQ_INSERT_TAIL +#undef TAILQ_INSERT_AFTER +#undef TAILQ_INSERT_BEFORE +#undef TAILQ_REMOVE +#undef TAILQ_REPLACE +#undef CIRCLEQ_HEAD +#undef CIRCLEQ_HEAD_INITIALIZER +#undef CIRCLEQ_ENTRY +#undef CIRCLEQ_FIRST +#undef CIRCLEQ_LAST +#undef CIRCLEQ_END +#undef CIRCLEQ_NEXT +#undef CIRCLEQ_PREV +#undef CIRCLEQ_EMPTY +#undef CIRCLEQ_FOREACH +#undef CIRCLEQ_FOREACH_REVERSE +#undef CIRCLEQ_INIT +#undef CIRCLEQ_INSERT_AFTER +#undef CIRCLEQ_INSERT_BEFORE +#undef CIRCLEQ_INSERT_HEAD +#undef CIRCLEQ_INSERT_TAIL +#undef CIRCLEQ_REMOVE +#undef CIRCLEQ_REPLACE + +/* + * This file defines five types of data structures: singly-linked lists, + * lists, simple queues, tail queues, and circular queues. + * + * + * A singly-linked list is headed by a single forward pointer. The elements + * are singly linked for minimum space and pointer manipulation overhead at + * the expense of O(n) removal for arbitrary elements. New elements can be + * added to the list after an existing element or at the head of the list. + * Elements being removed from the head of the list should use the explicit + * macro for this purpose for optimum efficiency. A singly-linked list may + * only be traversed in the forward direction. Singly-linked lists are ideal + * for applications with large datasets and few or no removals or for + * implementing a LIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * A simple queue is headed by a pair of pointers, one the head of the + * list and the other to the tail of the list. The elements are singly + * linked to save space, so elements can only be removed from the + * head of the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the + * list. A simple queue may only be traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * A circle queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the list. + * A circle queue may be traversed in either direction, but has a more + * complex end of list detection. + * + * For details on the use of these macros, see the queue(3) manual page. + */ + +#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC)) +#define _Q_INVALIDATE(a) (a) = ((void *)-1) +#else +#define _Q_INVALIDATE(a) +#endif + +/* + * Singly-linked List definitions. + */ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +/* + * Singly-linked List access methods. + */ +#define SLIST_FIRST(head) ((head)->slh_first) +#define SLIST_END(head) NULL +#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#define SLIST_FOREACH(var, head, field) \ + for((var) = SLIST_FIRST(head); \ + (var) != SLIST_END(head); \ + (var) = SLIST_NEXT(var, field)) + +#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = SLIST_FIRST(head); \ + (var) && ((tvar) = SLIST_NEXT(var, field), 1); \ + (var) = (tvar)) + +/* + * Singly-linked List functions. + */ +#define SLIST_INIT(head) { \ + SLIST_FIRST(head) = SLIST_END(head); \ +} + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + (elm)->field.sle_next = (slistelm)->field.sle_next; \ + (slistelm)->field.sle_next = (elm); \ +} while (0) + +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.sle_next = (head)->slh_first; \ + (head)->slh_first = (elm); \ +} while (0) + +#define SLIST_REMOVE_AFTER(elm, field) do { \ + (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \ +} while (0) + +#define SLIST_REMOVE_HEAD(head, field) do { \ + (head)->slh_first = (head)->slh_first->field.sle_next; \ +} while (0) + +#define SLIST_REMOVE(head, elm, type, field) do { \ + if ((head)->slh_first == (elm)) { \ + SLIST_REMOVE_HEAD((head), field); \ + } else { \ + struct type *curelm = (head)->slh_first; \ + \ + while (curelm->field.sle_next != (elm)) \ + curelm = curelm->field.sle_next; \ + curelm->field.sle_next = \ + curelm->field.sle_next->field.sle_next; \ + _Q_INVALIDATE((elm)->field.sle_next); \ + } \ +} while (0) + +/* + * List definitions. + */ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List access methods + */ +#define LIST_FIRST(head) ((head)->lh_first) +#define LIST_END(head) NULL +#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head)) +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + +#define LIST_FOREACH(var, head, field) \ + for((var) = LIST_FIRST(head); \ + (var)!= LIST_END(head); \ + (var) = LIST_NEXT(var, field)) + +#define LIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = LIST_FIRST(head); \ + (var) && ((tvar) = LIST_NEXT(var, field), 1); \ + (var) = (tvar)) + +/* + * List functions. + */ +#define LIST_INIT(head) do { \ + LIST_FIRST(head) = LIST_END(head); \ +} while (0) + +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ + if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ + (listelm)->field.le_next->field.le_prev = \ + &(elm)->field.le_next; \ + (listelm)->field.le_next = (elm); \ + (elm)->field.le_prev = &(listelm)->field.le_next; \ +} while (0) + +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.le_prev = (listelm)->field.le_prev; \ + (elm)->field.le_next = (listelm); \ + *(listelm)->field.le_prev = (elm); \ + (listelm)->field.le_prev = &(elm)->field.le_next; \ +} while (0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.le_next = (head)->lh_first) != NULL) \ + (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ + (head)->lh_first = (elm); \ + (elm)->field.le_prev = &(head)->lh_first; \ +} while (0) + +#define LIST_REMOVE(elm, field) do { \ + if ((elm)->field.le_next != NULL) \ + (elm)->field.le_next->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = (elm)->field.le_next; \ + _Q_INVALIDATE((elm)->field.le_prev); \ + _Q_INVALIDATE((elm)->field.le_next); \ +} while (0) + +#define LIST_REPLACE(elm, elm2, field) do { \ + if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \ + (elm2)->field.le_next->field.le_prev = \ + &(elm2)->field.le_next; \ + (elm2)->field.le_prev = (elm)->field.le_prev; \ + *(elm2)->field.le_prev = (elm2); \ + _Q_INVALIDATE((elm)->field.le_prev); \ + _Q_INVALIDATE((elm)->field.le_next); \ +} while (0) + +/* + * Simple queue definitions. + */ +#define SIMPLEQ_HEAD(name, type) \ +struct name { \ + struct type *sqh_first; /* first element */ \ + struct type **sqh_last; /* addr of last next element */ \ +} + +#define SIMPLEQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).sqh_first } + +#define SIMPLEQ_ENTRY(type) \ +struct { \ + struct type *sqe_next; /* next element */ \ +} + +/* + * Simple queue access methods. + */ +#define SIMPLEQ_FIRST(head) ((head)->sqh_first) +#define SIMPLEQ_END(head) NULL +#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head)) +#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) + +#define SIMPLEQ_FOREACH(var, head, field) \ + for((var) = SIMPLEQ_FIRST(head); \ + (var) != SIMPLEQ_END(head); \ + (var) = SIMPLEQ_NEXT(var, field)) + +#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = SIMPLEQ_FIRST(head); \ + (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); \ + (var) = (tvar)) + +/* + * Simple queue functions. + */ +#define SIMPLEQ_INIT(head) do { \ + (head)->sqh_first = NULL; \ + (head)->sqh_last = &(head)->sqh_first; \ +} while (0) + +#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (head)->sqh_first = (elm); \ +} while (0) + +#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.sqe_next = NULL; \ + *(head)->sqh_last = (elm); \ + (head)->sqh_last = &(elm)->field.sqe_next; \ +} while (0) + +#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (listelm)->field.sqe_next = (elm); \ +} while (0) + +#define SIMPLEQ_REMOVE_HEAD(head, field) do { \ + if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \ + (head)->sqh_last = &(head)->sqh_first; \ +} while (0) + +#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \ + if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \ + == NULL) \ + (head)->sqh_last = &(elm)->field.sqe_next; \ +} while (0) + +/* + * Tail queue definitions. + */ +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ +} + +#define TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first } + +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ +} + +/* + * tail queue access methods + */ +#define TAILQ_FIRST(head) ((head)->tqh_first) +#define TAILQ_END(head) NULL +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) +/* XXX */ +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) +#define TAILQ_EMPTY(head) \ + (TAILQ_FIRST(head) == TAILQ_END(head)) + +#define TAILQ_FOREACH(var, head, field) \ + for((var) = TAILQ_FIRST(head); \ + (var) != TAILQ_END(head); \ + (var) = TAILQ_NEXT(var, field)) + +#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = TAILQ_FIRST(head); \ + (var) != TAILQ_END(head) && \ + ((tvar) = TAILQ_NEXT(var, field), 1); \ + (var) = (tvar)) + + +#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ + for((var) = TAILQ_LAST(head, headname); \ + (var) != TAILQ_END(head); \ + (var) = TAILQ_PREV(var, headname, field)) + +#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ + for ((var) = TAILQ_LAST(head, headname); \ + (var) != TAILQ_END(head) && \ + ((tvar) = TAILQ_PREV(var, headname, field), 1); \ + (var) = (tvar)) + +/* + * Tail queue functions. + */ +#define TAILQ_INIT(head) do { \ + (head)->tqh_first = NULL; \ + (head)->tqh_last = &(head)->tqh_first; \ +} while (0) + +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ + (head)->tqh_first->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (head)->tqh_first = (elm); \ + (elm)->field.tqe_prev = &(head)->tqh_first; \ +} while (0) + +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.tqe_next = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &(elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ + (elm)->field.tqe_next->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (listelm)->field.tqe_next = (elm); \ + (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ +} while (0) + +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + (elm)->field.tqe_next = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_REMOVE(head, elm, field) do { \ + if (((elm)->field.tqe_next) != NULL) \ + (elm)->field.tqe_next->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ + _Q_INVALIDATE((elm)->field.tqe_prev); \ + _Q_INVALIDATE((elm)->field.tqe_next); \ +} while (0) + +#define TAILQ_REPLACE(head, elm, elm2, field) do { \ + if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \ + (elm2)->field.tqe_next->field.tqe_prev = \ + &(elm2)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm2)->field.tqe_next; \ + (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \ + *(elm2)->field.tqe_prev = (elm2); \ + _Q_INVALIDATE((elm)->field.tqe_prev); \ + _Q_INVALIDATE((elm)->field.tqe_next); \ +} while (0) + +/* + * Circular queue definitions. + */ +#define CIRCLEQ_HEAD(name, type) \ +struct name { \ + struct type *cqh_first; /* first element */ \ + struct type *cqh_last; /* last element */ \ +} + +#define CIRCLEQ_HEAD_INITIALIZER(head) \ + { CIRCLEQ_END(&head), CIRCLEQ_END(&head) } + +#define CIRCLEQ_ENTRY(type) \ +struct { \ + struct type *cqe_next; /* next element */ \ + struct type *cqe_prev; /* previous element */ \ +} + +/* + * Circular queue access methods + */ +#define CIRCLEQ_FIRST(head) ((head)->cqh_first) +#define CIRCLEQ_LAST(head) ((head)->cqh_last) +#define CIRCLEQ_END(head) ((void *)(head)) +#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) +#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) +#define CIRCLEQ_EMPTY(head) \ + (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head)) + +#define CIRCLEQ_FOREACH(var, head, field) \ + for((var) = CIRCLEQ_FIRST(head); \ + (var) != CIRCLEQ_END(head); \ + (var) = CIRCLEQ_NEXT(var, field)) + +#define CIRCLEQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = CIRCLEQ_FIRST(head); \ + (var) != CIRCLEQ_END(head) && \ + ((tvar) = CIRCLEQ_NEXT(var, field), 1); \ + (var) = (tvar)) + +#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ + for((var) = CIRCLEQ_LAST(head); \ + (var) != CIRCLEQ_END(head); \ + (var) = CIRCLEQ_PREV(var, field)) + +#define CIRCLEQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ + for ((var) = CIRCLEQ_LAST(head, headname); \ + (var) != CIRCLEQ_END(head) && \ + ((tvar) = CIRCLEQ_PREV(var, headname, field), 1); \ + (var) = (tvar)) + +/* + * Circular queue functions. + */ +#define CIRCLEQ_INIT(head) do { \ + (head)->cqh_first = CIRCLEQ_END(head); \ + (head)->cqh_last = CIRCLEQ_END(head); \ +} while (0) + +#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + (elm)->field.cqe_next = (listelm)->field.cqe_next; \ + (elm)->field.cqe_prev = (listelm); \ + if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \ + (head)->cqh_last = (elm); \ + else \ + (listelm)->field.cqe_next->field.cqe_prev = (elm); \ + (listelm)->field.cqe_next = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ + (elm)->field.cqe_next = (listelm); \ + (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ + if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \ + (head)->cqh_first = (elm); \ + else \ + (listelm)->field.cqe_prev->field.cqe_next = (elm); \ + (listelm)->field.cqe_prev = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.cqe_next = (head)->cqh_first; \ + (elm)->field.cqe_prev = CIRCLEQ_END(head); \ + if ((head)->cqh_last == CIRCLEQ_END(head)) \ + (head)->cqh_last = (elm); \ + else \ + (head)->cqh_first->field.cqe_prev = (elm); \ + (head)->cqh_first = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.cqe_next = CIRCLEQ_END(head); \ + (elm)->field.cqe_prev = (head)->cqh_last; \ + if ((head)->cqh_first == CIRCLEQ_END(head)) \ + (head)->cqh_first = (elm); \ + else \ + (head)->cqh_last->field.cqe_next = (elm); \ + (head)->cqh_last = (elm); \ +} while (0) + +#define CIRCLEQ_REMOVE(head, elm, field) do { \ + if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \ + (head)->cqh_last = (elm)->field.cqe_prev; \ + else \ + (elm)->field.cqe_next->field.cqe_prev = \ + (elm)->field.cqe_prev; \ + if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \ + (head)->cqh_first = (elm)->field.cqe_next; \ + else \ + (elm)->field.cqe_prev->field.cqe_next = \ + (elm)->field.cqe_next; \ + _Q_INVALIDATE((elm)->field.cqe_prev); \ + _Q_INVALIDATE((elm)->field.cqe_next); \ +} while (0) + +#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \ + if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \ + CIRCLEQ_END(head)) \ + (head).cqh_last = (elm2); \ + else \ + (elm2)->field.cqe_next->field.cqe_prev = (elm2); \ + if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \ + CIRCLEQ_END(head)) \ + (head).cqh_first = (elm2); \ + else \ + (elm2)->field.cqe_prev->field.cqe_next = (elm2); \ + _Q_INVALIDATE((elm)->field.cqe_prev); \ + _Q_INVALIDATE((elm)->field.cqe_next); \ +} while (0) + +#endif /* !_FAKE_QUEUE_H_ */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/sys-tree.h b/crypto/external/bsd/openssh/dist/openbsd-compat/sys-tree.h new file mode 100644 index 000000000..7f7546ecd --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/sys-tree.h @@ -0,0 +1,755 @@ +/* $OpenBSD: tree.h,v 1.13 2011/07/09 00:19:45 pirofti Exp $ */ +/* + * Copyright 2002 Niels Provos + * 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. + */ + +/* OPENBSD ORIGINAL: sys/sys/tree.h */ + +#include "config.h" +#ifdef NO_ATTRIBUTE_ON_RETURN_TYPE +# define __attribute__(x) +#endif + +#ifndef _SYS_TREE_H_ +#define _SYS_TREE_H_ + +/* + * This file defines data structures for different types of trees: + * splay trees and red-black trees. + * + * A splay tree is a self-organizing data structure. Every operation + * on the tree causes a splay to happen. The splay moves the requested + * node to the root of the tree and partly rebalances it. + * + * This has the benefit that request locality causes faster lookups as + * the requested nodes move to the top of the tree. On the other hand, + * every lookup causes memory writes. + * + * The Balance Theorem bounds the total access time for m operations + * and n inserts on an initially empty tree as O((m + n)lg n). The + * amortized cost for a sequence of m accesses to a splay tree is O(lg n); + * + * A red-black tree is a binary search tree with the node color as an + * extra attribute. It fulfills a set of conditions: + * - every search path from the root to a leaf consists of the + * same number of black nodes, + * - each red node (except for the root) has a black parent, + * - each leaf node is black. + * + * Every operation on a red-black tree is bounded as O(lg n). + * The maximum height of a red-black tree is 2lg (n+1). + */ + +#define SPLAY_HEAD(name, type) \ +struct name { \ + struct type *sph_root; /* root of the tree */ \ +} + +#define SPLAY_INITIALIZER(root) \ + { NULL } + +#define SPLAY_INIT(root) do { \ + (root)->sph_root = NULL; \ +} while (0) + +#define SPLAY_ENTRY(type) \ +struct { \ + struct type *spe_left; /* left element */ \ + struct type *spe_right; /* right element */ \ +} + +#define SPLAY_LEFT(elm, field) (elm)->field.spe_left +#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right +#define SPLAY_ROOT(head) (head)->sph_root +#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL) + +/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */ +#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \ + SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \ + SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ + (head)->sph_root = tmp; \ +} while (0) + +#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \ + SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \ + SPLAY_LEFT(tmp, field) = (head)->sph_root; \ + (head)->sph_root = tmp; \ +} while (0) + +#define SPLAY_LINKLEFT(head, tmp, field) do { \ + SPLAY_LEFT(tmp, field) = (head)->sph_root; \ + tmp = (head)->sph_root; \ + (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ +} while (0) + +#define SPLAY_LINKRIGHT(head, tmp, field) do { \ + SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ + tmp = (head)->sph_root; \ + (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ +} while (0) + +#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \ + SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \ + SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\ + SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \ + SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \ +} while (0) + +/* Generates prototypes and inline functions */ + +#define SPLAY_PROTOTYPE(name, type, field, cmp) \ +void name##_SPLAY(struct name *, struct type *); \ +void name##_SPLAY_MINMAX(struct name *, int); \ +struct type *name##_SPLAY_INSERT(struct name *, struct type *); \ +struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \ + \ +/* Finds the node with the same key as elm */ \ +static __inline struct type * \ +name##_SPLAY_FIND(struct name *head, struct type *elm) \ +{ \ + if (SPLAY_EMPTY(head)) \ + return(NULL); \ + name##_SPLAY(head, elm); \ + if ((cmp)(elm, (head)->sph_root) == 0) \ + return (head->sph_root); \ + return (NULL); \ +} \ + \ +static __inline struct type * \ +name##_SPLAY_NEXT(struct name *head, struct type *elm) \ +{ \ + name##_SPLAY(head, elm); \ + if (SPLAY_RIGHT(elm, field) != NULL) { \ + elm = SPLAY_RIGHT(elm, field); \ + while (SPLAY_LEFT(elm, field) != NULL) { \ + elm = SPLAY_LEFT(elm, field); \ + } \ + } else \ + elm = NULL; \ + return (elm); \ +} \ + \ +static __inline struct type * \ +name##_SPLAY_MIN_MAX(struct name *head, int val) \ +{ \ + name##_SPLAY_MINMAX(head, val); \ + return (SPLAY_ROOT(head)); \ +} + +/* Main splay operation. + * Moves node close to the key of elm to top + */ +#define SPLAY_GENERATE(name, type, field, cmp) \ +struct type * \ +name##_SPLAY_INSERT(struct name *head, struct type *elm) \ +{ \ + if (SPLAY_EMPTY(head)) { \ + SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \ + } else { \ + int __comp; \ + name##_SPLAY(head, elm); \ + __comp = (cmp)(elm, (head)->sph_root); \ + if(__comp < 0) { \ + SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\ + SPLAY_RIGHT(elm, field) = (head)->sph_root; \ + SPLAY_LEFT((head)->sph_root, field) = NULL; \ + } else if (__comp > 0) { \ + SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\ + SPLAY_LEFT(elm, field) = (head)->sph_root; \ + SPLAY_RIGHT((head)->sph_root, field) = NULL; \ + } else \ + return ((head)->sph_root); \ + } \ + (head)->sph_root = (elm); \ + return (NULL); \ +} \ + \ +struct type * \ +name##_SPLAY_REMOVE(struct name *head, struct type *elm) \ +{ \ + struct type *__tmp; \ + if (SPLAY_EMPTY(head)) \ + return (NULL); \ + name##_SPLAY(head, elm); \ + if ((cmp)(elm, (head)->sph_root) == 0) { \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \ + (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\ + } else { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\ + name##_SPLAY(head, elm); \ + SPLAY_RIGHT((head)->sph_root, field) = __tmp; \ + } \ + return (elm); \ + } \ + return (NULL); \ +} \ + \ +void \ +name##_SPLAY(struct name *head, struct type *elm) \ +{ \ + struct type __node, *__left, *__right, *__tmp; \ + int __comp; \ +\ + SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ + __left = __right = &__node; \ +\ + while ((__comp = (cmp)(elm, (head)->sph_root))) { \ + if (__comp < 0) { \ + __tmp = SPLAY_LEFT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if ((cmp)(elm, __tmp) < 0){ \ + SPLAY_ROTATE_RIGHT(head, __tmp, field); \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKLEFT(head, __right, field); \ + } else if (__comp > 0) { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if ((cmp)(elm, __tmp) > 0){ \ + SPLAY_ROTATE_LEFT(head, __tmp, field); \ + if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKRIGHT(head, __left, field); \ + } \ + } \ + SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ +} \ + \ +/* Splay with either the minimum or the maximum element \ + * Used to find minimum or maximum element in tree. \ + */ \ +void name##_SPLAY_MINMAX(struct name *head, int __comp) \ +{ \ + struct type __node, *__left, *__right, *__tmp; \ +\ + SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ + __left = __right = &__node; \ +\ + while (1) { \ + if (__comp < 0) { \ + __tmp = SPLAY_LEFT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if (__comp < 0){ \ + SPLAY_ROTATE_RIGHT(head, __tmp, field); \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKLEFT(head, __right, field); \ + } else if (__comp > 0) { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if (__comp > 0) { \ + SPLAY_ROTATE_LEFT(head, __tmp, field); \ + if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKRIGHT(head, __left, field); \ + } \ + } \ + SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ +} + +#define SPLAY_NEGINF -1 +#define SPLAY_INF 1 + +#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y) +#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y) +#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y) +#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y) +#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \ + : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF)) +#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \ + : name##_SPLAY_MIN_MAX(x, SPLAY_INF)) + +#define SPLAY_FOREACH(x, name, head) \ + for ((x) = SPLAY_MIN(name, head); \ + (x) != NULL; \ + (x) = SPLAY_NEXT(name, head, x)) + +/* Macros that define a red-black tree */ +#define RB_HEAD(name, type) \ +struct name { \ + struct type *rbh_root; /* root of the tree */ \ +} + +#define RB_INITIALIZER(root) \ + { NULL } + +#define RB_INIT(root) do { \ + (root)->rbh_root = NULL; \ +} while (0) + +#define RB_BLACK 0 +#define RB_RED 1 +#define RB_ENTRY(type) \ +struct { \ + struct type *rbe_left; /* left element */ \ + struct type *rbe_right; /* right element */ \ + struct type *rbe_parent; /* parent element */ \ + int rbe_color; /* node color */ \ +} + +#define RB_LEFT(elm, field) (elm)->field.rbe_left +#define RB_RIGHT(elm, field) (elm)->field.rbe_right +#define RB_PARENT(elm, field) (elm)->field.rbe_parent +#define RB_COLOR(elm, field) (elm)->field.rbe_color +#define RB_ROOT(head) (head)->rbh_root +#define RB_EMPTY(head) (RB_ROOT(head) == NULL) + +#define RB_SET(elm, parent, field) do { \ + RB_PARENT(elm, field) = parent; \ + RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ + RB_COLOR(elm, field) = RB_RED; \ +} while (0) + +#define RB_SET_BLACKRED(black, red, field) do { \ + RB_COLOR(black, field) = RB_BLACK; \ + RB_COLOR(red, field) = RB_RED; \ +} while (0) + +#ifndef RB_AUGMENT +#define RB_AUGMENT(x) do {} while (0) +#endif + +#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ + (tmp) = RB_RIGHT(elm, field); \ + if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) { \ + RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \ + } \ + RB_AUGMENT(elm); \ + if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \ + if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ + RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ + else \ + RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ + } else \ + (head)->rbh_root = (tmp); \ + RB_LEFT(tmp, field) = (elm); \ + RB_PARENT(elm, field) = (tmp); \ + RB_AUGMENT(tmp); \ + if ((RB_PARENT(tmp, field))) \ + RB_AUGMENT(RB_PARENT(tmp, field)); \ +} while (0) + +#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ + (tmp) = RB_LEFT(elm, field); \ + if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) { \ + RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \ + } \ + RB_AUGMENT(elm); \ + if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \ + if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ + RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ + else \ + RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ + } else \ + (head)->rbh_root = (tmp); \ + RB_RIGHT(tmp, field) = (elm); \ + RB_PARENT(elm, field) = (tmp); \ + RB_AUGMENT(tmp); \ + if ((RB_PARENT(tmp, field))) \ + RB_AUGMENT(RB_PARENT(tmp, field)); \ +} while (0) + +/* Generates prototypes and inline functions */ +#define RB_PROTOTYPE(name, type, field, cmp) \ + RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) +#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \ + RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static) +#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \ +attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \ +attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ +attr struct type *name##_RB_REMOVE(struct name *, struct type *); \ +attr struct type *name##_RB_INSERT(struct name *, struct type *); \ +attr struct type *name##_RB_FIND(struct name *, struct type *); \ +attr struct type *name##_RB_NFIND(struct name *, struct type *); \ +attr struct type *name##_RB_NEXT(struct type *); \ +attr struct type *name##_RB_PREV(struct type *); \ +attr struct type *name##_RB_MINMAX(struct name *, int); \ + \ + +/* Main rb operation. + * Moves node close to the key of elm to top + */ +#define RB_GENERATE(name, type, field, cmp) \ + RB_GENERATE_INTERNAL(name, type, field, cmp,) +#define RB_GENERATE_STATIC(name, type, field, cmp) \ + RB_GENERATE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static) +#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \ +attr void \ +name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ +{ \ + struct type *parent, *gparent, *tmp; \ + while ((parent = RB_PARENT(elm, field)) && \ + RB_COLOR(parent, field) == RB_RED) { \ + gparent = RB_PARENT(parent, field); \ + if (parent == RB_LEFT(gparent, field)) { \ + tmp = RB_RIGHT(gparent, field); \ + if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ + RB_COLOR(tmp, field) = RB_BLACK; \ + RB_SET_BLACKRED(parent, gparent, field);\ + elm = gparent; \ + continue; \ + } \ + if (RB_RIGHT(parent, field) == elm) { \ + RB_ROTATE_LEFT(head, parent, tmp, field);\ + tmp = parent; \ + parent = elm; \ + elm = tmp; \ + } \ + RB_SET_BLACKRED(parent, gparent, field); \ + RB_ROTATE_RIGHT(head, gparent, tmp, field); \ + } else { \ + tmp = RB_LEFT(gparent, field); \ + if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ + RB_COLOR(tmp, field) = RB_BLACK; \ + RB_SET_BLACKRED(parent, gparent, field);\ + elm = gparent; \ + continue; \ + } \ + if (RB_LEFT(parent, field) == elm) { \ + RB_ROTATE_RIGHT(head, parent, tmp, field);\ + tmp = parent; \ + parent = elm; \ + elm = tmp; \ + } \ + RB_SET_BLACKRED(parent, gparent, field); \ + RB_ROTATE_LEFT(head, gparent, tmp, field); \ + } \ + } \ + RB_COLOR(head->rbh_root, field) = RB_BLACK; \ +} \ + \ +attr void \ +name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \ +{ \ + struct type *tmp; \ + while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \ + elm != RB_ROOT(head)) { \ + if (RB_LEFT(parent, field) == elm) { \ + tmp = RB_RIGHT(parent, field); \ + if (RB_COLOR(tmp, field) == RB_RED) { \ + RB_SET_BLACKRED(tmp, parent, field); \ + RB_ROTATE_LEFT(head, parent, tmp, field);\ + tmp = RB_RIGHT(parent, field); \ + } \ + if ((RB_LEFT(tmp, field) == NULL || \ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ + (RB_RIGHT(tmp, field) == NULL || \ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ + RB_COLOR(tmp, field) = RB_RED; \ + elm = parent; \ + parent = RB_PARENT(elm, field); \ + } else { \ + if (RB_RIGHT(tmp, field) == NULL || \ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\ + struct type *oleft; \ + if ((oleft = RB_LEFT(tmp, field)))\ + RB_COLOR(oleft, field) = RB_BLACK;\ + RB_COLOR(tmp, field) = RB_RED; \ + RB_ROTATE_RIGHT(head, tmp, oleft, field);\ + tmp = RB_RIGHT(parent, field); \ + } \ + RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ + RB_COLOR(parent, field) = RB_BLACK; \ + if (RB_RIGHT(tmp, field)) \ + RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\ + RB_ROTATE_LEFT(head, parent, tmp, field);\ + elm = RB_ROOT(head); \ + break; \ + } \ + } else { \ + tmp = RB_LEFT(parent, field); \ + if (RB_COLOR(tmp, field) == RB_RED) { \ + RB_SET_BLACKRED(tmp, parent, field); \ + RB_ROTATE_RIGHT(head, parent, tmp, field);\ + tmp = RB_LEFT(parent, field); \ + } \ + if ((RB_LEFT(tmp, field) == NULL || \ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ + (RB_RIGHT(tmp, field) == NULL || \ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ + RB_COLOR(tmp, field) = RB_RED; \ + elm = parent; \ + parent = RB_PARENT(elm, field); \ + } else { \ + if (RB_LEFT(tmp, field) == NULL || \ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\ + struct type *oright; \ + if ((oright = RB_RIGHT(tmp, field)))\ + RB_COLOR(oright, field) = RB_BLACK;\ + RB_COLOR(tmp, field) = RB_RED; \ + RB_ROTATE_LEFT(head, tmp, oright, field);\ + tmp = RB_LEFT(parent, field); \ + } \ + RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ + RB_COLOR(parent, field) = RB_BLACK; \ + if (RB_LEFT(tmp, field)) \ + RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\ + RB_ROTATE_RIGHT(head, parent, tmp, field);\ + elm = RB_ROOT(head); \ + break; \ + } \ + } \ + } \ + if (elm) \ + RB_COLOR(elm, field) = RB_BLACK; \ +} \ + \ +attr struct type * \ +name##_RB_REMOVE(struct name *head, struct type *elm) \ +{ \ + struct type *child, *parent, *old = elm; \ + int color; \ + if (RB_LEFT(elm, field) == NULL) \ + child = RB_RIGHT(elm, field); \ + else if (RB_RIGHT(elm, field) == NULL) \ + child = RB_LEFT(elm, field); \ + else { \ + struct type *left; \ + elm = RB_RIGHT(elm, field); \ + while ((left = RB_LEFT(elm, field))) \ + elm = left; \ + child = RB_RIGHT(elm, field); \ + parent = RB_PARENT(elm, field); \ + color = RB_COLOR(elm, field); \ + if (child) \ + RB_PARENT(child, field) = parent; \ + if (parent) { \ + if (RB_LEFT(parent, field) == elm) \ + RB_LEFT(parent, field) = child; \ + else \ + RB_RIGHT(parent, field) = child; \ + RB_AUGMENT(parent); \ + } else \ + RB_ROOT(head) = child; \ + if (RB_PARENT(elm, field) == old) \ + parent = elm; \ + (elm)->field = (old)->field; \ + if (RB_PARENT(old, field)) { \ + if (RB_LEFT(RB_PARENT(old, field), field) == old)\ + RB_LEFT(RB_PARENT(old, field), field) = elm;\ + else \ + RB_RIGHT(RB_PARENT(old, field), field) = elm;\ + RB_AUGMENT(RB_PARENT(old, field)); \ + } else \ + RB_ROOT(head) = elm; \ + RB_PARENT(RB_LEFT(old, field), field) = elm; \ + if (RB_RIGHT(old, field)) \ + RB_PARENT(RB_RIGHT(old, field), field) = elm; \ + if (parent) { \ + left = parent; \ + do { \ + RB_AUGMENT(left); \ + } while ((left = RB_PARENT(left, field))); \ + } \ + goto color; \ + } \ + parent = RB_PARENT(elm, field); \ + color = RB_COLOR(elm, field); \ + if (child) \ + RB_PARENT(child, field) = parent; \ + if (parent) { \ + if (RB_LEFT(parent, field) == elm) \ + RB_LEFT(parent, field) = child; \ + else \ + RB_RIGHT(parent, field) = child; \ + RB_AUGMENT(parent); \ + } else \ + RB_ROOT(head) = child; \ +color: \ + if (color == RB_BLACK) \ + name##_RB_REMOVE_COLOR(head, parent, child); \ + return (old); \ +} \ + \ +/* Inserts a node into the RB tree */ \ +attr struct type * \ +name##_RB_INSERT(struct name *head, struct type *elm) \ +{ \ + struct type *tmp; \ + struct type *parent = NULL; \ + int comp = 0; \ + tmp = RB_ROOT(head); \ + while (tmp) { \ + parent = tmp; \ + comp = (cmp)(elm, parent); \ + if (comp < 0) \ + tmp = RB_LEFT(tmp, field); \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + RB_SET(elm, parent, field); \ + if (parent != NULL) { \ + if (comp < 0) \ + RB_LEFT(parent, field) = elm; \ + else \ + RB_RIGHT(parent, field) = elm; \ + RB_AUGMENT(parent); \ + } else \ + RB_ROOT(head) = elm; \ + name##_RB_INSERT_COLOR(head, elm); \ + return (NULL); \ +} \ + \ +/* Finds the node with the same key as elm */ \ +attr struct type * \ +name##_RB_FIND(struct name *head, struct type *elm) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + int comp; \ + while (tmp) { \ + comp = cmp(elm, tmp); \ + if (comp < 0) \ + tmp = RB_LEFT(tmp, field); \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + return (NULL); \ +} \ + \ +/* Finds the first node greater than or equal to the search key */ \ +attr struct type * \ +name##_RB_NFIND(struct name *head, struct type *elm) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + struct type *res = NULL; \ + int comp; \ + while (tmp) { \ + comp = cmp(elm, tmp); \ + if (comp < 0) { \ + res = tmp; \ + tmp = RB_LEFT(tmp, field); \ + } \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + return (res); \ +} \ + \ +/* ARGSUSED */ \ +attr struct type * \ +name##_RB_NEXT(struct type *elm) \ +{ \ + if (RB_RIGHT(elm, field)) { \ + elm = RB_RIGHT(elm, field); \ + while (RB_LEFT(elm, field)) \ + elm = RB_LEFT(elm, field); \ + } else { \ + if (RB_PARENT(elm, field) && \ + (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ + elm = RB_PARENT(elm, field); \ + else { \ + while (RB_PARENT(elm, field) && \ + (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\ + elm = RB_PARENT(elm, field); \ + elm = RB_PARENT(elm, field); \ + } \ + } \ + return (elm); \ +} \ + \ +/* ARGSUSED */ \ +attr struct type * \ +name##_RB_PREV(struct type *elm) \ +{ \ + if (RB_LEFT(elm, field)) { \ + elm = RB_LEFT(elm, field); \ + while (RB_RIGHT(elm, field)) \ + elm = RB_RIGHT(elm, field); \ + } else { \ + if (RB_PARENT(elm, field) && \ + (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \ + elm = RB_PARENT(elm, field); \ + else { \ + while (RB_PARENT(elm, field) && \ + (elm == RB_LEFT(RB_PARENT(elm, field), field)))\ + elm = RB_PARENT(elm, field); \ + elm = RB_PARENT(elm, field); \ + } \ + } \ + return (elm); \ +} \ + \ +attr struct type * \ +name##_RB_MINMAX(struct name *head, int val) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + struct type *parent = NULL; \ + while (tmp) { \ + parent = tmp; \ + if (val < 0) \ + tmp = RB_LEFT(tmp, field); \ + else \ + tmp = RB_RIGHT(tmp, field); \ + } \ + return (parent); \ +} + +#define RB_NEGINF -1 +#define RB_INF 1 + +#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) +#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) +#define RB_FIND(name, x, y) name##_RB_FIND(x, y) +#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y) +#define RB_NEXT(name, x, y) name##_RB_NEXT(y) +#define RB_PREV(name, x, y) name##_RB_PREV(y) +#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) +#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) + +#define RB_FOREACH(x, name, head) \ + for ((x) = RB_MIN(name, head); \ + (x) != NULL; \ + (x) = name##_RB_NEXT(x)) + +#define RB_FOREACH_SAFE(x, name, head, y) \ + for ((x) = RB_MIN(name, head); \ + ((x) != NULL) && ((y) = name##_RB_NEXT(x), 1); \ + (x) = (y)) + +#define RB_FOREACH_REVERSE(x, name, head) \ + for ((x) = RB_MAX(name, head); \ + (x) != NULL; \ + (x) = name##_RB_PREV(x)) + +#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \ + for ((x) = RB_MAX(name, head); \ + ((x) != NULL) && ((y) = name##_RB_PREV(x), 1); \ + (x) = (y)) + +#endif /* _SYS_TREE_H_ */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/timingsafe_bcmp.c b/crypto/external/bsd/openssh/dist/openbsd-compat/timingsafe_bcmp.c new file mode 100644 index 000000000..7e28c0e2a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/timingsafe_bcmp.c @@ -0,0 +1,34 @@ +/* $OpenBSD: timingsafe_bcmp.c,v 1.1 2010/09/24 13:33:00 matthew Exp $ */ +/* + * Copyright (c) 2010 Damien Miller. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/string/timingsafe_bcmp.c */ + +#include "includes.h" +#ifndef HAVE_TIMINGSAFE_BCMP + +int +timingsafe_bcmp(const void *b1, const void *b2, size_t n) +{ + const unsigned char *p1 = b1, *p2 = b2; + int ret = 0; + + for (; n > 0; n--) + ret |= *p1++ ^ *p2++; + return (ret != 0); +} + +#endif /* TIMINGSAFE_BCMP */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/vis.c b/crypto/external/bsd/openssh/dist/openbsd-compat/vis.c new file mode 100644 index 000000000..f6f5665c1 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/vis.c @@ -0,0 +1,225 @@ +/* $OpenBSD: vis.c,v 1.19 2005/09/01 17:15:49 millert Exp $ */ +/*- + * 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. 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. + */ + +/* OPENBSD ORIGINAL: lib/libc/gen/vis.c */ + +#include "includes.h" +#if !defined(HAVE_STRNVIS) || defined(BROKEN_STRNVIS) + +#include +#include + +#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)) && \ + (((c) != '*' && (c) != '?' && (c) != '[' && (c) != '#') || \ + (flag & VIS_GLOB) == 0) && 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' || \ + isgraph((u_char)(c))))) + +/* + * vis - visually encode characters + */ +char * +vis(char *dst, int c, int flag, int nextc) +{ + 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) || + ((flag & VIS_GLOB) && (c == '*' || c == '?' || c == '[' || c == '#'))) { + *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((u_char)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(char *dst, const char *src, int flag) +{ + char c; + char *start; + + for (start = dst; (c = *src);) + dst = vis(dst, c, flag, *++src); + *dst = '\0'; + return (dst - start); +} + +int +strnvis(char *dst, const char *src, size_t siz, int flag) +{ + char *start, *end; + char tbuf[5]; + int c, i; + + i = 0; + for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) { + if (isvisible(c)) { + i = 1; + *dst++ = c; + if (c == '\\' && (flag & VIS_NOSLASH) == 0) { + /* need space for the extra '\\' */ + if (dst < end) + *dst++ = '\\'; + else { + dst--; + i = 2; + break; + } + } + src++; + } else { + i = vis(tbuf, c, flag, *++src) - tbuf; + if (dst + i <= end) { + memcpy(dst, tbuf, i); + dst += i; + } else { + src--; + break; + } + } + } + if (siz > 0) + *dst = '\0'; + if (dst + i > end) { + /* adjust return value for truncation */ + while ((c = *src)) + dst += vis(tbuf, c, flag, *++src) - tbuf; + } + return (dst - start); +} + +int +strvisx(char *dst, const char *src, size_t len, int flag) +{ + 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/crypto/external/bsd/openssh/dist/openbsd-compat/vis.h b/crypto/external/bsd/openssh/dist/openbsd-compat/vis.h new file mode 100644 index 000000000..d1286c99d --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/vis.h @@ -0,0 +1,95 @@ +/* $OpenBSD: vis.h,v 1.11 2005/08/09 19:38:31 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. 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 + */ + +/* OPENBSD ORIGINAL: include/vis.h */ + +#include "includes.h" +#if !defined(HAVE_STRNVIS) || defined(BROKEN_STRNVIS) + +#ifndef _VIS_H_ +#define _VIS_H_ + +#include +#include + +/* + * 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 '\' */ +#define VIS_GLOB 0x100 /* encode glob(3) magics and '#' */ + +/* + * 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) + __attribute__ ((__bounded__(__string__,1,3))); +int strvisx(char *, const char *, size_t, int) + __attribute__ ((__bounded__(__string__,1,3))); +int strunvis(char *, const char *); +int unvis(char *, char, int *, int); +ssize_t strnunvis(char *, const char *, size_t) + __attribute__ ((__bounded__(__string__,1,3))); + +#endif /* !_VIS_H_ */ + +#endif /* !HAVE_STRNVIS || BROKEN_STRNVIS */ diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/xcrypt.c b/crypto/external/bsd/openssh/dist/openbsd-compat/xcrypt.c new file mode 100644 index 000000000..8577cbd8a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/xcrypt.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2003 Ben Lindstrom. 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" + +#include +#include +#include + +# if defined(HAVE_CRYPT_H) && !defined(HAVE_SECUREWARE) +# include +# endif + +# ifdef __hpux +# include +# include +# endif + +# ifdef HAVE_SECUREWARE +# include +# include +# include +# endif + +# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) +# include +# endif + +# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) +# include +# include +# include +# endif + +# if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) +# include "md5crypt.h" +# endif + +# if defined(WITH_OPENSSL) && !defined(HAVE_CRYPT) && defined(HAVE_DES_CRYPT) +# include +# define crypt DES_crypt +# endif + +char * +xcrypt(const char *password, const char *salt) +{ + char *crypted; + +# ifdef HAVE_MD5_PASSWORDS + if (is_md5_salt(salt)) + crypted = md5_crypt(password, salt); + else + crypted = crypt(password, salt); +# elif defined(__hpux) && !defined(HAVE_SECUREWARE) + if (iscomsec()) + crypted = bigcrypt(password, salt); + else + crypted = crypt(password, salt); +# elif defined(HAVE_SECUREWARE) + crypted = bigcrypt(password, salt); +# else + crypted = crypt(password, salt); +# endif + + return crypted; +} + +/* + * Handle shadowed password systems in a cleaner way for portable + * version. + */ + +char * +shadow_pw(struct passwd *pw) +{ + char *pw_password = pw->pw_passwd; + +# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) + struct spwd *spw = getspnam(pw->pw_name); + + if (spw != NULL) + pw_password = spw->sp_pwdp; +# endif + +#ifdef USE_LIBIAF + return(get_iaf_password(pw)); +#endif + +# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) + struct passwd_adjunct *spw; + if (issecure() && (spw = getpwanam(pw->pw_name)) != NULL) + pw_password = spw->pwa_passwd; +# elif defined(HAVE_SECUREWARE) + struct pr_passwd *spw = getprpwnam(pw->pw_name); + + if (spw != NULL) + pw_password = spw->ufld.fd_encrypt; +# endif + + return pw_password; +} diff --git a/crypto/external/bsd/openssh/dist/openbsd-compat/xmmap.c b/crypto/external/bsd/openssh/dist/openbsd-compat/xmmap.c new file mode 100644 index 000000000..04c6babc2 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openbsd-compat/xmmap.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2002 Tim Rice. All rights reserved. + * MAP_FAILED code by Solar Designer. + * + * 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. + */ + +/* $Id: xmmap.c,v 1.15 2009/02/16 04:21:40 djm Exp $ */ + +#include "includes.h" + +#include +#ifdef HAVE_SYS_MMAN_H +#include +#endif +#include + +#ifdef HAVE_FCNTL_H +# include +#endif +#include +#include +#include +#include +#include + +#include "log.h" + +void * +xmmap(size_t size) +{ +#ifdef HAVE_MMAP + void *address; + +# ifdef MAP_ANON + address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANON|MAP_SHARED, + -1, (off_t)0); +# else + address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED, + open("/dev/zero", O_RDWR), (off_t)0); +# endif + +#define MM_SWAP_TEMPLATE "/var/run/sshd.mm.XXXXXXXX" + if (address == (void *)MAP_FAILED) { + char tmpname[sizeof(MM_SWAP_TEMPLATE)] = MM_SWAP_TEMPLATE; + int tmpfd; + mode_t old_umask; + + old_umask = umask(0177); + tmpfd = mkstemp(tmpname); + umask(old_umask); + if (tmpfd == -1) + fatal("mkstemp(\"%s\"): %s", + MM_SWAP_TEMPLATE, strerror(errno)); + unlink(tmpname); + if (ftruncate(tmpfd, size) != 0) + fatal("%s: ftruncate: %s", __func__, strerror(errno)); + address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED, + tmpfd, (off_t)0); + close(tmpfd); + } + + return (address); +#else + fatal("%s: UsePrivilegeSeparation=yes and Compression=yes not supported", + __func__); +#endif /* HAVE_MMAP */ + +} + diff --git a/crypto/external/bsd/openssh/dist/openssh.xml b/crypto/external/bsd/openssh/dist/openssh.xml new file mode 100644 index 000000000..5417c18c8 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openssh.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/crypto/external/bsd/openssh/dist/opensshd.init b/crypto/external/bsd/openssh/dist/opensshd.init new file mode 100644 index 000000000..b2c161fec --- /dev/null +++ b/crypto/external/bsd/openssh/dist/opensshd.init @@ -0,0 +1,92 @@ +#!/bin/sh +# Donated code that was put under PD license. +# +# Stripped PRNGd out of it for the time being. + +umask 022 + +CAT=/bin/cat +KILL=/bin/kill + +prefix=/usr/local +sysconfdir=${prefix}/etc +piddir=/var/run + +SSHD=$prefix/sbin/sshd +PIDFILE=$piddir/sshd.pid +PidFile=`grep "^PidFile" ${sysconfdir}/sshd_config | tr "=" " " | awk '{print $2}'` +[ X$PidFile = X ] || PIDFILE=$PidFile +SSH_KEYGEN=$prefix/bin/ssh-keygen +HOST_KEY_RSA1=$sysconfdir/ssh_host_key +HOST_KEY_DSA=$sysconfdir/ssh_host_dsa_key +HOST_KEY_RSA=$sysconfdir/ssh_host_rsa_key +HOST_KEY_ECDSA=$sysconfdir/ssh_host_ecdsa_key +HOST_KEY_ED25519=$sysconfdir/ssh_host_ed25519_key + + +checkkeys() { + if [ ! -f $HOST_KEY_RSA1 ]; then + ${SSH_KEYGEN} -t rsa1 -f ${HOST_KEY_RSA1} -N "" + fi + if [ ! -f $HOST_KEY_DSA ]; then + ${SSH_KEYGEN} -t dsa -f ${HOST_KEY_DSA} -N "" + fi + if [ ! -f $HOST_KEY_RSA ]; then + ${SSH_KEYGEN} -t rsa -f ${HOST_KEY_RSA} -N "" + fi + if [ ! -f $HOST_KEY_ECDSA ]; then + ${SSH_KEYGEN} -t ecdsa -f ${HOST_KEY_ECDSA} -N "" + fi + if [ ! -f $HOST_KEY_ED25519 ]; then + ${SSH_KEYGEN} -t ed25519 -f ${HOST_KEY_ED25519} -N "" + fi +} + +stop_service() { + if [ -r $PIDFILE -a ! -z ${PIDFILE} ]; then + PID=`${CAT} ${PIDFILE}` + fi + if [ ${PID:=0} -gt 1 -a ! "X$PID" = "X " ]; then + ${KILL} ${PID} + else + echo "Unable to read PID file" + fi +} + +start_service() { + # XXX We really should check if the service is already going, but + # XXX we will opt out at this time. - Bal + + # Check to see if we have keys that need to be made + checkkeys + + # Start SSHD + echo "starting $SSHD... \c" ; $SSHD + + sshd_rc=$? + if [ $sshd_rc -ne 0 ]; then + echo "$0: Error ${sshd_rc} starting ${SSHD}... bailing." + exit $sshd_rc + fi + echo done. +} + +case $1 in + +'start') + start_service + ;; + +'stop') + stop_service + ;; + +'restart') + stop_service + start_service + ;; + +*) + echo "$0: usage: $0 {start|stop|restart}" + ;; +esac diff --git a/crypto/external/bsd/openssh/dist/openssl-compat.c b/crypto/external/bsd/openssh/dist/openssl-compat.c new file mode 120000 index 000000000..23b0a19b6 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openssl-compat.c @@ -0,0 +1 @@ +openbsd-compat/openssl-compat.c \ No newline at end of file diff --git a/crypto/external/bsd/openssh/dist/openssl-compat.h b/crypto/external/bsd/openssh/dist/openssl-compat.h new file mode 120000 index 000000000..7e987ccff --- /dev/null +++ b/crypto/external/bsd/openssh/dist/openssl-compat.h @@ -0,0 +1 @@ +openbsd-compat/openssl-compat.h \ No newline at end of file diff --git a/crypto/external/bsd/openssh/dist/platform.c b/crypto/external/bsd/openssh/dist/platform.c new file mode 100644 index 000000000..ee313da55 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/platform.c @@ -0,0 +1,215 @@ +/* $Id: platform.c,v 1.22 2014/07/18 04:11:26 djm Exp $ */ + +/* + * Copyright (c) 2006 Darren Tucker. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include + +#include +#include + +#include "log.h" +#include "buffer.h" +#include "misc.h" +#include "servconf.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "auth-pam.h" +#include "platform.h" + +#include "openbsd-compat/openbsd-compat.h" + +extern int use_privsep; +extern ServerOptions options; + +void +platform_pre_listen(void) +{ +#ifdef LINUX_OOM_ADJUST + /* Adjust out-of-memory killer so listening process is not killed */ + oom_adjust_setup(); +#endif +} + +void +platform_pre_fork(void) +{ +#ifdef USE_SOLARIS_PROCESS_CONTRACTS + solaris_contract_pre_fork(); +#endif +} + +void +platform_pre_restart(void) +{ +#ifdef LINUX_OOM_ADJUST + oom_adjust_restore(); +#endif +} + +void +platform_post_fork_parent(pid_t child_pid) +{ +#ifdef USE_SOLARIS_PROCESS_CONTRACTS + solaris_contract_post_fork_parent(child_pid); +#endif +} + +void +platform_post_fork_child(void) +{ +#ifdef USE_SOLARIS_PROCESS_CONTRACTS + solaris_contract_post_fork_child(); +#endif +#ifdef LINUX_OOM_ADJUST + oom_adjust_restore(); +#endif +} + +/* return 1 if we are running with privilege to swap UIDs, 0 otherwise */ +int +platform_privileged_uidswap(void) +{ +#ifdef HAVE_CYGWIN + /* uid 0 is not special on Cygwin so always try */ + return 1; +#else + return (getuid() == 0 || geteuid() == 0); +#endif +} + +/* + * This gets called before switching UIDs, and is called even when sshd is + * not running as root. + */ +void +platform_setusercontext(struct passwd *pw) +{ +#ifdef WITH_SELINUX + /* Cache selinux status for later use */ + (void)ssh_selinux_enabled(); +#endif + +#ifdef USE_SOLARIS_PROJECTS + /* if solaris projects were detected, set the default now */ + if (getuid() == 0 || geteuid() == 0) + solaris_set_default_project(pw); +#endif + +#if defined(HAVE_LOGIN_CAP) && defined (__bsdi__) + if (getuid() == 0 || geteuid() == 0) + setpgid(0, 0); +# endif + +#if defined(HAVE_LOGIN_CAP) && defined(USE_PAM) + /* + * If we have both LOGIN_CAP and PAM, we want to establish creds + * before calling setusercontext (in session.c:do_setusercontext). + */ + if (getuid() == 0 || geteuid() == 0) { + if (options.use_pam) { + do_pam_setcred(use_privsep); + } + } +# endif /* USE_PAM */ + +#if !defined(HAVE_LOGIN_CAP) && defined(HAVE_GETLUID) && defined(HAVE_SETLUID) + if (getuid() == 0 || geteuid() == 0) { + /* Sets login uid for accounting */ + if (getluid() == -1 && setluid(pw->pw_uid) == -1) + error("setluid: %s", strerror(errno)); + } +#endif +} + +/* + * This gets called after we've established the user's groups, and is only + * called if sshd is running as root. + */ +void +platform_setusercontext_post_groups(struct passwd *pw) +{ +#if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM) + /* + * PAM credentials may take the form of supplementary groups. + * These will have been wiped by the above initgroups() call. + * Reestablish them here. + */ + if (options.use_pam) { + do_pam_setcred(use_privsep); + } +#endif /* USE_PAM */ + +#if !defined(HAVE_LOGIN_CAP) && (defined(WITH_IRIX_PROJECT) || \ + defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)) + irix_setusercontext(pw); +#endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ + +#ifdef _AIX + aix_usrinfo(pw); +#endif /* _AIX */ + +#ifdef HAVE_SETPCRED + /* + * If we have a chroot directory, we set all creds except real + * uid which we will need for chroot. If we don't have a + * chroot directory, we don't override anything. + */ + { + char **creds = NULL, *chroot_creds[] = + { "REAL_USER=root", NULL }; + + if (options.chroot_directory != NULL && + strcasecmp(options.chroot_directory, "none") != 0) + creds = chroot_creds; + + if (setpcred(pw->pw_name, creds) == -1) + fatal("Failed to set process credentials"); + } +#endif /* HAVE_SETPCRED */ +#ifdef WITH_SELINUX + ssh_selinux_setup_exec_context(pw->pw_name); +#endif +} + +char * +platform_krb5_get_principal_name(const char *pw_name) +{ +#ifdef USE_AIX_KRB_NAME + return aix_krb5_get_principal_name(pw_name); +#else + return NULL; +#endif +} + +/* + * return 1 if the specified uid is a uid that may own a system directory + * otherwise 0. + */ +int +platform_sys_dir_uid(uid_t uid) +{ + if (uid == 0) + return 1; +#ifdef PLATFORM_SYS_DIR_UID + if (uid == PLATFORM_SYS_DIR_UID) + return 1; +#endif + return 0; +} diff --git a/crypto/external/bsd/openssh/dist/platform.h b/crypto/external/bsd/openssh/dist/platform.h new file mode 100644 index 000000000..1c7a45d8f --- /dev/null +++ b/crypto/external/bsd/openssh/dist/platform.h @@ -0,0 +1,33 @@ +/* $Id: platform.h,v 1.9 2013/09/22 09:02:40 dtucker Exp $ */ + +/* + * Copyright (c) 2006 Darren Tucker. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +void platform_pre_listen(void); +void platform_pre_fork(void); +void platform_pre_restart(void); +void platform_post_fork_parent(pid_t child_pid); +void platform_post_fork_child(void); +int platform_privileged_uidswap(void); +void platform_setusercontext(struct passwd *); +void platform_setusercontext_post_groups(struct passwd *); +char *platform_get_krb5_client(const char *); +char *platform_krb5_get_principal_name(const char *); +int platform_sys_dir_uid(uid_t); diff --git a/crypto/external/bsd/openssh/dist/reallocarray.c b/crypto/external/bsd/openssh/dist/reallocarray.c new file mode 120000 index 000000000..cee09385a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/reallocarray.c @@ -0,0 +1 @@ +openbsd-compat/reallocarray.c \ No newline at end of file diff --git a/crypto/external/bsd/openssh/dist/realpath.c b/crypto/external/bsd/openssh/dist/realpath.c new file mode 120000 index 000000000..bc69e29ea --- /dev/null +++ b/crypto/external/bsd/openssh/dist/realpath.c @@ -0,0 +1 @@ +openbsd-compat/realpath.c \ No newline at end of file diff --git a/crypto/external/bsd/openssh/dist/regress/.cvsignore b/crypto/external/bsd/openssh/dist/regress/.cvsignore new file mode 100644 index 000000000..3fd25b02e --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/.cvsignore @@ -0,0 +1,31 @@ +*-agent +*.copy +*.log +*.prv +*.pub +actual +authorized_keys_* +batch +copy.dd* +data +expect +host.rsa* +key.* +known_hosts +krl-* +modpipe +remote_pid +revoked-* +revoked-ca +revoked-keyid +revoked-serials +rsa +rsa1 +sftp-server.sh +ssh-log-wrapper.sh +ssh_config +ssh_proxy* +sshd_config +sshd_proxy* +t*.out +t*.out[0-9] diff --git a/crypto/external/bsd/openssh/dist/regress/Makefile b/crypto/external/bsd/openssh/dist/regress/Makefile new file mode 100644 index 000000000..cba83f4d6 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/Makefile @@ -0,0 +1,221 @@ +# $OpenBSD: Makefile,v 1.81 2015/05/21 06:44:25 djm Exp $ + +REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t-exec +tests: prep $(REGRESS_TARGETS) + +# Interop tests are not run by default +interop interop-tests: t-exec-interop + +prep: + test "x${USE_VALGRIND}" = "x" || mkdir -p $(OBJ)/valgrind-out + +clean: + for F in $(CLEANFILES); do rm -f $(OBJ)$$F; done + test -z "${SUDO}" || ${SUDO} rm -f ${SUDO_CLEAN} + rm -rf $(OBJ).putty + +distclean: clean + +LTESTS= connect \ + proxy-connect \ + connect-privsep \ + proto-version \ + proto-mismatch \ + exit-status \ + envpass \ + transfer \ + banner \ + rekey \ + stderr-data \ + stderr-after-eof \ + broken-pipe \ + try-ciphers \ + yes-head \ + login-timeout \ + agent \ + agent-getpeereid \ + agent-timeout \ + agent-ptrace \ + keyscan \ + keygen-change \ + keygen-convert \ + key-options \ + scp \ + sftp \ + sftp-chroot \ + sftp-cmds \ + sftp-badcmds \ + sftp-batch \ + sftp-glob \ + sftp-perm \ + reconfigure \ + dynamic-forward \ + forwarding \ + multiplex \ + reexec \ + brokenkeys \ + cfgparse \ + cfgmatch \ + addrmatch \ + localcommand \ + forcecommand \ + portnum \ + keytype \ + kextype \ + cert-hostkey \ + cert-userkey \ + host-expand \ + keys-command \ + forward-control \ + integrity \ + krl \ + multipubkey \ + limit-keytype \ + hostkey-agent \ + keygen-knownhosts \ + hostkey-rotate \ + principals-command + + +# dhgex \ + +INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers +#INTEROP_TESTS+=ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp + +#LTESTS= cipher-speed + +USER!= id -un +CLEANFILES= t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ + t8.out t8.out.pub t9.out t9.out.pub t10.out t10.out.pub \ + t12.out t12.out.pub \ + authorized_keys_${USER} known_hosts pidfile testdata \ + ssh_config sshd_config.orig ssh_proxy sshd_config sshd_proxy \ + rsa.pub rsa rsa1.pub rsa1 host.rsa host.rsa1 \ + rsa-agent rsa-agent.pub rsa1-agent rsa1-agent.pub \ + ls.copy banner.in banner.out empty.in \ + scp-ssh-wrapper.scp ssh_proxy_envpass remote_pid \ + sshd_proxy_bak rsa_ssh2_cr.prv rsa_ssh2_crnl.prv \ + known_hosts-cert host_ca_key* cert_host_key* cert_user_key* \ + putty.rsa2 sshd_proxy_orig ssh_proxy_bak \ + key.rsa-* key.dsa-* key.ecdsa-* \ + authorized_principals_${USER} expect actual ready \ + sshd_proxy.* authorized_keys_${USER}.* modpipe revoked-* krl-* \ + ssh.log failed-ssh.log sshd.log failed-sshd.log \ + regress.log failed-regress.log ssh-log-wrapper.sh \ + sftp-server.sh sftp-server.log sftp.log setuid-allowed \ + data ed25519-agent ed25519-agent.pub key.ed25519-512 \ + key.ed25519-512.pub netcat host_krl_* host_revoked_* \ + kh.* user_*key* agent-key.* known_hosts.* hkr.* + +SUDO_CLEAN+= /var/run/testdata_${USER} /var/run/keycommand_${USER} + +# Enable all malloc(3) randomisations and checks +TEST_ENV= "MALLOC_OPTIONS=AFGJPRX" + +TEST_SSH_SSHKEYGEN?=ssh-keygen + +CPPFLAGS=-I.. + +t1: + ${TEST_SSH_SSHKEYGEN} -if ${.CURDIR}/rsa_ssh2.prv | diff - ${.CURDIR}/rsa_openssh.prv + tr '\n' '\r' <${.CURDIR}/rsa_ssh2.prv > ${.OBJDIR}/rsa_ssh2_cr.prv + ${TEST_SSH_SSHKEYGEN} -if ${.OBJDIR}/rsa_ssh2_cr.prv | diff - ${.CURDIR}/rsa_openssh.prv + awk '{print $$0 "\r"}' ${.CURDIR}/rsa_ssh2.prv > ${.OBJDIR}/rsa_ssh2_crnl.prv + ${TEST_SSH_SSHKEYGEN} -if ${.OBJDIR}/rsa_ssh2_crnl.prv | diff - ${.CURDIR}/rsa_openssh.prv + +t2: + cat ${.CURDIR}/rsa_openssh.prv > $(OBJ)/t2.out + chmod 600 $(OBJ)/t2.out + ${TEST_SSH_SSHKEYGEN} -yf $(OBJ)/t2.out | diff - ${.CURDIR}/rsa_openssh.pub + +t3: + ${TEST_SSH_SSHKEYGEN} -ef ${.CURDIR}/rsa_openssh.pub >$(OBJ)/t3.out + ${TEST_SSH_SSHKEYGEN} -if $(OBJ)/t3.out | diff - ${.CURDIR}/rsa_openssh.pub + +t4: + ${TEST_SSH_SSHKEYGEN} -E md5 -lf ${.CURDIR}/rsa_openssh.pub |\ + awk '{print $$2}' | diff - ${.CURDIR}/t4.ok + +t5: + ${TEST_SSH_SSHKEYGEN} -Bf ${.CURDIR}/rsa_openssh.pub |\ + awk '{print $$2}' | diff - ${.CURDIR}/t5.ok + +t6: + ${TEST_SSH_SSHKEYGEN} -if ${.CURDIR}/dsa_ssh2.prv > $(OBJ)/t6.out1 + ${TEST_SSH_SSHKEYGEN} -if ${.CURDIR}/dsa_ssh2.pub > $(OBJ)/t6.out2 + chmod 600 $(OBJ)/t6.out1 + ${TEST_SSH_SSHKEYGEN} -yf $(OBJ)/t6.out1 | diff - $(OBJ)/t6.out2 + +$(OBJ)/t7.out: + ${TEST_SSH_SSHKEYGEN} -q -t rsa -N '' -f $@ + +t7: $(OBJ)/t7.out + ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t7.out > /dev/null + ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t7.out > /dev/null + +$(OBJ)/t8.out: + ${TEST_SSH_SSHKEYGEN} -q -t dsa -N '' -f $@ + +t8: $(OBJ)/t8.out + ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t8.out > /dev/null + ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t8.out > /dev/null + +$(OBJ)/t9.out: + test "${TEST_SSH_ECC}" != yes || \ + ${TEST_SSH_SSHKEYGEN} -q -t ecdsa -N '' -f $@ + +t9: $(OBJ)/t9.out + test "${TEST_SSH_ECC}" != yes || \ + ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t9.out > /dev/null + test "${TEST_SSH_ECC}" != yes || \ + ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t9.out > /dev/null + + +$(OBJ)/t10.out: + ${TEST_SSH_SSHKEYGEN} -q -t ed25519 -N '' -f $@ + +t10: $(OBJ)/t10.out + ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t10.out > /dev/null + ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t10.out > /dev/null + +t11: + ${TEST_SSH_SSHKEYGEN} -E sha256 -lf ${.CURDIR}/rsa_openssh.pub |\ + awk '{print $$2}' | diff - ${.CURDIR}/t11.ok + +$(OBJ)/t12.out: + ${TEST_SSH_SSHKEYGEN} -q -t ed25519 -N '' -C 'test-comment-1234' -f $@ + +t12: $(OBJ)/t12.out + ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t12.out.pub | grep test-comment-1234 >/dev/null + +t-exec: ${LTESTS:=.sh} + @if [ "x$?" = "x" ]; then exit 0; fi; \ + for TEST in ""$?; do \ + echo "run test $${TEST}" ... 1>&2; \ + (env SUDO="${SUDO}" TEST_ENV=${TEST_ENV} ${TEST_SHELL} ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \ + done + +t-exec-interop: ${INTEROP_TESTS:=.sh} + @if [ "x$?" = "x" ]; then exit 0; fi; \ + for TEST in ""$?; do \ + echo "run test $${TEST}" ... 1>&2; \ + (env SUDO="${SUDO}" TEST_ENV=${TEST_ENV} ${TEST_SHELL} ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \ + done + +# Not run by default +interop: ${INTEROP_TARGETS} + +# Unit tests, built by top-level Makefile +unit: + set -e ; if test -z "${SKIP_UNIT}" ; then \ + V="" ; \ + test "x${USE_VALGRIND}" = "x" || \ + V=${.CURDIR}/valgrind-unit.sh ; \ + $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ + $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ + -d ${.CURDIR}/unittests/sshkey/testdata ; \ + $$V ${.OBJDIR}/unittests/bitmap/test_bitmap ; \ + $$V ${.OBJDIR}/unittests/kex/test_kex ; \ + $$V ${.OBJDIR}/unittests/hostkeys/test_hostkeys \ + -d ${.CURDIR}/unittests/hostkeys/testdata ; \ + fi diff --git a/crypto/external/bsd/openssh/dist/regress/README.regress b/crypto/external/bsd/openssh/dist/regress/README.regress new file mode 100644 index 000000000..9b99bdacb --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/README.regress @@ -0,0 +1,104 @@ +Overview. + +$ ./configure && make tests + +You'll see some progress info. A failure will cause either the make to +abort or the driver script to report a "FATAL" failure. + +The test consists of 2 parts. The first is the file-based tests which is +driven by the Makefile, and the second is a set of network or proxycommand +based tests, which are driven by a driver script (test-exec.sh) which is +called multiple times by the Makefile. + +Failures in the first part will cause the Makefile to return an error. +Failures in the second part will print a "FATAL" message for the failed +test and continue. + +OpenBSD has a system-wide regression test suite. OpenSSH Portable's test +suite is based on OpenBSD's with modifications. + + +Environment variables. + +SUDO: path to sudo command, if desired. Note that some systems (notably + systems using PAM) require sudo to execute some tests. +TEST_SSH_TRACE: set to "yes" for verbose output from tests +TEST_SSH_QUIET: set to "yes" to suppress non-fatal output. +TEST_SSH_x: path to "ssh" command under test, where x=SSH,SSHD,SSHAGENT,SSHADD + SSHKEYGEN,SSHKEYSCAN,SFTP,SFTPSERVER +OBJ: used by test scripts to access build dir. +TEST_SHELL: shell used for running the test scripts. +TEST_SSH_PORT: TCP port to be used for the listening tests. +TEST_SSH_SSH_CONFOPTS: Configuration directives to be added to ssh_config + before running each test. +TEST_SSH_SSHD_CONFOPTS: Configuration directives to be added to sshd_config + before running each test. + + +Individual tests. + +You can run an individual test from the top-level Makefile, eg: +$ make tests LTESTS=agent-timeout + +If you need to manipulate the environment more you can invoke test-exec.sh +directly if you set up the path to find the binaries under test and the +test scripts themselves, for example: + +$ cd regress +$ PATH=`pwd`/..:$PATH:. TEST_SHELL=/bin/sh sh test-exec.sh `pwd` \ + agent-timeout.sh +ok agent timeout test + + +Files. + +test-exec.sh: the main test driver. Sets environment, creates config files +and keys and runs the specified test. + +At the time of writing, the individual tests are: +agent-timeout.sh: agent timeout test +agent.sh: simple agent test +broken-pipe.sh: broken pipe test +connect-privsep.sh: proxy connect with privsep +connect.sh: simple connect +exit-status.sh: remote exit status +forwarding.sh: local and remote forwarding +keygen-change.sh: change passphrase for key +keyscan.sh: keyscan +proto-mismatch.sh: protocol version mismatch +proto-version.sh: sshd version with different protocol combinations +proxy-connect.sh: proxy connect +sftp.sh: basic sftp put/get +ssh-com-client.sh: connect with ssh.com client +ssh-com-keygen.sh: ssh.com key import +ssh-com-sftp.sh: basic sftp put/get with ssh.com server +ssh-com.sh: connect to ssh.com server +stderr-after-eof.sh: stderr data after eof +stderr-data.sh: stderr data transfer +transfer.sh: transfer data +try-ciphers.sh: try ciphers +yes-head.sh: yes pipe head + + +Problems? + +Run the failing test with shell tracing (-x) turned on: +$ PATH=`pwd`/..:$PATH:. sh -x test-exec.sh `pwd` agent-timeout.sh + +Failed tests can be difficult to diagnose. Suggestions: +- run the individual test via ./test-exec.sh `pwd` [testname] +- set LogLevel to VERBOSE in test-exec.sh and enable syslogging of + auth.debug (eg to /var/log/authlog). + + +Known Issues. + +- Similarly, if you do not have "scp" in your system's $PATH then the + multiplex scp tests will fail (since the system's shell startup scripts + will determine where the shell started by sshd will look for scp). + +- Recent GNU coreutils deprecate "head -[n]": this will cause the yes-head + test to fail. The old behaviour can be restored by setting (and + exporting) _POSIX2_VERSION=199209 before running the tests. + +$Id: README.regress,v 1.12 2011/05/05 03:48:42 djm Exp $ diff --git a/crypto/external/bsd/openssh/dist/regress/addrmatch.sh b/crypto/external/bsd/openssh/dist/regress/addrmatch.sh new file mode 100644 index 000000000..1584bd405 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/addrmatch.sh @@ -0,0 +1,56 @@ +# $OpenBSD: addrmatch.sh,v 1.4 2012/05/13 01:42:32 dtucker Exp $ +# Placed in the Public Domain. + +tid="address match" + +mv $OBJ/sshd_proxy $OBJ/sshd_proxy_bak + +run_trial() +{ + user="$1"; addr="$2"; host="$3"; laddr="$4"; lport="$5" + expected="$6"; descr="$7" + + verbose "test $descr for $user $addr $host" + result=`${SSHD} -f $OBJ/sshd_proxy -T \ + -C user=${user},addr=${addr},host=${host},laddr=${laddr},lport=${lport} | \ + awk '/^forcecommand/ {print $2}'` + if [ "$result" != "$expected" ]; then + fail "failed '$descr' expected $expected got $result" + fi +} + +cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy +cat >>$OBJ/sshd_proxy < /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 2>/dev/null + 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/crypto/external/bsd/openssh/dist/regress/agent-pkcs11.sh b/crypto/external/bsd/openssh/dist/regress/agent-pkcs11.sh new file mode 100644 index 000000000..3aa20c8b1 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/agent-pkcs11.sh @@ -0,0 +1,71 @@ +# $OpenBSD: agent-pkcs11.sh,v 1.2 2015/01/12 11:46:32 djm Exp $ +# Placed in the Public Domain. + +tid="pkcs11 agent test" + +TEST_SSH_PIN="" +TEST_SSH_PKCS11=/usr/local/lib/soft-pkcs11.so.0.0 + +test -f "$TEST_SSH_PKCS11" || fatal "$TEST_SSH_PKCS11 does not exist" + +# setup environment for soft-pkcs11 token +SOFTPKCS11RC=$OBJ/pkcs11.info +export SOFTPKCS11RC +# prevent ssh-agent from calling ssh-askpass +SSH_ASKPASS=/usr/bin/true +export SSH_ASKPASS +unset DISPLAY + +# start command w/o tty, so ssh-add accepts pin from stdin +notty() { + perl -e 'use POSIX; POSIX::setsid(); + if (fork) { wait; exit($? >> 8); } else { exec(@ARGV) }' "$@" +} + +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 "generating key/cert" + rm -f $OBJ/pkcs11.key $OBJ/pkcs11.crt + openssl genrsa -out $OBJ/pkcs11.key 2048 > /dev/null 2>&1 + chmod 600 $OBJ/pkcs11.key + openssl req -key $OBJ/pkcs11.key -new -x509 \ + -out $OBJ/pkcs11.crt -text -subj '/CN=pkcs11 test' > /dev/null + printf "a\ta\t$OBJ/pkcs11.crt\t$OBJ/pkcs11.key" > $SOFTPKCS11RC + # add to authorized keys + ${SSHKEYGEN} -y -f $OBJ/pkcs11.key > $OBJ/authorized_keys_$USER + + trace "add pkcs11 key to agent" + echo ${TEST_SSH_PIN} | notty ${SSHADD} -s ${TEST_SSH_PKCS11} > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then + fail "ssh-add -s failed: exit code $r" + fi + + trace "pkcs11 list via agent" + ${SSHADD} -l > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then + fail "ssh-add -l failed: exit code $r" + fi + + trace "pkcs11 connect via agent" + ${SSH} -2 -F $OBJ/ssh_proxy somehost exit 5 + r=$? + if [ $r -ne 5 ]; then + fail "ssh connect failed (exit code $r)" + fi + + trace "remove pkcs11 keys" + echo ${TEST_SSH_PIN} | notty ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then + fail "ssh-add -e failed: exit code $r" + fi + + trace "kill agent" + ${SSHAGENT} -k > /dev/null +fi diff --git a/crypto/external/bsd/openssh/dist/regress/agent-ptrace.sh b/crypto/external/bsd/openssh/dist/regress/agent-ptrace.sh new file mode 100644 index 000000000..1912ca8f9 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/agent-ptrace.sh @@ -0,0 +1,61 @@ +# $OpenBSD: agent-ptrace.sh,v 1.2 2014/02/27 21:21:25 djm Exp $ +# Placed in the Public Domain. + +tid="disallow agent ptrace attach" + +if have_prog uname ; then + case `uname` in + AIX|CYGWIN*|OSF1) + echo "skipped (not supported on this platform)" + exit 0 + ;; + esac +fi + +if have_prog gdb ; then + : ok +else + echo "skipped (gdb not found)" + exit 0 +fi + +if $OBJ/setuid-allowed ${SSHAGENT} ; then + : ok +else + echo "skipped (${SSHAGENT} is mounted on a no-setuid filesystem)" + exit 0 +fi + +if test -z "$SUDO" ; then + echo "skipped (SUDO not set)" + exit 0 +else + $SUDO chown 0 ${SSHAGENT} + $SUDO chgrp 0 ${SSHAGENT} + $SUDO chmod 2755 ${SSHAGENT} +fi + +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 + r=$? + if [ $r -ne 0 ]; then + fail "gdb failed: exit code $r" + fi + egrep 'ptrace: Operation not permitted.|procfs:.*Permission denied.|ttrace.*Permission denied.|procfs:.*: Invalid argument.|Unable to access task ' >/dev/null ${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/crypto/external/bsd/openssh/dist/regress/agent-timeout.sh b/crypto/external/bsd/openssh/dist/regress/agent-timeout.sh new file mode 100644 index 000000000..9598c2032 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/agent-timeout.sh @@ -0,0 +1,36 @@ +# $OpenBSD: agent-timeout.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="agent timeout test" + +SSHAGENT_TIMEOUT=10 + +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 ${SSH_KEYTYPES}; do + ${SSHADD} -t ${SSHAGENT_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*${SSHAGENT_TIMEOUT} seconds" + sleep ${SSHAGENT_TIMEOUT} + sleep ${SSHAGENT_TIMEOUT} + ${SSHADD} -l 2> /dev/null | grep 'The agent has no identities.' >/dev/null + 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/crypto/external/bsd/openssh/dist/regress/agent.sh b/crypto/external/bsd/openssh/dist/regress/agent.sh new file mode 100644 index 000000000..c5e2794b7 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/agent.sh @@ -0,0 +1,81 @@ +# $OpenBSD: agent.sh,v 1.11 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="simple agent test" + +SSH_AUTH_SOCK=/nonexistent ${SSHADD} -l > /dev/null 2>&1 +if [ $? -ne 2 ]; then + fail "ssh-add -l did not fail with exit code 2" +fi + +trace "start agent" +eval `${SSHAGENT} -s` > /dev/null +r=$? +if [ $r -ne 0 ]; then + fail "could not start ssh-agent: exit code $r" +else + ${SSHADD} -l > /dev/null 2>&1 + if [ $? -ne 1 ]; then + fail "ssh-add -l did not fail with exit code 1" + fi + trace "overwrite authorized keys" + printf '' > $OBJ/authorized_keys_$USER + for t in ${SSH_KEYTYPES}; do + # generate user key for agent + rm -f $OBJ/$t-agent + ${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t-agent ||\ + fail "ssh-keygen for $t-agent failed" + # add to authorized keys + cat $OBJ/$t-agent.pub >> $OBJ/authorized_keys_$USER + # add privat key to agent + ${SSHADD} $OBJ/$t-agent > /dev/null 2>&1 + if [ $? -ne 0 ]; then + fail "ssh-add did succeed exit code 0" + fi + done + ${SSHADD} -l > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then + fail "ssh-add -l failed: exit code $r" + fi + # the same for full pubkey output + ${SSHADD} -L > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then + fail "ssh-add -L failed: exit code $r" + fi + + trace "simple connect via agent" + for p in ${SSH_PROTOCOLS}; do + ${SSH} -$p -F $OBJ/ssh_proxy somehost exit 5$p + r=$? + if [ $r -ne 5$p ]; then + fail "ssh connect with protocol $p failed (exit code $r)" + fi + done + + trace "agent forwarding" + for p in ${SSH_PROTOCOLS}; do + ${SSH} -A -$p -F $OBJ/ssh_proxy somehost ${SSHADD} -l > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then + fail "ssh-add -l via agent fwd proto $p failed (exit code $r)" + fi + ${SSH} -A -$p -F $OBJ/ssh_proxy somehost \ + "${SSH} -$p -F $OBJ/ssh_proxy somehost exit 5$p" + r=$? + if [ $r -ne 5$p ]; then + fail "agent fwd proto $p failed (exit code $r)" + fi + done + + trace "delete all agent keys" + ${SSHADD} -D > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then + fail "ssh-add -D failed: exit code $r" + fi + + trace "kill agent" + ${SSHAGENT} -k > /dev/null +fi diff --git a/crypto/external/bsd/openssh/dist/regress/banner.sh b/crypto/external/bsd/openssh/dist/regress/banner.sh new file mode 100644 index 000000000..0b9c95007 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/banner.sh @@ -0,0 +1,44 @@ +# $OpenBSD: banner.sh,v 1.2 2003/10/11 11:49:49 dtucker Exp $ +# Placed in the Public Domain. + +tid="banner" +echo "Banner $OBJ/banner.in" >> $OBJ/sshd_proxy + +rm -f $OBJ/banner.out $OBJ/banner.in $OBJ/empty.in +touch $OBJ/empty.in + +trace "test missing banner file" +verbose "test $tid: missing banner file" +( ${SSH} -2 -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \ + cmp $OBJ/empty.in $OBJ/banner.out ) || \ + fail "missing banner file" + +for s in 0 10 100 1000 10000 100000 ; do + if [ "$s" = "0" ]; then + # create empty banner + touch $OBJ/banner.in + elif [ "$s" = "10" ]; then + # create 10-byte banner file + echo "abcdefghi" >$OBJ/banner.in + else + # increase size 10x + cp $OBJ/banner.in $OBJ/banner.out + for i in 0 1 2 3 4 5 6 7 8 ; do + cat $OBJ/banner.out >> $OBJ/banner.in + done + fi + + trace "test banner size $s" + verbose "test $tid: size $s" + ( ${SSH} -2 -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \ + cmp $OBJ/banner.in $OBJ/banner.out ) || \ + fail "banner size $s mismatch" +done + +trace "test suppress banner (-q)" +verbose "test $tid: suppress banner (-q)" +( ${SSH} -q -2 -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \ + cmp $OBJ/empty.in $OBJ/banner.out ) || \ + fail "suppress banner (-q)" + +rm -f $OBJ/banner.out $OBJ/banner.in $OBJ/empty.in diff --git a/crypto/external/bsd/openssh/dist/regress/broken-pipe.sh b/crypto/external/bsd/openssh/dist/regress/broken-pipe.sh new file mode 100644 index 000000000..a416f7a3b --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/broken-pipe.sh @@ -0,0 +1,15 @@ +# $OpenBSD: broken-pipe.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="broken pipe test" + +for p in ${SSH_PROTOCOLS}; do + trace "protocol $p" + for i in 1 2 3 4; do + ${SSH} -$p -F $OBJ/ssh_config_config nexthost echo $i 2> /dev/null | true + r=$? + if [ $r -ne 0 ]; then + fail "broken pipe returns $r for protocol $p" + fi + done +done diff --git a/crypto/external/bsd/openssh/dist/regress/brokenkeys.sh b/crypto/external/bsd/openssh/dist/regress/brokenkeys.sh new file mode 100644 index 000000000..3e70c348a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/brokenkeys.sh @@ -0,0 +1,23 @@ +# $OpenBSD: brokenkeys.sh,v 1.1 2004/10/29 23:59:22 djm Exp $ +# Placed in the Public Domain. + +tid="broken keys" + +KEYS="$OBJ/authorized_keys_${USER}" + +start_sshd + +mv ${KEYS} ${KEYS}.bak + +# Truncated key +echo "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEABTM= bad key" > $KEYS +cat ${KEYS}.bak >> ${KEYS} +cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER + +${SSH} -2 -F $OBJ/ssh_config somehost true +if [ $? -ne 0 ]; then + fail "ssh connect with protocol $p failed" +fi + +mv ${KEYS}.bak ${KEYS} + diff --git a/crypto/external/bsd/openssh/dist/regress/cert-hostkey.sh b/crypto/external/bsd/openssh/dist/regress/cert-hostkey.sh new file mode 100644 index 000000000..3f53922c8 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/cert-hostkey.sh @@ -0,0 +1,302 @@ +# $OpenBSD: cert-hostkey.sh,v 1.13 2015/07/10 06:23:25 markus Exp $ +# Placed in the Public Domain. + +tid="certified host keys" + +rm -f $OBJ/known_hosts-cert* $OBJ/host_ca_key* $OBJ/host_revoked_* +rm -f $OBJ/cert_host_key* $OBJ/host_krl_* + +# Allow all hostkey/pubkey types, prefer certs for the client +types="" +for i in `$SSH -Q key`; do + if [ -z "$types" ]; then + types="$i" + continue + fi + case "$i" in + *cert*) types="$i,$types";; + *) types="$types,$i";; + esac +done +( + echo "HostKeyAlgorithms ${types}" + echo "PubkeyAcceptedKeyTypes *" +) >> $OBJ/ssh_proxy +cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak +( + echo "HostKeyAlgorithms *" + echo "PubkeyAcceptedKeyTypes *" +) >> $OBJ/sshd_proxy_bak + +HOSTS='localhost-with-alias,127.0.0.1,::1' + +# Create a CA key and add it to known hosts. Ed25519 chosed for speed. +${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/host_ca_key ||\ + fail "ssh-keygen of host_ca_key failed" +( + printf '@cert-authority ' + printf "$HOSTS " + cat $OBJ/host_ca_key.pub +) > $OBJ/known_hosts-cert.orig +cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert + +# Plain text revocation files +touch $OBJ/host_revoked_empty +touch $OBJ/host_revoked_plain +touch $OBJ/host_revoked_cert +cp $OBJ/host_ca_key.pub $OBJ/host_revoked_ca + +PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'` + +# Prepare certificate, plain key and CA KRLs +${SSHKEYGEN} -kf $OBJ/host_krl_empty || fatal "KRL init failed" +${SSHKEYGEN} -kf $OBJ/host_krl_plain || fatal "KRL init failed" +${SSHKEYGEN} -kf $OBJ/host_krl_cert || fatal "KRL init failed" +${SSHKEYGEN} -kf $OBJ/host_krl_ca $OBJ/host_ca_key.pub \ + || fatal "KRL init failed" + +# Generate and sign host keys +serial=1 +for ktype in $PLAIN_TYPES ; do + verbose "$tid: sign host ${ktype} cert" + # Generate and sign a host key + ${SSHKEYGEN} -q -N '' -t ${ktype} \ + -f $OBJ/cert_host_key_${ktype} || \ + fatal "ssh-keygen of cert_host_key_${ktype} failed" + ${SSHKEYGEN} -ukf $OBJ/host_krl_plain \ + $OBJ/cert_host_key_${ktype}.pub || fatal "KRL update failed" + cat $OBJ/cert_host_key_${ktype}.pub >> $OBJ/host_revoked_plain + ${SSHKEYGEN} -h -q -s $OBJ/host_ca_key -z $serial \ + -I "regress host key for $USER" \ + -n $HOSTS $OBJ/cert_host_key_${ktype} || + fatal "couldn't sign cert_host_key_${ktype}" + ${SSHKEYGEN} -ukf $OBJ/host_krl_cert \ + $OBJ/cert_host_key_${ktype}-cert.pub || \ + fatal "KRL update failed" + cat $OBJ/cert_host_key_${ktype}-cert.pub >> $OBJ/host_revoked_cert + serial=`expr $serial + 1` +done + +attempt_connect() { + _ident="$1" + _expect_success="$2" + shift; shift + verbose "$tid: $_ident expect success $_expect_success" + cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert + ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ + -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ + "$@" -F $OBJ/ssh_proxy somehost true + _r=$? + if [ "x$_expect_success" = "xyes" ] ; then + if [ $_r -ne 0 ]; then + fail "ssh cert connect $_ident failed" + fi + else + if [ $_r -eq 0 ]; then + fail "ssh cert connect $_ident succeeded unexpectedly" + fi + fi +} + +# Basic connect and revocation tests. +for privsep in yes no ; do + for ktype in $PLAIN_TYPES ; do + verbose "$tid: host ${ktype} cert connect privsep $privsep" + ( + cat $OBJ/sshd_proxy_bak + echo HostKey $OBJ/cert_host_key_${ktype} + echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub + echo UsePrivilegeSeparation $privsep + ) > $OBJ/sshd_proxy + + # test name expect success + attempt_connect "$ktype basic connect" "yes" + attempt_connect "$ktype empty KRL" "yes" \ + -oRevokedHostKeys=$OBJ/host_krl_empty + attempt_connect "$ktype KRL w/ plain key revoked" "no" \ + -oRevokedHostKeys=$OBJ/host_krl_plain + attempt_connect "$ktype KRL w/ cert revoked" "no" \ + -oRevokedHostKeys=$OBJ/host_krl_cert + attempt_connect "$ktype KRL w/ CA revoked" "no" \ + -oRevokedHostKeys=$OBJ/host_krl_ca + attempt_connect "$ktype empty plaintext revocation" "yes" \ + -oRevokedHostKeys=$OBJ/host_revoked_empty + attempt_connect "$ktype plain key plaintext revocation" "no" \ + -oRevokedHostKeys=$OBJ/host_revoked_plain + attempt_connect "$ktype cert plaintext revocation" "no" \ + -oRevokedHostKeys=$OBJ/host_revoked_cert + attempt_connect "$ktype CA plaintext revocation" "no" \ + -oRevokedHostKeys=$OBJ/host_revoked_ca + done +done + +# Revoked certificates with key present +( + printf '@cert-authority ' + printf "$HOSTS " + cat $OBJ/host_ca_key.pub + for ktype in $PLAIN_TYPES ; do + test -f "$OBJ/cert_host_key_${ktype}.pub" || fatal "no pubkey" + printf "@revoked * `cat $OBJ/cert_host_key_${ktype}.pub`\n" + done +) > $OBJ/known_hosts-cert.orig +cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert +for privsep in yes no ; do + for ktype in $PLAIN_TYPES ; do + verbose "$tid: host ${ktype} revoked cert privsep $privsep" + ( + cat $OBJ/sshd_proxy_bak + echo HostKey $OBJ/cert_host_key_${ktype} + echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub + echo UsePrivilegeSeparation $privsep + ) > $OBJ/sshd_proxy + + cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert + ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ + -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect succeeded unexpectedly" + fi + done +done + +# Revoked CA +( + printf '@cert-authority ' + printf "$HOSTS " + cat $OBJ/host_ca_key.pub + printf '@revoked ' + printf "* " + cat $OBJ/host_ca_key.pub +) > $OBJ/known_hosts-cert.orig +cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert +for ktype in $PLAIN_TYPES ; do + verbose "$tid: host ${ktype} revoked cert" + ( + cat $OBJ/sshd_proxy_bak + echo HostKey $OBJ/cert_host_key_${ktype} + echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub + ) > $OBJ/sshd_proxy + cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert + ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ + -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect succeeded unexpectedly" + fi +done + +# Create a CA key and add it to known hosts +( + printf '@cert-authority ' + printf "$HOSTS " + cat $OBJ/host_ca_key.pub +) > $OBJ/known_hosts-cert.orig +cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert + +test_one() { + ident=$1 + result=$2 + sign_opts=$3 + + for kt in rsa ed25519 ; do + ${SSHKEYGEN} -q -s $OBJ/host_ca_key \ + -I "regress host key for $USER" \ + $sign_opts $OBJ/cert_host_key_${kt} || + fail "couldn't sign cert_host_key_${kt}" + ( + cat $OBJ/sshd_proxy_bak + echo HostKey $OBJ/cert_host_key_${kt} + echo HostCertificate $OBJ/cert_host_key_${kt}-cert.pub + ) > $OBJ/sshd_proxy + + cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert + ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ + -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + rc=$? + if [ "x$result" = "xsuccess" ] ; then + if [ $rc -ne 0 ]; then + fail "ssh cert connect $ident failed unexpectedly" + fi + else + if [ $rc -eq 0 ]; then + fail "ssh cert connect $ident succeeded unexpectedly" + fi + fi + done +} + +test_one "user-certificate" failure "-n $HOSTS" +test_one "empty principals" success "-h" +test_one "wrong principals" failure "-h -n foo" +test_one "cert not yet valid" failure "-h -V20200101:20300101" +test_one "cert expired" failure "-h -V19800101:19900101" +test_one "cert valid interval" success "-h -V-1w:+2w" +test_one "cert has constraints" failure "-h -Oforce-command=false" + +# Check downgrade of cert to raw key when no CA found +for ktype in $PLAIN_TYPES ; do + rm -f $OBJ/known_hosts-cert $OBJ/cert_host_key* + verbose "$tid: host ${ktype} ${v} cert downgrade to raw key" + # Generate and sign a host key + ${SSHKEYGEN} -q -N '' -t ${ktype} \ + -f $OBJ/cert_host_key_${ktype} || \ + fail "ssh-keygen of cert_host_key_${ktype} failed" + ${SSHKEYGEN} -t ${v} -h -q -s $OBJ/host_ca_key \ + -I "regress host key for $USER" \ + -n $HOSTS $OBJ/cert_host_key_${ktype} || + fail "couldn't sign cert_host_key_${ktype}" + ( + printf "$HOSTS " + cat $OBJ/cert_host_key_${ktype}.pub + ) > $OBJ/known_hosts-cert + ( + cat $OBJ/sshd_proxy_bak + echo HostKey $OBJ/cert_host_key_${ktype} + echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub + ) > $OBJ/sshd_proxy + + ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ + -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ + -F $OBJ/ssh_proxy somehost true + if [ $? -ne 0 ]; then + fail "ssh cert connect failed" + fi +done + +# Wrong certificate +( + printf '@cert-authority ' + printf "$HOSTS " + cat $OBJ/host_ca_key.pub +) > $OBJ/known_hosts-cert.orig +cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert +for kt in $PLAIN_TYPES ; do + rm -f $OBJ/cert_host_key* + # Self-sign key + ${SSHKEYGEN} -q -N '' -t ${kt} \ + -f $OBJ/cert_host_key_${kt} || \ + fail "ssh-keygen of cert_host_key_${kt} failed" + ${SSHKEYGEN} -t ${v} -h -q -s $OBJ/cert_host_key_${kt} \ + -I "regress host key for $USER" \ + -n $HOSTS $OBJ/cert_host_key_${kt} || + fail "couldn't sign cert_host_key_${kt}" + verbose "$tid: host ${kt} connect wrong cert" + ( + cat $OBJ/sshd_proxy_bak + echo HostKey $OBJ/cert_host_key_${kt} + echo HostCertificate $OBJ/cert_host_key_${kt}-cert.pub + ) > $OBJ/sshd_proxy + + cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert + ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ + -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ + -F $OBJ/ssh_proxy -q somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect $ident succeeded unexpectedly" + fi +done + +rm -f $OBJ/known_hosts-cert* $OBJ/host_ca_key* $OBJ/cert_host_key* diff --git a/crypto/external/bsd/openssh/dist/regress/cert-userkey.sh b/crypto/external/bsd/openssh/dist/regress/cert-userkey.sh new file mode 100644 index 000000000..c38c00a02 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/cert-userkey.sh @@ -0,0 +1,362 @@ +# $OpenBSD: cert-userkey.sh,v 1.14 2015/07/10 06:23:25 markus Exp $ +# Placed in the Public Domain. + +tid="certified user keys" + +rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* +cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak +cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak + +PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` + +kname() { + n=`echo "$1" | sed 's/^dsa/ssh-dss/;s/^rsa/ssh-rsa/;s/^ed/ssh-ed/'` + echo "$n*,ssh-rsa*,ssh-ed25519*" +} + +# Create a CA key +${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_ca_key ||\ + fail "ssh-keygen of user_ca_key failed" + +# Generate and sign user keys +for ktype in $PLAIN_TYPES ; do + verbose "$tid: sign user ${ktype} cert" + ${SSHKEYGEN} -q -N '' -t ${ktype} \ + -f $OBJ/cert_user_key_${ktype} || \ + fail "ssh-keygen of cert_user_key_${ktype} failed" + ${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \ + -z $$ -n ${USER},mekmitasdigoat $OBJ/cert_user_key_${ktype} || + fail "couldn't sign cert_user_key_${ktype}" +done + +# Test explicitly-specified principals +for ktype in $PLAIN_TYPES ; do + t=$(kname $ktype) + for privsep in yes no ; do + _prefix="${ktype} privsep $privsep" + + # Setup for AuthorizedPrincipalsFile + rm -f $OBJ/authorized_keys_$USER + ( + cat $OBJ/sshd_proxy_bak + echo "UsePrivilegeSeparation $privsep" + echo "AuthorizedPrincipalsFile " \ + "$OBJ/authorized_principals_%u" + echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" + echo "PubkeyAcceptedKeyTypes ${t}" + ) > $OBJ/sshd_proxy + ( + cat $OBJ/ssh_proxy_bak + echo "PubkeyAcceptedKeyTypes ${t}" + ) > $OBJ/ssh_proxy + + # Missing authorized_principals + verbose "$tid: ${_prefix} missing authorized_principals" + rm -f $OBJ/authorized_principals_$USER + ${SSH} -2i $OBJ/cert_user_key_${ktype} \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect succeeded unexpectedly" + fi + + # Empty authorized_principals + verbose "$tid: ${_prefix} empty authorized_principals" + echo > $OBJ/authorized_principals_$USER + ${SSH} -2i $OBJ/cert_user_key_${ktype} \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect succeeded unexpectedly" + fi + + # Wrong authorized_principals + verbose "$tid: ${_prefix} wrong authorized_principals" + echo gregorsamsa > $OBJ/authorized_principals_$USER + ${SSH} -2i $OBJ/cert_user_key_${ktype} \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect succeeded unexpectedly" + fi + + # Correct authorized_principals + verbose "$tid: ${_prefix} correct authorized_principals" + echo mekmitasdigoat > $OBJ/authorized_principals_$USER + ${SSH} -2i $OBJ/cert_user_key_${ktype} \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -ne 0 ]; then + fail "ssh cert connect failed" + fi + + # authorized_principals with bad key option + verbose "$tid: ${_prefix} authorized_principals bad key opt" + echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_$USER + ${SSH} -2i $OBJ/cert_user_key_${ktype} \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect succeeded unexpectedly" + fi + + # authorized_principals with command=false + verbose "$tid: ${_prefix} authorized_principals command=false" + echo 'command="false" mekmitasdigoat' > \ + $OBJ/authorized_principals_$USER + ${SSH} -2i $OBJ/cert_user_key_${ktype} \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect succeeded unexpectedly" + fi + + + # authorized_principals with command=true + verbose "$tid: ${_prefix} authorized_principals command=true" + echo 'command="true" mekmitasdigoat' > \ + $OBJ/authorized_principals_$USER + ${SSH} -2i $OBJ/cert_user_key_${ktype} \ + -F $OBJ/ssh_proxy somehost false >/dev/null 2>&1 + if [ $? -ne 0 ]; then + fail "ssh cert connect failed" + fi + + # Setup for principals= key option + rm -f $OBJ/authorized_principals_$USER + ( + cat $OBJ/sshd_proxy_bak + echo "UsePrivilegeSeparation $privsep" + echo "PubkeyAcceptedKeyTypes ${t}" + ) > $OBJ/sshd_proxy + ( + cat $OBJ/ssh_proxy_bak + echo "PubkeyAcceptedKeyTypes ${t}" + ) > $OBJ/ssh_proxy + + # Wrong principals list + verbose "$tid: ${_prefix} wrong principals key option" + ( + printf 'cert-authority,principals="gregorsamsa" ' + cat $OBJ/user_ca_key.pub + ) > $OBJ/authorized_keys_$USER + ${SSH} -2i $OBJ/cert_user_key_${ktype} \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect succeeded unexpectedly" + fi + + # Correct principals list + verbose "$tid: ${_prefix} correct principals key option" + ( + printf 'cert-authority,principals="mekmitasdigoat" ' + cat $OBJ/user_ca_key.pub + ) > $OBJ/authorized_keys_$USER + ${SSH} -2i $OBJ/cert_user_key_${ktype} \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -ne 0 ]; then + fail "ssh cert connect failed" + fi + done +done + +basic_tests() { + auth=$1 + if test "x$auth" = "xauthorized_keys" ; then + # Add CA to authorized_keys + ( + printf 'cert-authority ' + cat $OBJ/user_ca_key.pub + ) > $OBJ/authorized_keys_$USER + else + echo > $OBJ/authorized_keys_$USER + extra_sshd="TrustedUserCAKeys $OBJ/user_ca_key.pub" + fi + + for ktype in $PLAIN_TYPES ; do + t=$(kname $ktype) + for privsep in yes no ; do + _prefix="${ktype} privsep $privsep $auth" + # Simple connect + verbose "$tid: ${_prefix} connect" + ( + cat $OBJ/sshd_proxy_bak + echo "UsePrivilegeSeparation $privsep" + echo "PubkeyAcceptedKeyTypes ${t}" + echo "$extra_sshd" + ) > $OBJ/sshd_proxy + ( + cat $OBJ/ssh_proxy_bak + echo "PubkeyAcceptedKeyTypes ${t}" + ) > $OBJ/ssh_proxy + + ${SSH} -2i $OBJ/cert_user_key_${ktype} \ + -F $OBJ/ssh_proxy somehost true + if [ $? -ne 0 ]; then + fail "ssh cert connect failed" + fi + + # Revoked keys + verbose "$tid: ${_prefix} revoked key" + ( + cat $OBJ/sshd_proxy_bak + echo "UsePrivilegeSeparation $privsep" + echo "RevokedKeys $OBJ/cert_user_key_revoked" + echo "PubkeyAcceptedKeyTypes ${t}" + echo "$extra_sshd" + ) > $OBJ/sshd_proxy + cp $OBJ/cert_user_key_${ktype}.pub \ + $OBJ/cert_user_key_revoked + ${SSH} -2i $OBJ/cert_user_key_${ktype} \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect succeeded unexpecedly" + fi + verbose "$tid: ${_prefix} revoked via KRL" + rm $OBJ/cert_user_key_revoked + ${SSHKEYGEN} -kqf $OBJ/cert_user_key_revoked \ + $OBJ/cert_user_key_${ktype}.pub + ${SSH} -2i $OBJ/cert_user_key_${ktype} \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect succeeded unexpecedly" + fi + verbose "$tid: ${_prefix} empty KRL" + ${SSHKEYGEN} -kqf $OBJ/cert_user_key_revoked + ${SSH} -2i $OBJ/cert_user_key_${ktype} \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -ne 0 ]; then + fail "ssh cert connect failed" + fi + done + + # Revoked CA + verbose "$tid: ${ktype} $auth revoked CA key" + ( + cat $OBJ/sshd_proxy_bak + echo "RevokedKeys $OBJ/user_ca_key.pub" + echo "PubkeyAcceptedKeyTypes ${t}" + echo "$extra_sshd" + ) > $OBJ/sshd_proxy + ${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \ + somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect succeeded unexpecedly" + fi + done + + verbose "$tid: $auth CA does not authenticate" + ( + cat $OBJ/sshd_proxy_bak + echo "PubkeyAcceptedKeyTypes ${t}" + echo "$extra_sshd" + ) > $OBJ/sshd_proxy + verbose "$tid: ensure CA key does not authenticate user" + ${SSH} -2i $OBJ/user_ca_key \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect with CA key succeeded unexpectedly" + fi +} + +basic_tests authorized_keys +basic_tests TrustedUserCAKeys + +test_one() { + ident=$1 + result=$2 + sign_opts=$3 + auth_choice=$4 + auth_opt=$5 + + if test "x$auth_choice" = "x" ; then + auth_choice="authorized_keys TrustedUserCAKeys" + fi + + for auth in $auth_choice ; do + for ktype in rsa ed25519 ; do + cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy + if test "x$auth" = "xauthorized_keys" ; then + # Add CA to authorized_keys + ( + printf "cert-authority${auth_opt} " + cat $OBJ/user_ca_key.pub + ) > $OBJ/authorized_keys_$USER + else + echo > $OBJ/authorized_keys_$USER + echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" \ + >> $OBJ/sshd_proxy + echo "PubkeyAcceptedKeyTypes ${t}*" \ + >> $OBJ/sshd_proxy + if test "x$auth_opt" != "x" ; then + echo $auth_opt >> $OBJ/sshd_proxy + fi + fi + + verbose "$tid: $ident auth $auth expect $result $ktype" + ${SSHKEYGEN} -q -s $OBJ/user_ca_key \ + -I "regress user key for $USER" \ + $sign_opts $OBJ/cert_user_key_${ktype} || + fail "couldn't sign cert_user_key_${ktype}" + + ${SSH} -2i $OBJ/cert_user_key_${ktype} \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + rc=$? + if [ "x$result" = "xsuccess" ] ; then + if [ $rc -ne 0 ]; then + fail "$ident failed unexpectedly" + fi + else + if [ $rc -eq 0 ]; then + fail "$ident succeeded unexpectedly" + fi + fi + done + done +} + +test_one "correct principal" success "-n ${USER}" +test_one "host-certificate" failure "-n ${USER} -h" +test_one "wrong principals" failure "-n foo" +test_one "cert not yet valid" failure "-n ${USER} -V20200101:20300101" +test_one "cert expired" failure "-n ${USER} -V19800101:19900101" +test_one "cert valid interval" success "-n ${USER} -V-1w:+2w" +test_one "wrong source-address" failure "-n ${USER} -Osource-address=10.0.0.0/8" +test_one "force-command" failure "-n ${USER} -Oforce-command=false" + +# Behaviour is different here: TrustedUserCAKeys doesn't allow empty principals +test_one "empty principals" success "" authorized_keys +test_one "empty principals" failure "" TrustedUserCAKeys + +# Check explicitly-specified principals: an empty principals list in the cert +# should always be refused. + +# AuthorizedPrincipalsFile +rm -f $OBJ/authorized_keys_$USER +echo mekmitasdigoat > $OBJ/authorized_principals_$USER +test_one "AuthorizedPrincipalsFile principals" success "-n mekmitasdigoat" \ + TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" +test_one "AuthorizedPrincipalsFile no principals" failure "" \ + TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" + +# principals= key option +rm -f $OBJ/authorized_principals_$USER +test_one "principals key option principals" success "-n mekmitasdigoat" \ + authorized_keys ',principals="mekmitasdigoat"' +test_one "principals key option no principals" failure "" \ + authorized_keys ',principals="mekmitasdigoat"' + +# Wrong certificate +cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy +for ktype in $PLAIN_TYPES ; do + t=$(kname $ktype) + # Self-sign + ${SSHKEYGEN} -q -s $OBJ/cert_user_key_${ktype} -I \ + "regress user key for $USER" \ + -n $USER $OBJ/cert_user_key_${ktype} || + fail "couldn't sign cert_user_key_${ktype}" + verbose "$tid: user ${ktype} connect wrong cert" + ${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \ + somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect $ident succeeded unexpectedly" + fi +done + +rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* +rm -f $OBJ/authorized_principals_$USER + diff --git a/crypto/external/bsd/openssh/dist/regress/cfgmatch.sh b/crypto/external/bsd/openssh/dist/regress/cfgmatch.sh new file mode 100644 index 000000000..056296398 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/cfgmatch.sh @@ -0,0 +1,127 @@ +# $OpenBSD: cfgmatch.sh,v 1.9 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="sshd_config match" + +pidfile=$OBJ/remote_pid +fwdport=3301 +fwd="-L $fwdport:127.0.0.1:$PORT" + +echo "ExitOnForwardFailure=yes" >> $OBJ/ssh_config +echo "ExitOnForwardFailure=yes" >> $OBJ/ssh_proxy + +start_client() +{ + rm -f $pidfile + ${SSH} -q -$p $fwd "$@" somehost \ + exec sh -c \'"echo \$\$ > $pidfile; exec sleep 100"\' \ + >>$TEST_REGRESS_LOGFILE 2>&1 & + client_pid=$! + # Wait for remote end + n=0 + while test ! -f $pidfile ; do + sleep 1 + n=`expr $n + 1` + if test $n -gt 60; then + kill $client_pid + fatal "timeout waiting for background ssh" + fi + done +} + +stop_client() +{ + pid=`cat $pidfile` + if [ ! -z "$pid" ]; then + kill $pid + fi + wait +} + +cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak +echo "PermitOpen 127.0.0.1:1" >>$OBJ/sshd_config +echo "Match Address 127.0.0.1" >>$OBJ/sshd_config +echo "PermitOpen 127.0.0.1:$PORT" >>$OBJ/sshd_config + +grep -v AuthorizedKeysFile $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy +echo "AuthorizedKeysFile /dev/null" >>$OBJ/sshd_proxy +echo "PermitOpen 127.0.0.1:1" >>$OBJ/sshd_proxy +echo "Match user $USER" >>$OBJ/sshd_proxy +echo "AuthorizedKeysFile /dev/null $OBJ/authorized_keys_%u" >>$OBJ/sshd_proxy +echo "Match Address 127.0.0.1" >>$OBJ/sshd_proxy +echo "PermitOpen 127.0.0.1:$PORT" >>$OBJ/sshd_proxy + +start_sshd + +#set -x + +# Test Match + PermitOpen in sshd_config. This should be permitted +for p in ${SSH_PROTOCOLS}; do + trace "match permitopen localhost proto $p" + start_client -F $OBJ/ssh_config + ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \ + fail "match permitopen permit proto $p" + stop_client +done + +# Same but from different source. This should not be permitted +for p in ${SSH_PROTOCOLS}; do + trace "match permitopen proxy proto $p" + start_client -F $OBJ/ssh_proxy + ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \ + fail "match permitopen deny proto $p" + stop_client +done + +# Retry previous with key option, should also be denied. +cp /dev/null $OBJ/authorized_keys_$USER +for t in ${SSH_KEYTYPES}; do + printf 'permitopen="127.0.0.1:'$PORT'" ' >> $OBJ/authorized_keys_$USER + cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER +done +for p in ${SSH_PROTOCOLS}; do + trace "match permitopen proxy w/key opts proto $p" + start_client -F $OBJ/ssh_proxy + ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \ + fail "match permitopen deny w/key opt proto $p" + stop_client +done + +# Test both sshd_config and key options permitting the same dst/port pair. +# Should be permitted. +for p in ${SSH_PROTOCOLS}; do + trace "match permitopen localhost proto $p" + start_client -F $OBJ/ssh_config + ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \ + fail "match permitopen permit proto $p" + stop_client +done + +cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy +echo "PermitOpen 127.0.0.1:1 127.0.0.1:$PORT 127.0.0.2:2" >>$OBJ/sshd_proxy +echo "Match User $USER" >>$OBJ/sshd_proxy +echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy + +# Test that a Match overrides a PermitOpen in the global section +for p in ${SSH_PROTOCOLS}; do + trace "match permitopen proxy w/key opts proto $p" + start_client -F $OBJ/ssh_proxy + ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \ + fail "match override permitopen proto $p" + stop_client +done + +cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy +echo "PermitOpen 127.0.0.1:1 127.0.0.1:$PORT 127.0.0.2:2" >>$OBJ/sshd_proxy +echo "Match User NoSuchUser" >>$OBJ/sshd_proxy +echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy + +# Test that a rule that doesn't match doesn't override, plus test a +# PermitOpen entry that's not at the start of the list +for p in ${SSH_PROTOCOLS}; do + trace "nomatch permitopen proxy w/key opts proto $p" + start_client -F $OBJ/ssh_proxy + ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \ + fail "nomatch override permitopen proto $p" + stop_client +done diff --git a/crypto/external/bsd/openssh/dist/regress/cfgparse.sh b/crypto/external/bsd/openssh/dist/regress/cfgparse.sh new file mode 100644 index 000000000..736f38976 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/cfgparse.sh @@ -0,0 +1,75 @@ +# $OpenBSD: cfgparse.sh,v 1.5 2015/05/29 03:05:13 djm Exp $ +# Placed in the Public Domain. + +tid="config parse" + +# This is a reasonable proxy for IPv6 support. +if ! config_defined HAVE_STRUCT_IN6_ADDR ; then + SKIP_IPV6=yes +fi + +# We need to use the keys generated for the regression test because sshd -T +# will fail if we're not running with SUDO (no permissions for real keys) or +# if we are # running tests on a system that has never had sshd installed +# (keys won't exist). + +grep "HostKey " $OBJ/sshd_config > $OBJ/sshd_config_minimal +SSHD_KEYS="`cat $OBJ/sshd_config_minimal`" + +verbose "reparse minimal config" +($SUDO ${SSHD} -T -f $OBJ/sshd_config_minimal >$OBJ/sshd_config.1 && + $SUDO ${SSHD} -T -f $OBJ/sshd_config.1 >$OBJ/sshd_config.2 && + diff $OBJ/sshd_config.1 $OBJ/sshd_config.2) || fail "reparse minimal config" + +verbose "reparse regress config" +($SUDO ${SSHD} -T -f $OBJ/sshd_config >$OBJ/sshd_config.1 && + $SUDO ${SSHD} -T -f $OBJ/sshd_config.1 >$OBJ/sshd_config.2 && + diff $OBJ/sshd_config.1 $OBJ/sshd_config.2) || fail "reparse regress config" + +verbose "listenaddress order" +# expected output +cat > $OBJ/sshd_config.0 <> $OBJ/sshd_config.0 < $OBJ/sshd_config.1 <> $OBJ/sshd_config.1 <$OBJ/sshd_config.2 && + diff $OBJ/sshd_config.0 $OBJ/sshd_config.2) || \ + fail "listenaddress order 1" +# test 2: listenaddress first +cat > $OBJ/sshd_config.1 <> $OBJ/sshd_config.1 <$OBJ/sshd_config.2 && + diff $OBJ/sshd_config.0 $OBJ/sshd_config.2) || \ + fail "listenaddress order 2" + +# cleanup +rm -f $OBJ/sshd_config.[012] diff --git a/crypto/external/bsd/openssh/dist/regress/cipher-speed.sh b/crypto/external/bsd/openssh/dist/regress/cipher-speed.sh new file mode 100644 index 000000000..575dc2341 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/cipher-speed.sh @@ -0,0 +1,51 @@ +# $OpenBSD: cipher-speed.sh,v 1.13 2015/03/24 20:22:17 markus Exp $ +# Placed in the Public Domain. + +tid="cipher speed" + +getbytes () +{ + sed -n -e '/transferred/s/.*secs (\(.* bytes.sec\).*/\1/p' \ + -e '/copied/s/.*s, \(.* MB.s\).*/\1/p' +} + +tries="1 2" + +for c in `${SSH} -Q cipher`; do n=0; for m in `${SSH} -Q mac`; do + trace "proto 2 cipher $c mac $m" + for x in $tries; do + printf "%-60s" "$c/$m:" + ( ${SSH} -o 'compression no' \ + -F $OBJ/ssh_proxy -2 -m $m -c $c somehost \ + exec sh -c \'"dd of=/dev/null obs=32k"\' \ + < ${DATA} ) 2>&1 | getbytes + + if [ $? -ne 0 ]; then + fail "ssh -2 failed with mac $m cipher $c" + fi + done + # No point trying all MACs for AEAD ciphers since they are ignored. + if ${SSH} -Q cipher-auth | grep "^${c}\$" >/dev/null 2>&1 ; then + break + fi + n=`expr $n + 1` +done; done + +if ssh_version 1; then + ciphers="3des blowfish" +else + ciphers="" +fi +for c in $ciphers; do + trace "proto 1 cipher $c" + for x in $tries; do + printf "%-60s" "$c:" + ( ${SSH} -o 'compression no' \ + -F $OBJ/ssh_proxy -1 -c $c somehost \ + exec sh -c \'"dd of=/dev/null obs=32k"\' \ + < ${DATA} ) 2>&1 | getbytes + if [ $? -ne 0 ]; then + fail "ssh -1 failed with cipher $c" + fi + done +done diff --git a/crypto/external/bsd/openssh/dist/regress/conch-ciphers.sh b/crypto/external/bsd/openssh/dist/regress/conch-ciphers.sh new file mode 100644 index 000000000..199d863a0 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/conch-ciphers.sh @@ -0,0 +1,28 @@ +# $OpenBSD: conch-ciphers.sh,v 1.3 2013/05/17 04:29:14 dtucker Exp $ +# Placed in the Public Domain. + +tid="conch ciphers" + +if test "x$REGRESS_INTEROP_CONCH" != "xyes" ; then + echo "conch interop tests not enabled" + exit 0 +fi + +start_sshd + +for c in aes256-ctr aes256-cbc aes192-ctr aes192-cbc aes128-ctr aes128-cbc \ + cast128-cbc blowfish 3des-cbc ; do + verbose "$tid: cipher $c" + rm -f ${COPY} + # XXX the 2nd "cat" seems to be needed because of buggy FD handling + # in conch + ${CONCH} --identity $OBJ/rsa --port $PORT --user $USER -e none \ + --known-hosts $OBJ/known_hosts --notty --noagent --nox11 -n \ + 127.0.0.1 "cat ${DATA}" 2>/dev/null | cat > ${COPY} + if [ $? -ne 0 ]; then + fail "ssh cat $DATA failed" + fi + cmp ${DATA} ${COPY} || fail "corrupted copy" +done +rm -f ${COPY} + diff --git a/crypto/external/bsd/openssh/dist/regress/connect-privsep.sh b/crypto/external/bsd/openssh/dist/regress/connect-privsep.sh new file mode 100644 index 000000000..9a51f5690 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/connect-privsep.sh @@ -0,0 +1,36 @@ +# $OpenBSD: connect-privsep.sh,v 1.6 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="proxy connect with privsep" + +cp $OBJ/sshd_proxy $OBJ/sshd_proxy.orig +echo 'UsePrivilegeSeparation yes' >> $OBJ/sshd_proxy + +for p in ${SSH_PROTOCOLS}; do + ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true + if [ $? -ne 0 ]; then + fail "ssh privsep+proxyconnect protocol $p failed" + fi +done + +cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy +echo 'UsePrivilegeSeparation sandbox' >> $OBJ/sshd_proxy + +for p in ${SSH_PROTOCOLS}; do + ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true + if [ $? -ne 0 ]; then + # XXX replace this with fail once sandbox has stabilised + warn "ssh privsep/sandbox+proxyconnect protocol $p failed" + fi +done + +# Because sandbox is sensitive to changes in libc, especially malloc, retest +# with every malloc.conf option (and none). +for m in '' A F G H J P R S X '<' '>'; do + for p in ${SSH_PROTOCOLS}; do + env MALLOC_OPTIONS="$m" ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true + if [ $? -ne 0 ]; then + fail "ssh privsep/sandbox+proxyconnect protocol $p mopt '$m' failed" + fi + done +done diff --git a/crypto/external/bsd/openssh/dist/regress/connect.sh b/crypto/external/bsd/openssh/dist/regress/connect.sh new file mode 100644 index 000000000..f0d55d343 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/connect.sh @@ -0,0 +1,13 @@ +# $OpenBSD: connect.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="simple connect" + +start_sshd + +for p in ${SSH_PROTOCOLS}; do + ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true + if [ $? -ne 0 ]; then + fail "ssh connect with protocol $p failed" + fi +done diff --git a/crypto/external/bsd/openssh/dist/regress/core.13225 b/crypto/external/bsd/openssh/dist/regress/core.13225 new file mode 100755 index 0000000000000000000000000000000000000000..16ac83fabe4dc3ca9d8f67911e8bac08173d3b22 GIT binary patch literal 2372468 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%0DAs{ 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%0A97qP5tT){Qf)^`kdRwCT?C-HlrO5rzDU`~bg z6^1t25xEnCF7^}`JPUH41?{@Xb*aE9pZYXc23#!9V=Z!}ZzTjrKDKJk!B=ec98TiH zAA%)La5lm<2vc%}162t5GOe+s;&U-L;sfoDN7(~YkW2Vy{1$6U;9TtY$1rP@x`mcqqeRF3APG=e5ErDH!tPpP+wM%WDhRRG0gty0+)ZG5-hKQ`DtB zQ~&<Hzx;YkGk&FBvYTtLj(bCCsBDT{1z3o%HOLhpQb>LQ%_{GM#Lyb?RpQUyK_}DJj*n;sZ zY}Yh}IGmlB-xJ2`ch)7-@G}Y8zB^uTyArWVT-cDmyG8^aZ&frNd-fUJDpryGe%&Z)aP=SQ15E`K>*o*S;)`|>xWFQj! zsRM7EA0g;Pj1%-Rh(Fb@kP@;g1r7+Tc&(RJ8Bi+USqDjhJqwHJgxdc76V#)f_2jm& zfLNi0N0bYM^<#4@Vnqm}s-vp-3{!OtzzHJ;NSLl*B=1GCC-LAPf{(jFtc)-S#FWS< ztQAqS!22Y=1Hd4{^B69Dn}D~dn@|YXr2_MqZE;UcV_%4-o-hvL67|rr zweZ)qR|`La!W!yunzPx%tx5NQsI-PpuR*iw0zso6Tw09wW+`yd6haNMC&ZPI6nyF@ zeDh}+ham&Li)z_AB9h$(QSXq{b1+YK-{weD8mzEgE)9;1#ZWt%gxxy#q^orLHlAn* z#s_xaP-f;~;SaCQ$fyD7bHO|V&rbziMB*$5nKKxJYc6mw*2M8tm+5L-2G$s@@iJ>1 z&%4fIBAi}kiUk2NTfC+HJay+fcCNoQ{~h=*!r54yi^WlNZOstS zoi*-=e&QS2s`C+cFkx-3n0hAh>|%4ZnQ;sDeY{!vcH%t;fVtaySu-+mm;1mPYcvj* z;x2b>!#2Gm5c+kD1~97z2df9_Coj_?x1lAFEpu@1d-5XrLR|Y$Cnt92$UXAfmfJX= zb}o|NGyi>aozSMX;Z^+v?phg&wREUfHNbxZN=N6Ca*@a(SH7_eajM+u#Z$m6*2J~& zZ3sA}asTfClr*;mE^CCd%rXHO_LUHEG2RakqmPUU;AR9Pwa7mq_N%K!`cZDx^{Q%g z0uM-y&?0bZpNQ?lT}t&YtDaURmm%8e`@+~TR$hnG&jQK?cq7g@(z(0AEqW@}aB$kE zF{44TOKORg66ZtN!azelhm{UriQ>4nkMpJ&lx!)>4)y_HlW=XC7THJ}RX9)&%6}rB{hcNZ6ToL7GwWrU z5-}MOY?n{os#zmQ`Dw7DRwTK2>)}MAPevj3U!LdW|$oSYY`FDC*bPq#zWPgMd>~ zWEWW0jNk%v|BSiOT+hy$_>E}a2zVoc!g8TRH|63;KhBdGJLARr&Wczm8?e(KD<)tB zO7UI`N6l7?fMjCntumZ)F#01IHcz4{M59;QbOv{feIZ*-{B?|}5!Q_!oaXO2Hy9X^ z>p6}yChMe7YrYr4O5|^UR4@zda|Db@#L%UFsd?vuvQx#mi6-*w_5!|C%3 zIpGHe#ahFEl?oT1XB@hi+yFI=)gr6O+DY-j zz|vvCz!YuGIK(80eeVU5a0YyC?Zw5r#&&$6d_cESYUpSBX{(<_VMzo;GeMRadb1yW z#1s`^K_XB(eDf!xtEX9K6DN24;%wrCR&?^p3~Qap+u&ufi_jLS(|8LK1eVj3z~voN zPC}&6TUtqZ#(BnmYqD2AlrM8_s9Qmw5_;Q+@8DIj zWhFoqii=++P%_9b@$=K5MMa`QNFKoJay~8mFKn=qct&P)w3vf{eHW=`5!yF{1{OnX zPdIA}PX7GwZNbpk<}1*bUGUo(VwVQBFjpl&?#J;cK^i^v-D7DBmP^{FL91Zu7*j?6t zM2&{vmyHIZA+7xX{qb-MP2}BDS~ugN|JVMZ@euqw$HPR7*e~{p+aJ%;qTMZoX=5RH zc`S6f!fN~?HCnr+e+Os7mImsyHKWt8{;XjA%I^730{rKhbd3M+$$z4)a1bZFCjs6wlRDnD9y%3q2eQK*$sNccp{iq5F2#O~)EutjtPrN*o01AR zUk(6;_Y77Lo_m&Yz~mfLZBb9~E)xQZM`C^gjAG?&mPdQAmLuYjegu2iN3m1jUnR+n zjQxe9gNjX6+AKLhlDd%9?+ zpW_A9Fzz2>msk$tVtcqRz)b_wz}9z1v+s9S7`qa*7Je7i$HoCjaQj&P06e$*VjqKb z^Sznyevt>dGD&qIXO5%+V=st;G)M$tRP%4ASC7FkJEXzd8Krl?h}%6%d8Oow zfPr~MSZ>EL3h1%1pA;(q$78OdH~Eb1vHw7H8l|V{0=34q=zuB=#ak1`WUn=)Ea6aX z`keP0ln3w?#zFL*vx2&jCh2Y&A2G{|yceSMQ0u*7q`8~7Fi z@j%j-zGoPIV&NK?iW@zE+ z-sr~rC&640t3VL!YF1>|CK|66XH^x`#;7@bF%Nsas<_w9$*BFS7#UNG5;J&Z8pa!{ummy2*3QqcUQB1$Jvb0Uc) znK%yrZt)py%}s#AOzdEEV6V5-PsP{t%Jd?^G-8lXl>CO<&G5aDJw`T(q2kBtj(YBO<_}hxxwKY5#>XN=vMag+}DxN9l=`i7;FsqfG?6@bt-zfE3Smee-WVY@3y-S9Ay z8iHvA@Ww-DgRcu^gR|Wp92Lt2h%R9ZSG+xbsSHUW*Sxf0iTWH?qm<9vVMX(72hGFQ zmPY&9gFaZcRP=-Y1uF}NN3i@=V<(Qx9s=X$=GIB*0@k{i-}JwDdP5>ASJvo8rC?FB zLXAlU3;oFsrLICnvwOYu|6%TJz@w_J#qXJ9NG33F0!ECQN|30DVw)({M6d?T7nlse z0#XIFEpJNItB5n8HbCM`V9p#zZELmdwO{{wy|%UY(#mVlT1)_$fL{5s2m*@A)iVxP z1K0%6Chu?UGiPQ3fol6c&;R0M&Y82n)?RDvwbx#I?X?%(DdJL2+NB}K(pU7iY`$Cd z12z+m3{Jyz9Epl5vp67f6)?g+cDxW65}#vB`66o8Ewq+~r2#W3H>vD*4ny>7!LYzj z=k&}dlN3MfQJzL#se94Ch!kgpp?IBnLPu1fCA%B3@1Kg$sga(b*m`!isZrs#=^WG2t!ENENNj9-iub%&w1yXE&Pl=Tmfu{UD}#Z)TE4O? z&g%y2HJ4XW{rPI`C^r*KUiNo_RuwMdBQA#|(b(hY+=Bv=MvB-FCdIT&1M#i;DG0=q zRN8FozgH8H4QE5jSi7t!s7&wceG6nK^qc;VWuxWcCjioArU0fT3IzX&He&aXB&OP2QH^@mW4*3sp2Kt}`+j8|&liG5{f#5PODH$8 z8>Iy=M!~;5q1Aka_hbc4z3U4Le3$h^sb`POr3sZtEWN~~m?>5xuJ$gxg*rFxmd=mI1bUs$Ej{S-7BKn_EhwSu1ri^y-cA)B=eF2=f<1dT zLE@Z=DB9=P_vqR6z5@J7Wsf=9YRL`lB3ylkF+3$VV{bX# zUnoJD-ajWn@uZ}yg189<-lG$_?k)2r44!!75#i@8Gt-cFaoN{`>!j?)5?RiY_O^K? zQ#JL9Fq|LzArU9jQ1=6nWe=Fgc~|WImf&;H0kWO7e}dKD=2ra)NZ9Ny|}}7CawUvoz?g9l_5ehfL#F znn;W!CnAuaxmwWzo~er9cZl)=`_3=fU2zC~RAS690JVn<5kBW|Jrr$-iok_Gr_>du zV!5718-uT7!r{*$EPdz2Ud?9^V{0E&Q)=rGeH0qc=N^uY+C%dJ3CPq~ZTUQA>EF>G zQ4s%e`{+9TRQ)*7oW%Z2|5*ur)moJOz5SWbYmdI2DT+B6N8(dqyWo^ircX^Q+1a1D z5g-TU5|W88B+E%@4Hmgq>DKb6XFa@k1K7W$SvJcWcvI3ZL5o#t!|XK1>i17>t=5A#hL`YnuL-Id`cPXAi4f3I>W zu*Vg`&emDKdYY=WV3cyPbFJx2M0;w>m;quF#SnO?TnG$Q{teABdChQ_1Q!(ObDq<+w?7dgF z2nOJy1EHc~TIm~a$D=Hcxh^*xyWjO7gNvtfZXUbnI z)w4>F#^E^P`e_e1X~=n$$PM!s|1tInI8vSaA<{KXsMg6;k`$`b`K59_AwpaRhBeE! zZ3?3%&^gjYwj0gN;=LZ{p_nRf&90Fd9{QwI{*v7t38kM&G@<1e@S4!_WtL4$t$9=@ z9zC8tIBPxdJpyiA2^kau6XWg2bMXMtx5nCKT3BBRuqa3KQoTURPr%WgdX)P2EkI;; zb9QMjxntQL%4~4?bBH{m1?9fmw5|^kGAFz4v50;GFOduigmg+nvR9q}@P)`)CVUx(o zy0P+bQ!d#ILzNHG(*P)-Ay<(+>_M|%I6KNA4g6M=J`|~SrZIlmJtV7ZRqB=Jk~F`Y$x8d_g{in>V_$2)YwH&g)5oMD2yhNK~E@G`+AN z_Ym8Cf)1V5bAnNUkd9bh6R}Ni5!QQsr51eM((?{dt&G*DgfEgb{k_E{C(txOPg$en zbDP_6u-`&)VfXk*`5XC(V!1@V1e~!e>62>mhXb3OGoZ;^_@#3Ff?NYekQV$FX#+>k zccrX7dfbW8v(K5(Qd48+bZRM#AS&sK7Igq(X3;_|7=Q(_?dGtsmBCjc0if?qXse>2 zD!(YU{0!O|6#h8F@y;Wvn?cr9yiu`mw z!zsR;7+zh&9h8y|Q01-a8i-me>@MhPkuI>F63Y{l% ztTmsEj*{J4=&Mp0SyXWAv{rw__sCE0pw-wT>h)G$G0IzQ*i0H*nkY{7w)H<9jH9x( z8l@?=0A;5^aeB#{ZF?fu^{={gS;neMxQ}8piN7I{Xy)33bEUCh(Hm0lHhtp@-)U-U z(z|*;)VFq;V>*v#IM?02ZfNf=?lLG1)$~Pba6|j{^1tYvfpw*Uj=s>0KA2=Dg)6#v z`K{ElMGMH@I^Ie0ldpfVl7mIE?a2%j9LF=Tkr-0PY1#T1uE`?mqj-RAmE7I_k79qL z8wLwG!7RvZ+oL)I{BH`1bGm$Nu#I$*VIaF~Il+3I`mO_YP5E=Z?@eysJK<#5mo%n~AHizTyN zZ(3nQY3xag1IQ$8ZCBu(x7SFCz_IECp8R+up^*`bhK!zO z;-buit&V4CPjt}xx!iBULF7V?B6kM5ozAWLI_L3I0~1?C%QDK!_Sle$o0s4yQYpwS z*4A#)50`A_Yw@z1?P}8=uZ78n5m|TMmjFfvDc!9-mA#6R1W; zNKe$>CeniU&|Q&;KgR@fd%~LXYu=?*U@4XxK&?t3LwP1K+?{U%osz+-dZ>sm7*NON z?jFR&PNeJ<0G`0h9s0J;V`K0l#cwZH-w~_Yp%6a-O(Y$pAIr=RVFav>G_YQ_z&bJe zV`ngP$P7Zic`TR}N6(OzOl|C;+mjO&Me7hQt56RxY+y6o)u*{YaT#LoI? z1aZ917ELzoc%EWR&?V)2$Wx5fvgo-r*7C+_X)B1nLwD=1#1?KlRYs#6HKvXsb1KYQ zY7u%F-W_D4EA{rIcX!eg6OFP~?=vc>ORVGy|H3{g+`9$I3HDjS>}uoxId^Q7O|gL` zveQc3Jg~$_DUr@Zg$X9of*vWQ7|3F%t7Rq!W}Ato@cX2$injR^;AYt~Q~?(I9{1NI zv)L9XLoO(YoqtMXY3;~NNO&v!MMV8%`Q$=Fcr}?xP)cT{Y3f_cw#QyUg;k z;rM+PV`ygl=CVz_Z!71Evu(z|lp#AaUY*1{7F_N+K52~05rk$ztl+F|(|tpGciYNI z3L9nHVY_={5xUs30h6sUL{ZvSE`Q9=1k=TSW+k1VS|)@DpjyBS6(LLMp!7a5vp`1X zOhNFVL!?4KhM0|gC_-%j1}%hzmzDWt?%`- z87MT86_ilImTk~}0=3L{+?OSQ#D~h?*7rmYP^NJ5%ISrfSez-zjm)eR0`E8pt8)oQ zX!>$Ca&7lmQTE)dA7o!rYuiZ1woUfWV7rvF)Yf}doJWR4_zAV+F2Tq5SO7HwNS?O# z2+ik`TUi)rTcoPYrnl;tbdSZqp}(a7c;BgS$%*>UPH)&hqpc^=sINve>(&qCSc10J zYKux#8RZbX7b-w-}s zuOHH$Jocr)2if}Zz~<7>*ZVp@!VjpQp7-io{BH-=_tE{i4lOtfVg(MDYQcJ5^z|fc ztn4d|eN8^gk+eeK2yy0#Ir1#Pp9{u?BK7*=1U&JZ)z5)}jmha2ezj3j`dyYGU8Qi8 z81Mvj`lKQTq5XKHFC%m~xZQshFy30R z9+xpo0q{Q{#NbR+WvH%CO1IqWboho;3Sf zNElR_q1vY8MQn?dwxdrvWk9n;vhTKpIF2tm30zrn#%?7ta?gfB z0*)t(%(aWmPkqa=zl|Kcn!ol8(rvY-Rr*nrQjn&1oil9Qs_A9&D3iK=1EQ*mrKSJFfkyFET$t!UJX^j#$oaa2R{N71 z>5xMPp$#Bj220(sCV=KCVW?uWt@qgVJPGSlsrSZiluwB&o@!zPEb;zR-fio;ITdb}x;TLr02)Wx zCd2=#@#tfBe4R6hhx^}EUE~hUNWGi$huO7ONjZN=4MlpNza#!QSJaafIC`=Faedwf zIn6c)RWb1CP)r5>$>=MLfbr+Y_1tj>rKI<91dR6RlBseX}VYwb=gJU^MM#+K3*R-`$oKx&$ zat7TNq)=lBJhb*%HC}$PRpUl2An4U+tpY!IdGu0!pkcK;wv|(WM)hij|9z>0a(eaZ zSUU-=4Xec*8~a@%Q?Bn8>x7(Sc#Mx!Q5cIPaze0JYvLV{V}5x*X2B6H0ghQ+++-Gb z88}qjnP-3|wo3r%s+0<=rNXXUdA*8PdSsU#lITUJ7FYthWP#eCQ1hrPDXc!t+YljY ztk=o4(_9xCSlZ>*+Bzk(D?)<~DZntD_o~@8PbMcToDIfYkKnvvgPf?YEifkM>$UmD zzXI%rx0U=s06CA*kH!6JTDR?$WcBDht)AFX9?y!DBU?Xb#Uit?fmchw`** z=1QY>d>}4F4E{*EM6-7n=v(!L1;&hgy)oaIk*7E288dSA##{rdf1}5k;pWnMW27`J zMu6A@s!JTD1qG{M5L(TINv!_LhCQqmakZ%~TmAjfT$wJ5wib$A=y7QmOf+5T2rwT zG1>4U&Tw0!u4myu9Kjl1G#XY-)|YnaTlDHRu{AQkg5hM7=2F@d6U8gYAH&}j$y-H% zl0(uOR^7DL^o?ejG5 zX z^eG;r#;s3r6I6)-G|eUF-XMFa$suKW{{_8)!Vs;xL&nrreItyv zGwKT98{mkI!HyP77)Ke4 zOu$N`Ml}H2z0?B#0+G{u`Z!kMG{xb;LM!tjEs!gSlyG-STD%s^1d)UFPVh5G@21Zh z(7T<&6aT0H_^E)BP)kl2h52aUG76ih|MQH(E=KJsM&U@sYD0l@fbjeSp2vyN^RmE^ z#wH6viLeQ(WboTEdJ@Xpg@Q#(dHX={ZDDcN>e&A)*d9>(U8&mlpHTaK3gOmVenPL$ z|9`ArFNC(Ar`OvToU+$A>o{V+J_YB>j?^Huz31x#XsbNT|54iBD}!hd;r{gCO&`5} zK-0?w)BkAG3upp=45Oh-3yw(>egRyFD>iEZEhY9ER>yLnod7Bt-Kw++Q1-Q$6m0%% zuxCJTI;5h(?hqGtG`eqy20Q2TYp`4bH7JILRCjR46->i?BKvODt5^!jV&Facf-tbP z+N5e^#sws$7hNenuQFGm7p)#lFEW22(n*w}j)@IxI0unwpnAoo&V;g&YOFcIQ^ zp9sw-wVXY$<%du`zIe-Z1FKCDVfS>K2p34jrzJu}q#i`@cTB{D(v87+g&->SB~`hN z&_TI6XJGqqb?MgzAhcag!)j6e1-SYzr{b-QWVgI(#yQnln$=#`ULcgQAWYzFH26J~RR}CHeSHsWrjJmni%VF)**U0c6$W5|s8+%+;ep+q{3~Zlny*qJ0x4tW_ zf8lOTA6RXwTdV8sZb>Y^(|2n@qt&gGrwwRKKq;n+L8qq1WE=K@mWO;B&lFxxJBGHYV##S4Jp8@0TP{pBp&Q%N=X?VTj6)mWf8B+}Ap_q?X zE=^x_IVw0I1OpwOgaK;H6)br;dzvk)!#Z+BX@IE0!cFX6%-awzB-zNeK8vmJ_o-xS z$HvGD1dgArtqhT%zm0iPZF%gPX>EBJ{;kI7z($wO6CbN9^qC_(@wvvVt;S`7LPERw zyCT;UZh9+`jg3((!FAtIuH@Rl!xO)pjQcV;^z?MJ9(()f z5w`O`tqgQ}D!R25a=ALO$1Hr@hcvSAVII9n9KT}UkuSSJP^9|xicY;tYZDbn;V^dH zNonJgX%ZP=U^y`ZSmh*2x~~lYI&+ZO=(*FDBDoIw|d!$+Taelom{; ztvo4hK{D<3lhW#wY12Q+b5-o?cXZ5 z{-m@glWG5cQd%gPX7DCtt=^!u-Ie_6Pk!}}vg-eK@{5m~0~5Odv1^lGwKln|-O77q z+ShZFU&p3>9g_SyEbZ&ZGG<`K{@7oWZ*ksi__id!{w3|J1lX}ky_EL#*U7KHN&6Z} ze*IzctN(je>DJVj@2W5HMOMT98?B$;PW-&i`Z+W4bCUJ5I`Q*T>*p1TpXXUWFG~E> zte^STPak2~1(oK*SeaEyV8cumf8EMe}-h2iS_(6xOn_v1(6oWeC2xZX(6mm~&Gs9$`}1D*ICkK$bFwk54{ zBb0TEiFy8&#CbmXzKi$&0)FMPi#(%6cGC&>KQ*w_?eJw88gWIh;gXyd@xX~p&oy%K ze~kFMG0|HW4XCivq$$q;)I;@@Ny*WFeZHY_jd!O6x$if0seurf(Ok9581WyZ4$DbO zT^67YMCqQQ{_FF^*5b=Hi!NqXE#+p5K;l}3M2~HMfaHB07bf6W0pI^ub>W*OgLFaQ zpB+dADF4pupufSbrdZtRzGjHyTMk&Wx?c74qfvnzQtEEo@ z8**$(B5R#p2rF$|3#V%o}x*cKE-PM;?=Q&2K8!Ft|Q=5U7N+~14})^ zVrLNydCEV=V#YjExa=&rY@IPL7bL=HKS(j!WybZc2sfk1tr&7lZLVBS;o+x+zdTeS zvwwDe0)?wDN)oF$aW#bExPkpa9zDkzS~_zQza{(gPYfBWGY#C;Cg+T*8Y zYl1#Zq6H_7pDWvX{>kxkCF5tKF)NQD1lK*68b4VPbx}_~gU7o0L48m;B>eCHmj(Yx^6dYb3Sf6(>|kB6;ZM#l z7XtsF^NWK2|IhhF6q(b{FXAMV63J?QDNWF0=GY`XPCviQe)SacE7_laVto8F^NZb+ zaN*!RNsW(m{buDWbjP}YMHltbQU#5X5x=F%$m}J0-=qYd#wTjGRT-godVNQh&^ z7@w=k-D50(?J6xm6Ms*v|BcO`58lcIyv-+6eqwzq6ZL%#c4Tt`0SiWI6~Ob!jWVf+0XIE8}{uV4#@; zq0U|X`=c4GfS1cO5(zvhheWMAYTWRM*?S401P-y9O3(EBR3?ln4s*L?k|R8*#07eH zre!|5d6CA%{dseXibA_v-qAwSoSktONktR6BYtsq#qr4X{Y&;|in@E8YAd!H zbBhW>yBAk*0HQDnp#G+mb#vx3#?6n%THkXxy8ClJts~Mz;Sv_KV+b0}>`ak(W@mg% z%O+=tiz)9LwN`epsimd)vOY&-alfx8;<+r)H{7T$TwW|Uwv9tiP`+OEMMbc|8-&CX z%*l~dIHU-estfUB&(Pgo?i0J0)j+Ou=Od43Ye$4V?$8Kt#m;+<5Q-sj&zR|BeIY>0 zc)DRW)xBnO-&doV+$TtK;Ap0=5>+H{G{b*42h@~Xo%USSm857|o7jw}KcXL#qibR& z+2|U9OZUv8I0+R5X{9B9r8rS)PSX?H8ROqe_3X^<6?cIEKySaPW`T;W#=T zxE#If9gh9WwV>E_3On7K^-s07|Cjd~4k^@0CSjS_ulciY*WQkO@4UVL=Zo*!w|n2N z-5<$+``+BQYu_%wnj`p%EbG^vj!-uK z`4{pkwUq6FLFV*sqeC+}1|WyJi)o9{Zg9Z@eOIiL_T|iU@F`gH%^1z=y;jp&+Xtj+ zVcBSi`54dmzB0^|H$AjI2cYKS;cQg3=7K8omm~k$|9l};mvm;?1tP&b0W_1ZMIG>6{7S4?my3YDV;Zix7RH!|iP20k+IrPxFq+BI( zOe^%P)ZmeGP9po{jD<@?0H?F&7A-J6xd0`H*llJt?^iA3`Tr?cm_v(|+C$>XE>w)% z@7zdGU8a2`?AcwX!Y`bKJRgtybjBV~QChZrV>SWCN2&o|uD&OSHXUbV1n-0W^eq5U z4iyT73IY&-fZPvciNr4%b-tG=FkaAD?7Ia#2n~vjT1Dm~=9h+$b0hhBd_R->p*)f4 z9^;1GNZyYGnV`frmYA6y)ipscw18%2E3HTiR5(`)-X!eH8||u~8Vcn$x$(BXr$E6} zrJxj^A>_@+Vg!+MImy7VCPC`YH1;*qUrWX9IkRfjX_lbJ}MEJpQ)wy~Rh~m>N90hNr z^Qq)CZzCUI&98XP_tmxzf}aHoMFtM!XvwL1GD&LfY}*9N>ilQLJ`>| zj!s6KIZwC@s@5pRLK^u0HRhBC)j`JO09Pn}%lrztC8HMHhteYDfO#g=kpc3Qpv)Q) zC*oY>&oI>xBN%w+s#Dckn}L6S><3gOay^!hazn{R>Jhmo^WJ>6!xYrk7&u}sl{FUa zN+p5~o$>dUd6t^dmJjD^9g^QS1Dj+6u*eb1V*POJGpX?vek_Qs;*g#cw!+7zPahHq zeQqoWNP3ex-F&@!g}c{-UGc3$QGF1;0aa zJ__I1iZJ?hG%mP3c0Xs)~u2#*oxzj89{D*5N(}|fI zv&!OUGR4;R$45|aRiLAc5vNMgFs0_l7D5<+k6Dj*t;Zf7()ai__4gI^_ht3>CG_yG z(~CUq&urux79MhUnA^e1f$MR}C+0Bvr` z`m?3peC5OW%CUP3ueEOccXK&C&A3%2KOpp=^8aAtGl02G6ZG zm2F?2ypQt+7H}Sus%1ZC@$WNbL8v1t9}ye>#u^#PvqWkV`ik9$GZ78RRWw3&S{6x1 z0~);f-bqfSu1MUOO$3cAoc1yI^%g9X=gn_$RqyxM~po-_HeT5e5>j`el77iS@A6= zEV*_!7kvf+KI@F-1m4M7b14w*AXaqd!1e=j->hKB#!}-mUlxB>Drvg zRCd*dL<&NYX<{gxJK+9v#`%O?eZoktZHqMLx+>mY{69n4A4YV@S-6 zR9z-fhUXLizj-Y(_vYz=j?V~#=I@Tya5hjj-s0biW;j|HuY;}_UuIf~tv*9mjHyf~ zt{8tQnI0xnWV%!L=5~HCBtV1`hxBs@GX}AO;KYArX+~7F{WJ>J&lT~&XCAkjw;~!0 zUP_{w)t)%cy|SBdYhYO}()tJFk66VLMWjFG-&|Iah^IW_<3^L!s^Wc56zw8Ehj!&b z{>B%C0mnUBB!^X7H?tMKxBo6jBciipZ! zQJ2-0JoXxSu+>|gaQNaT(6YFR$!76#&+a>TrB93Z5U!Ve@|)A)>h+_2vV71UUr*S! z7pC5Ku094+Zy?jlZxa~d)~ zTaGre_U3x$(Xe^3Q(`(zqJ&zeaqXe7_oR|nB#rIgU37AMSqE`P=H&-I&0(efX5e^M z^YFmB&nQzaO~=m${WDwF{|$|(_0yvWlC$>&-g8nxxzL3Q^2u5$&GKv%0TehsWbxS; zElO#tP$)n`ktD=EB$pBVVR>ROr{|&jbHK_fa=;1l*lQG!58B|zK>Tx|jZe|WC$#bH zd7@}FxuA`Y%WLE{urV{ion)=!gFvJjj?4YGmGXsg-`1ftCnAY$Oa~xQ6wxj5spJq> zUHodhnEqNqU^q8QBH_>^;8mll=w3N`-Z)rQjKy32iu7R)m8i<}q8^18GX%2?a;(n7 z@#n5ORhpHT@9efsa>mI4Wb249?aNUi!%B$m1tRMMeOmq|W^oo9TCfpnP;I@jFjoN8 z+9f_ssn%Xq<0?7IYo*rS!J|Cl%0l9~k#UV8b#&y!yv?78x>L&W6f(h+XKNU)H35P1@+)ErlXg?&FYXSw@pSbD7di zTI%v77)w>`r|=17CTZ1T$MmZ4=TdmGhmvp}Tq|TQP()n9Asm_-tJ74+_cK$4>=(L@e9w-FFrqUmv zTXZ66GEN{3#=4#6+OALf37RRS!6MM4durrRe!EER&rKQz<^t1CMW=_*A`fJt?s`Qc zS(`F##(oDEelCdLFh>Zy+%TMkx0XA6wRROqT3G4sL0Bmp78<}xo1#frmo({Dp2SK^ zgq4;EE8Qya3Gr=~lBKW0&=#%zyo%l00}Wz4m2gY4S}4}qU(wp%;8@QCKNTfaz$#)S zHn@Gc)FNgRg{&X%WSIK6#+0ZXEw|?N@*JOdR@w$VTfeaEd4Yq;{mrI(WdEj{$y8-A z8grYBtD5A*^!(mzzt*ncT6Ce*`wf@4UgqKX(@0pwGZ>Ch=s!85VjcFK6)UMq zuw_*)mDa^Ysj{j?v-&+X8jEtZ_8K*+FA}wCj!U0+KzwrQfOZ%)o~Lis+GpOJQL&9M z?JGoW7j4^@alx&j`Kx zptLGZ5<+}MSpdE3<>YW`I3S}*+UztqHnkr#T0<+6cb`7%fHBJ~*{rp%)2sJJ^0E|% zR_|9ll2>FFQ;jj}pwY0GI+V1Vcc7Q6)Xhj$zAftjiQsW}ScCm$m$CE!qPQ9eJ7_H8 z$^pI9L6Bkd=41@;Eajx(}WLZ>?qns#7o$Xy-fy8)TB4; z7b)y2IR+`BWF>+eQsYmI)^56S(xmoSa^^Y{xg zoAl<%8HOM5e3L(PZb8hSX69{AN@aJjmnRxI?1V_gr z*EUn{)Td3*=k3y$9%%6b!u^Ft)eBXTIsL{Wk1;Jb(3u&TfMKD(f9zYj|KN_eKCjzY zRJ7xxinnBKk43-(qv-yVGGR+C!WNGjmx(*5F@ z$qL|q7+`ShL_bj<4*G`Dbj0(r^r39~ME_n8{v z(`laTFMkzfh&uzfd=oKUJ1B zta^X^sjsc^h*cduf|wQ7JnGM#Fx+t8@P_XSW(A?*0}bp}sZHfrR-? zjh8L(JA`n-&qQJ|%`5i_>$~Z9G*dMQi#8l=(jT0%QF1)-z$9wu2Qyd((7Ck-Z{oM~ z|H0d(!FdPN98G{zVu$d-v131>`8s3gGBG$ij}6Ij8IZN}gJI5I^1{qk4A`ano!b)G z_065f$8>&pu9N2wW2u=#yb37tpNl+^szc6+Q;M41o$qHlU(**A;Wxi@e_Q{uOT>X* zDjSH;iB;jMWkV)c9Bck7?tddLsR~!dhguoq8D*QU7WkVljRY3mz*-L!fCe{rYs>Z& z{N^z0w|&xY_I7+igr;-(UA8H{p!1z!&Mu58o0vs?H!>M9H@kJhhgijB=s3*zFMLA8 zbG^pRBKHcV4)}Lz?IW6unO+y_g4Zo?8BMHZY&sf-!}-W5nd=7`z6^eJlOK1P{|MML$hy3ek{c~$4zjWz|wq& zufq6)49P%WKheXgbCtX7HHZbgVU4>dImPokX{U{ImX9q(d$-|00bPht>T14sjD=I;_!R<%|dv&6(i zmCl`+e$%;8KMWUyr{-$^c6i78WgR`8h58|XhQ5veyAdg(BY6zvF6)MknVtnb=5N=0 z($8`qd3qEj=Vgci_yrYku-o?~bNov}%ISPnd1C*@o9c#iOO{{$tfs&<4&S|H+gtB* zZ-*RK+(hcAFz)trew5+!mu*V%m{IVszN^#B)!*#=Fh7*{aH#5GXQ=t%jL_VNGbdLZ zYJQu=ZoY>J6;R2;J5fnuclF|1o}XisLR2(cLKw z_ZDW#J-(UO>T;T<+YCc7Ar1@@zeeBP8M8QQ$Gc@6!cU}3orIQ!T~l06yUiOVzw%d= zBBWb(M(10Z{sW(vr^J0a!BeIha^2?TZ-A~&8%@5^WgQiVe7WY{7j1q@INlHN2DA6q z0|)c$@wby>FmlMJ)+0{r@aqffsCc6ieC)FM8G-#PMa5tXwRgwIMsSU^!NB^4&R9iE&N^srltJ%z>%p~>hMKTUfn%!)s+WVS3FBY= zgk`p274%=p@JFkRc>W>-e(WJ7Yj(WbyB*2XH>UHWbDcbgj3vrbK(xuk2tvaG@8A01 zlQe&QOTR)sUeUyQ$yyuC!V2!u8&Hj0T#I>MuHi-(75AU&gIaK<0z5lXUz=f!(r4{T z3~53L2Re_U_*WbvgxMk8FDkay?yE&R+@{akU-FvPz7dTx;>tD}b|J-FXxqwK|E=dg zVcA23IK;#zW7g~Fs90$k{fwE8h{w^pJM!QNOD51Jvqr6}De9_qItUC6C&3mng6P=P zx00MHTkRhKC~E;@)_$Vgxh+%k zoE5N?;D|z~(en;yZ4Zi$=07N#wV5f3q(DB29tZs+#T(auaN;7DKdZH~pUF#+s477s z6T@uve!3QMA-9A&EUXlv!0n&gEh05KAq{zC5pkqRFSsF+m(%;E;ol#5bhJey4GM|u zo;#h8JqPujm-tOThejY7-Y@hpeuV;3erG_RGy=*5-?lf6hWJMuf&J*X)C6*v9Q}J0 zJ`M|<_0uzOkq~T*U=+w`w$uh`VBmPhAAR<>#U5bF5@Mb^;>|^La`R&{Vx&y^POJm% zjV|9ft$i~_0WByj)B0{7m?Fx*@;>ohsUOqYbK{rm+gjgI3C9u%8IrI)a6D5MCAm$3 z=Ee+%&lA5bK@z^{4F{K4z`i zKfPQiU{BRH{)79RC5;9&BIn8iT}tvDPk7N@FPyIZ?IKeCEGs>kt$l z^1MJOI`E+Wyty{&R{K%xzDwc785s`$1<0Nm zNt09>&zYA3}X zM8D3Ryp|3m2UddrjauOI)L~=uO;k2Fr@xty^=dSzwHV~GKLP5Sh5Zli%iHxKEP$OjrwoyoYP8kubqn+@Fv7%N%oa>l=Hj(AqIISD@%pK}th8!he2B1-TX zh_XU3pdV5&z_J%aTWu5=m59D__RRZR6>eH>T(Lak$Y4QIkx$A8h+?zQv-4n~`*V${ z46E9Vl1~0&xnw_7w0hmYUuz2hA;THX$Az)*fDA*Xg;wb)-acD=N)Kp755U$X0wCdR zY2Jz6rLUB1YW0I%Cn(|f<**n!05^9~Z*-;I3HC1V{nXl8)K|L){VSzMv1bJYvA;2w zSJn0@yfQl}_7%N0$-X!KF0md1vOX=?K{-SYT4=<>Oe|sIl{s{2w|)%D9%R%j*yt7# zw&CFNhL{|;rIDJx!GzPNzonPxzbgek+(c!}`EE|(UqKsHsZ;}p>=zE1?D1bL?6EHM zaf>}_GBR~&rLG^Ia4ow4oc(B zx9dz?N2VV#F9Z@+UejI4^~6wPh3uf}*)n-pt{6&U*!35u@y8FPi4*wa0yPOA&9Ir| zfZ~jU{-sz=W&8;v_8G{N1K`(%`)<8djpb317 zKfbkv!jfRzjY3j%Mt7u&J!2V9^qCIY7tDdC@ zofwKReKnI&Z>ESr#)J{94&E&k;w#eExr}AGq8=h(kbR39n~dqKTkE9-Suz+bf4Jj| z)lpNRlLZNucRrJuwrgE<+FlJ!#DFIlQeE_&C%g5uO&n;uV}(AKUP{REh1l!$E_**s zoU7zNd;BHW@1y6y3=N*%&SQsO8l$y|UkYlQum=hr=ji)0e3u6Lo&H9BOX~+&BPt!O z?~p~3PaQIb3UrorzKHfW)m$U9{U67!PODE38N0jUQ181yn6jan!> zELare!KnnI3$RUGn8OJYc`^;iN_;onp~k{!O*z>d(Hdn~i`IA~K6|t#SB7-7Cf^}Q zswt4+7p=*&eyMF9Y2FCf6EiC>bQ>Es~E^=q;H4`|Wz+09DFOkrVsd;VNRlS^5*-FJ{wH^~QtIyMV z>>co+wdL?j_qyxwcw9W85)EX@5akXia4n@_wQGVw`2*Qts9(V@%ZfU^rZ8HgEcWbl z1iIwzGbJw5Rko4OSv_CP#!{pf_)GPg;z<29{knI2*qi%8Kb_t2;S_!Lq@VOI%UAa9 z5i}R-OjwmB&dyt$sn6yn0&_MX3KFrk5``yLz=KYXLoD(r5E>`?3&rB+o9$0Sjq+HP zaK`d;G-%^niE zGb`lHHoWfi1b1k5PUy~|A@4B5>q$@Wgk}#9-8mxU)eLL_X;l&NV`S*gQ6cXchBq%g zAulxh%+Q^qL*BCtZ+?10erWdDp*znBdCxVxMAc40TT>94{iV>I=Y_mu3~yn2LSbn3 z*wCHlhrHtqZ&7+eQE2uBp*t@Oc`stGG(Dj>G`l2p=fxrKC5Cr=dcye7>`Oy;emUg* zis3CyPbdw|E(_gxS;%|2;hm74Fd;PitD!ru2zjqGyyfW$<)PUXp*yb%c_$j)N$Clb zLbI<9-TAeU_Zq`nnVwJ?nmsvm=ai85+UGkET=v{9Pb28vAfs=+*vPS-=7%0tA3{%f zWoshzq*vB5p`bU)Lu(I?5UPisv>w3`65)o~)4%2=*|IQTgsUZk*4Dw#)~|i@%q-re z0i(u+TenkNDVH?~gGBXd&dGV7F( zlgK@79cr6KYf}NlY6^|26;;M;4}21-+S-qS7f0q5GLrQ}t)1mOJNIWOVX2NLFhWRq z+l;e!Ci1Vt_f5z;FH$&X4Dr-y_MIN6dvP z7b_?y*2>sbCvZ#3o{%R?-sG9QUy03-;PjS( zUr=lQnu(r+OKW#g5Bre!ib}5NXdQTvH50>7zWNX9ugMmG+8j`2zawRpUCm2|#M!!K z^N_glv(uTE_bDjg#`Dq$=Ohp9cn?iH;`xd0dAwq)|2^^->%Hc#U(=^jF83O0{+D{C zj5$t#T+2_rG^t|Sn+$1f*!op&sIEd8s>kkQ28xKhaHiAB*|K?p=D6~RWD=LG$p#8pT)gl?ZWPmnj4HKOD zhpCp1{~txMrQL>Nc9tC_DRb!~#)E1LgL!NO>lAaiYGDl(*H%QE-?cazKDU-!Z;NpY z=KTO8Tv-Qu7g!cO=1*uqFSS;JNxPDbA`3r_wx0Fl2GO&K#Nr!mOfN9kq6_F7v0<5y zie0ZeJ|t0%%Qi4bd5#CT?Fw#?3SLz^#lQSM{iIlIeqi zL?5vAiWiu{817~hx?21k^X*?rSqd?Lq^!Ip0B|Sb zs69#qL9Y3IRhyW(R1Pc7&WZ3pE_Ec}=hRDqd6Oz7P^aKm<>RAK;$#(xP6TPNcpWnT zV+i7OgAJSD*urlbg04^vuuhmdZW!Vzb;Ysf2K6RZSjpMv-hN_Uo>D#$lZI zU2P}}2e&|89#K{fjK>jW!eNBRr<)T~;HddCpSGJcrWYISBCN5+X7jOz4;8O1k(=U9yoHWx9p>I2e`2l5#nyF)fP_K8 zDPE8O>FcDluBxkeO?xwb6lBg#Uc?rV5lw@qv(PRqc&z2q{>R)V$DlT>)s9*RtI4zv4-WZ(Thj4p;d-o(~{nC~G= z0uJAeScS0->u+I`Ulb{DN@Zsg)U6MnPIFN{TZD`H;&~RM$jDX5;BGaxdHn}U*6Clz zneZT0)UCKbF+AMB!5V@h5{bm<7=0hwbMcCi*d zvbPp-iE78&0hv?YM8FEUB@P}2=+1YQJsk0(t74evQYL9CF>m}=<{Q}rHQ82`WlT!^ znm=dz5eueN`)l!_rWQ6~TBRbf^s;W>Y)r{dlu%QBGg^$Wyz6<8_ze)sxy@F=Tz{*Y zA19+;S5knjp|L-QMUNZP2$isGm{A{QVf8?jc(P3yU$Jp9_u!P~K;H3;G+I^rm10x7 z4wG_n+Oc=NlIT_VO`m_>r~$p$M)4?6c0O6`Seog$n(-5BikD@Mt0_$r(YAc9Ox;h1 zx#9a#3led<+SOoNewW&ow>)AAck;N09*(OWKe1LStSwb@Kx%gprg19@&D(4K=}~%} z3N<_yp{Or?70Z(w1C%m8W#~t=2bzS$N7(gdmm6ynw8deE8}azeK;570u-3kWq3K$5 z14S`45@KST|Dw!ml}S^e5IH4-k{wre7NKN9Fo2?uG zq<^Y5TkJ`#Hzu+R48iZIreD>M8Q&A+vc-YuQR|jpA>(AHu*<04YOQ3H3TxY&1q#)@ zROiOR+AU3ay}i56?ug$(w<(LIyP7BmncB)Rv_$iq&U=z|kVHgb<5g>~n!#2n$*&9D ztjg8+Q~qOuHbBP;f%M$23?)jH@Q;YevPv3TL$#<7l}f)FSkmmkn#H0?WS4lNCM@L^ z#Jxm{a-d3UZ41IA&~gT zAttbpG*{^l7xO!QhQ0%L9I?cm#Z2^#64_&rHVD643s|ZL0$;3xKSG^5WIZykJGKJ! z_dhHXYicUCCSl1Q|C7yviSa1sDFuL(*4{TIQyhubDiN&(bI=r{S+YKj*0@BcJH>ib zuc@?@ZXV;pUX4dl*ekVM5cUq|abei&;c-#edj^l8wVQ&GCE5qJ#Jj%n~^LbQ+y<>S?74{bLm>Bk6#A8y}dm)dj!`=&cd@bxP z;&DybdkK%qu=ipflf&K;9#g{JVjkCqy~o!((RH`!yc3!rrTS%no}e@wg%Ey_UzEuy+cNZ-l**dE6NGR`R$h-Cr_1(_0&w zSwEL&4bOQzt9jncvx?^};YUZvX!HMj68rdiRmt#+;Tm~Ed(o`+WFk+;$%duh~hjZA1_CCN8fa5%LUugg$O z9F2@^lF`IrMj1#v)d@=@P|C7FMQg>9N`^f0$+J*BT}5IUHD~+_iAt3_x+QnQ zbYjMSLOaK?P2BI2V@3t66%lab(JPsq`oZXB~nTPG&v30N)jTiQ9Nq z+{N@Ig~qev)r-e?)+7B~l50HsiTc8kaF2S)$7l8ZOqmV;OvPx!zEMoQZE~hb)&H0@ zjM5w7gd-}EwXtI{rMZ$dmq4dKAefYGf;Ne692<#Z3gZ@n@bUcSypRjW4CCHhqfw5& z78{NEJc^9U0v7mRiaajxw;p$}FQ=^}sFQ>E8SmoeBMuO={N1Uf9+pg9ko7zkzt%prw-H>( zyZQ7Z_BuyUk3nlYIvL=_E?`_@aIi3>cXq}&EMysti35iuEep*rx-3*xbUC=4V5KXQ zGLhj({VJ(fka{Jl+UV zxafySR{gLgNMoi9!EKSe=PI^|Q>v3Yne{`&y+Hm%CLd&D$XAp<rqVOWIuRkyhsWd z#_J*-#2djlV79?m5`xkTrKyoc#HsAF+ABh%wLK5x;kG1$rt*v zTON|7My33!w12e#iCzdKEf1YfqBEAqyLsP3vZpy(Yf}@(?fjCx0=ktIc~AumNDN7{ zTdb|1NctlK_M{A3$RLR;N#v&WE*?(*(u4)C(&|SgW0+m~Xk~7mxTpw&DB5PFYf@ztBxhz>W;)E@iiRmEMJJ@hJ`^e+Hm1l{p;#Hg>whVd z7`EKBKR+dVu7`D&o6nGe0PRQZDU~`4a;)Jme60pNuvO}6z{k#FyxFR&dM50NN%KQ( zxwVqy_U0Pdy!+D0bc=yCc4q}GJu3=@F4!s#JSb!kY*-V0mc?q~yE7m{iM@VJ+Vgf2 zNIUomQNfGbNFtR zS?ZxKh(TVN6~vQA+)?06Yx+$XsccRaE5w1HfbnS03dN+pNf3~IfSfc6QoF-^4Q7vD zWQ@i$UZ`%V6e?vkDQcsZaBX63Vz*e1HCm@5Z0CxkKGX<0dRhdxZY}r~q@ZQGl}+I~PHW`yr3%?yo4 zl9zHusFX88rI~zo@p(viZfO?Tvia`f`;gEbrL1;JvwNya-5I{haD7%z_>Qch;kjAE z!p&KpP;*vJXl~Zf&>dNYj$H4o=+hp!N!aIA z`Ve-98=c_=8R3PQq0-O-XQ)wd8m@DN8;67!WQ7-IhZed*3xs3=JA8EO=y zhU@aejc0}zj1Dh6D+HDnoEd5y9jZGkRsl$O>uPPKY50}(=!y8Pr_>$%UvJ~rQwjo| zATR?2W`-t}f(+Jqx;LLHDd|2Bmg{37gEL{#u^Oa9lURYZ4=0=tekLTK=Pdx)so4>PRf^3)| z8z#tx39?~=Y?vS$Cdh`rv*B+z0E&|ie`mwrZ~z=ZI{bYq>b?oT|KFJq0_+@~7=O&3 z-;)YO57UaP?E?L_w^g)J3o+xHVr`?6pR{tDU|*=R-P^UIVe zLkp^FChW--tN{LIVO~gBgX)hP!MJAL_1QAnoo!W zF7d$pIW12~J)c^;Ue@st^qU)I8_g^vxQz!5IIlC7apd0#uE%TOoy;Ro`E$!UZoXx` zirY}KrR23EPnC6qYl&zOp50%vl@!@OVV8#!v73Bf;+$5;RNv?U<1I3Cl(Ukfd%c!} zrsTh2wh4@mn_D;Db}6`T@Tk(a>staJha`m%1@ymvd-quF zxr`~!?tkXR**(>lIVJw=&9~U@qRIWWNeU*mZg!3rnDCF6gQ)bXSbXH~6OV==6-zum zqU*9kQ67}ejtq51jrKzUSO5 znQXt;*GyBEx`%MIWelE!cHGthDzxCUl&{ktkcMJn&e8EF`7?f)u_op-s*)hx>idq50)0c44_S-()}gNwuGAk3Q)ysZjl#!q3p=mUmsga&7G< ziI7`L(CNTCayn7QQX))GVr$%D)XaNj+^NMl(zsFGfAs@v3cf)0$=PWFVcmC%zKmh2->EBuapzL!WZ3Zuqmz%OTa>tVWE-6-7e0{$=}h2g-)*Awex1Q9+%0<`F*koW0Is%J z#}n$N!+$-7S;FNFtbF_zY2YvnqT~WlIlouwRBxTbm3O zWg=T9Y@8!aTH?)3io^UK+941J9n!9a$0CjZ*{u&bHQdBsK$ZK`cdYVpY3D>UooXT0 z0>jKgJ;`YD88zo;N0Gz5PZji zAdQ0(TOH4esH=9j)D=7R!}0lQ^ef|r_0fgRurodp_*$kGXT&cxUq6DZ^(nC!FX4Hqd-@`~Q!+cY%+p$`W_0k|GqLqyj_;7^T!i zi3CZM)&vj}NWw#2Dj==Wf)JG9*+~_kLm+q(%*nBoZu>Pe{cxrqW4CtuXa}KnGyx_7 zL?l83Dy^}lwaTJ3fRcbn?zi@Nq!J?S-21!N|3xcjpR?aeo^(#LVHFShqZWvMs}MqdOQ zu>Ij5+<+2dHa*!TwjHz-tVqG*o^fA!MX2=&Aw=wK* zZ`iIdIW}xA#h%p8xp8_H9Hp!xvfd_#Lp%uhUmWCru_gbcey%Jb_munHMf!KoNulFH z+$l`{w8oOY122z7sG8# zYwJ4j!~YpbDu2wPW7AlCOepOlqvWh|2_b4f@KfVbPZbS7gb@fA4N&7~8Z>fz`pHVN zpHcfa*<(3V2J1{WCu0eraoQ-{e_bQhqdj<>EUyt3it`*#$d@t`yt>MqlQ&a&^e04E z4T(NNIQ(F0*mIpR@;Z&Hr9V6?9K?&0#RG{k>u@+V*?l~5>fz4l;Vl(xhJ_l}&)uT% zV=CP!66DwwwRro;txD4ru@}$IBH~|}o;u9J5y`c~A z%tg72jLBe0(}rydOFkYpi^5MREIAy!UQyJnCi0l&Qk*Ib?nEI73&QGiQeq)$iQ*z_ z8m?nN4~$V-1Vr0nmn>==$5{j~i|mt#as3*{sgnq1uDLKmV9e77S??J0&=GB{J2V7W zilP^49@79j>}iMxnlj5{h1isyh)gCZejG!6Ra%zGCm&Ma{~>%>J+g3|45K?KXV`X0 zk~{Jyr~=2P*_Oa&|7`qBiN8|kuYT6_2|_C;blOX*a{d(0xCB>0J+Q&&(3<@S9w-vx zFjRHmE~c)-zx|O`U*_Q;AL-00-@2 zL8;iFlKG4>dWf{e)01vkd#lJaFg;w_)^P-*_MfUd^K3#ft52fz;hXIXn-d}6(*7ZI z-ae6hbfL8WY}^S_$9Om$_`yXo9&8J|VRUYB2>(s@Mr&KJ{tB(F&+421bny(R-Y>V6 z59ZAEZhX=+NO$8NNv^vh#lp~~vE)BhB4Uv=eY>WS1Hv@Gk`9yLfM-zL@UB?UWq3{g zIbOeXwGZGZorZe^#!a2e5{1$FPtbeplh5#1XGvVEFox;`Um$z$!;%r9S z<$as-nA*cw71Dcs#?%8H1mW>b zp=DhEa{8jq}i$CB`bQgc(Izv!D6i&T4|BY3x zQuv($^4ePPOqEGuSED9H$v-^F$wQJ%fXoP&qxj|E10r{Dg?(}-nrwQ^o{FQkmdNmX zS>$k5by?VF=C(APz9r~@*wZZGM&znt&vW|etmF0XCs2cw;>^D&3z2L%4S@l5vGaUM z8YN?Xo<*2FK4~_&{*5=$RjW0V{#+gXt*L+3U9~INR%6H~<0Tn5cJ7>?#Ci*42p7p9 z)CDhBDD5E0{*4Mr-m6s^YbK_|4j{cltY+aNJLGP(Ifly&#(O|;iWJU2!CsTyqkksL z(M!@aaw}Ylf3qq)e`j!DN4khE{5@0WxS(k}SH`_00QXurQP0F+NDdI$-KfQ`K^7G* z`W`M*1!h@IVP6=X2Bnl@HrOO`RjXxQrrBm+W@Gtl!_$#3%`Q{0N!r*-eoGBQjW$*=#|&hf$}ezmw%u~G%M7|R zSt)L~)A$y<@%;t*s_`^|j?n&ov<6Q`W8^<8*8oni_kB5ZIV|Uj4t} zL5#|4T^{@GVQ2$j@KVH)O#%hmn+s14!+WEm-xDTP?7zcFBgyKl7k3C?>VujP* ztsl&4K*HI14D>_ovsy%0gRcaaz{B@2va~(;kxQKGGs?Xvoc1~g$a-jd6HpcS@JqJH zdbv0MkiY74X3FTb4|zjeN&1jiKd$X^>$h-f;;-5wYsqx4h`@ah>%HaAEqHu;m|NwD zVTVYI?bb0~__E%oHJ=sXHg2T%DrxguczV@Nx{WbE0jUbi!h(6)`{(rO-pWN@{H%NP z*|ru+O)IU+C(_!p{;J{fZMK)=1butxKcbh(Yei)An4kNrWe2Tc?KEZvB53gw>-)Jr z^2e0U(N`}F6TIZp{+ih9j6NGn9&aw!RVL;(@%{SQ-qE3B!3^!MU&1whcn%Qgck;i_ zK#olZA5tBBC@MO&+U^9&p89hP4=*tu^lBd^_G%@!{-75yz9C@z=u2LdN)Wdpi7zBf zdB<$gSg6KKHhjNO^6^c&=ND$n67c~=(`Hyr<0P$M=mUHmk-`mD_(|;UZSvI@HKVu7s!{8(M zGYY)=cK2(+na1_TKjViKtqi&?120eUG+92#TAVB2v@Y=iGD*zdsaHwmDXD(UroA&iof| zKAs(`H_6MbzG#gqJQBT(r5~Hirs%~4z+CNwx?f<*CNF3ZJuIo2;B${?rIB-V4$1;- zgI8ebqkWLjYrj^}>{1`ZHgTukB!~$Gu8$4mgVhnaN%&YSOH$nGwZ8F19J>1c)$l#5 z`(EVGPLV2(xNtn$^%D~YDv>Md^SOIP>mE|^{#j6yp?*!jhoR=2Rv+_S;}&SYLR@R0 zgI7TrplS-Wf?UaP6b=X4BVL_<1&B4vZ=RfFpCymJ_E~RiPiFv|^T|43hHT%#lnGu9 z)ZGV-^hdShZd^+bjmx4RHqvWkK4k5Sje(89_4l`oqQ|_$#(87e#?77XZj)^Jt-*^q z1k_Ke`2jZPzZHsQ9n@Pa&dZ+9qTm_x!;doF`b1V2c?87k;3w;70}@R&aG z7CC$+ocz9Tt7F$w_GU$_qWGzF?2nt+T8T|HR<&S zUjhds{b7h^=qQBz7DdQU%Q71e8Srz=^R!vTpA&S2_ESMuxXYHu*9r8bQ%&sk1#?iA z6|yAes!^$Ep)IPKxTd5EUR)hFVkY=IR+Lz>_Q5%p#>(klm~NAm>(H&0kj?*#KfC+w zE!FK`;BmMjUHlVH^)ABenw&|MAejzbg9I8DKBGj~Xr2?*9tvR@6A>X!HddZvBLCt= zgfaB%q@3PMP+W1svT%(dBMR__93xEYmvtH`Z$He-GfME?Hk)s!Y0jw)qD4~~%rIbL ze3&F~`cX8thtb=(U33*pJ!7Z>4T;^s5rr{Xl1btzV?Cs%)ni2_Uw|T-!6hLc=?QGG z#}K7(Gh?K6s)%k=64!XJTgSJ8o7;ArjW1jLLn_{<<#E#C4UIF8Fe?piXQY&g!Ttgj z#3aa>XZa$NlL5zN&L^o`J}^DI8|o@*;U{fU}|^X z;0wgV6Wa8R>c~Py0^<&8g{mjXn10?7#y_!Tmn|!o-ePWq@6fXaq~+|2VdY$>z$o-- z%|l*dENGu!-@Sf{%z;^QIt(f=$vwr?;+%pE zuORwSN2|5A6o1tr-lMbWVn=ytMtXv_T}q3}zD@jRR6Q%nMv#ofRp>j_$}P?#xljxb zde~&G!+v5f>`PjPQj&i4rj@d5uPJW%zq856Mozvtr;_5}aL^!tF_K zK`irkmQSVl0!|zJ)lWztxDb|K&R0w#K#9eJ%%a;Foan!i!zo$?7+U(jGyJe~c$~F! z)wNPZc;>X!@RVr-+;zNx^cl2GETVH%aT&LO(()pW;W$NKmjZq%0leNCo9R^YwcGc& z*s3)OOLq==t&{}@i|{U6s!&yp6GQ@s{EvMoQBrdoQ;f8NT&_s-bVmWtUp15LT6-^! z)``M^74;r}wK$PogeNM_ll)b}+D(dH&R^z_c;~o7`NFsrQ07>}HI(A)rGYAN@YB zsLh2iJ*L?S!AmROKV5@gGRa|-q{+<6j&Uo9e2CpI8W4r}PfxKA#2{?A$;>|#nq=TP z^E|Vl+FNbC19S~IpOG`bI3WJpG!eh3b_V-fbqG-#D$X!P_hFa6`UM&&w2-fcoK7=F zC88#pDd57!4&A4q2&qmpgSfIbrLiPH4lJ`3{ozDBqeY*Fr_Ob0J}>9t;f1n9YPqDe?UF#{N!-JoV}61ehXMMB2u7p ze+J&#SQm`?)E09E44A?(#140Obp~whiTV{H|VOyr8@O0EkHFAm!pt)2t7mLWSNSWU1enhHrhk;jTsZEFu zwc0Q}3FSx*7`DawI-Ms#VzwR0qh-^f>XF{Y)$>!(+29CxLK2&^MI3VCa3YwDCu{Z_ za!CLWRP97Y@(@in`iz!1aYNNjn`cN_=+$-C>xIxmhxG`q(Qkxs+d46Fq0U74!`zU~ zh9EN)$hiN0q~Mdk>RW1ibxe5FqcT;Dq|wa#?plG;$4-zCs?LUl1E8aeM9XVxGmj)W zV=`T$*j!mWKb8}bl2M7>{=OigH(Z!)YbL}&j1lt4=taIiSw=`iQ2wel5J2h+BOBnf zG#>uUxKx90I&|Ox$9xIv0+{ppBm@J~-O`n*Td%L+|fgK=v8a|be32x4FSz;nT zyI$ZCoV0FW$%aNzCF;7NH7Kv?Q|zJE^+-jn%3oDUQ{i^HQ?9y9%EOEv5Zq-#?tH~6QE3X0$OfB$ zQ(VPI=3ghUGm`vOO4K4eRTpyjm@L|2f_%o&6lse1U*w9Iy8QZ3xuMjnmVQOs9-8R1 zZIZN27OxD*_E)rKf3DdYR1mspNe`>~9Q$cat2qmI*cq1pz1 z63@kVtTC9LD{|rF)c3_2WD?v?61iQ~N0OB4H@l+Krh>xBrhRH{TGczj@8%5(E#p&g zje5P8*YC*dV)c4EuhZrAPW4*EYk|DpqF%qnYp%SGQLk6=dWF0WSFZzk?JuvFsaJ2_ zpkS5EBmZWXe{-*_op+h)t($V|?y|0uH>a>e-__*3bHlczcbUA!J}Jdt^@P9(ZL>9Q zm%r*ic(Jy)okc|!O=&D{CIv~3m=C3w-B^4;-W-P0zxkx7w)d?4>8P5QzHG1mB++~K zw+_^%6;!OIPXxs}u%PPA&?i}(gme(G&i#jYCH+N+S3uYg&NXsS zJ!C;zTcYgf>*)!ivsJzwabUU*cn<@Jm@?W$LYz9* zeI`6p>8d%sJ$bE6*Rd>BX{x*F(p{YDWmv$GZFB;KM9)G;4K~-zXX*A7z9-ul(Mi5A z)Lzd{zAaNCMOe`pp6WM4eYFQXu265qgq*^JJh&F2IUE05QKC%71BrYK2a|hM)dj~x zzS6@#-YLVxS`vOt43mJV=(#B7Q&D`j=rd=>0X8%Ysv_eBd5ZNWNt)s5%Zqrg#Ak)= zET;X(EtJ+tozPm3MHB-6H_c-_=+Sqwx04Ov7f7Y9H2N7gv^KRK%0JEh^QQ};4`cnC z2WPz(>RB?bko)=)^tMiCuJ-&u-&5HDFp-OhQV`T3vcdErbSwtT z)*@%Gtdwr!xx+FtT{bJ96q@YQ_sFg_aJt@%^sQ5mn)SGe?u z)*qE?0qHFvxA4903p5^5$S#6GA^s_7Z~i~9}tUP4xjsY6gvR!5C`e1d#gw*fz4q7j;VB2b#@d5kT{K8~ zunUfP^rC~@ZpOY9f5-LSM$;3F*cV~}n}7|Rc!-4yG*yJRh}bq!ds)sJVc^1A>KyxO zS)~spqmU`U`5t?Uh>s1mGdT&^{c-4R!<+QyIWJ8e{hWZiY@v}K^Ep|J^BQpoR$d{|)CGx||!2F`gYXrmwkB>8yoD&slT zr;xhXtDh8>OD7cT=5%Cgr1HMBbJQo&835rGvBPu^o3%Tvf!3$UsG^O6n^ZFa7qj}f z=|(IZJDjmNpjLtN#^`Oc%o>C7;AhS z(0TO-ap5L#UFXpnJo-R;{tPguPoK((G!uP8eC<dRlTA~Sv_pI3Y9*~-6u$+}FRm+7gn z&oZqg(A+Vzu zZ$G$s;}Q;6?EMw$67BnBh7yPl6ltQlE&$v~u(9H^RT8X`ap zVfD$%%~PR`5L!W>$ebIcjrt*zdvEvGsPhXT##t*HV_`>R?KewMIj$l{^_y!-OjLN(0LC>oTGbmH8QFI^ScBfoSLJ+`oROy_5zLo) z4S;4T{@F0-rvH2XasL(7{$KT9^`X1|KMf}+zVyGk7at?H|BC(x{z3oA8F@+)UAX_9 z?NxsL8UXm_&2K=GG>aWms@(xl(Pp#`F{Y;3ib-E^Z>k*&*u31)-3jWfn@P|P&Zb#U zIna^!6#Mxe0o%yO!EsLpr;o14x32!Iy;eJV!sV)}3tilxLT*DV5ZQ#V0SWEMpB#`wzRg|atV7XbgKVY zwhhf6?GpMaUI!q})w|Y=HBSTvLJByeL5}RhF-4O0V2Ud=R!52dU}Trcn_m;jVFhh; zp_5@6okTwXw2@2HM>z{s(>S`9kDQhGSZ81+(X~Ee+T zJiO2twCF9FW>j|mM)46jj9TN<>X0}brU<>*z8@WCuGtuuzM);XY;OFlXesNlRfSF1 z34BnKy(63D`O$pZ!uiD9maOeG1_|F}FCMMYaXN#y@43f9&m%{>j5M?&Dw>J1>BWfz z60Zk*T0Me7>OQO&AF(8@vLI0ZTcQQW<~TG`vGnHXM$kF1$@~GmU4K_^Tsy!;MoCAbL{vD)oSiI~xkUasrMT z23Iy$i+`o42;jOMM&S1m_NKUPZ{}jdaikjO#X&0p^Hy4JXcxW7=JNI8{3HQhMW1?9 z-KcJqr83?yQHR354u#}!@CJAO-m*6AUu1TeI)9*4WWRZO!VR-k*U=b!@1GfVXKLb| zUL8e5{*Fu0%ea!WnM>ojs(73aPMBFyfzZ=zz^NSx!EtEl6dz^8@Db9&pfzAlDSWge zSP|Sk6qz{Wv-YgjUiXcxet$T5`n12um80^;zypc?EWcFR1tYW(_2qI72dc~){v5%#*I}9=SjD* z#tMbk&DkP3RccB52od_m8Yyh!6X;0Ezs8NfvO?ikL^{$r$CIK-wXs>Hds$c%6{@pB z;a3>nE;)7(r*F*Td*jB#J?$JvtWfxsdFSP5CQjeDN#*!V?G7Ywn-vPbB1a3ITXmK= zePcxBNRfq)e~lYctx))t6adyaM;dYZ#sa=`(-zu|W{w;y6n;fa0XpXxNu0j%Co0E8 zB{7q{Q>;+UpH}mAhD9GrJ zZob4Rq!@^F*yBeeHI^YieU*!+Y7|kdQADxQA&Qj_QLIr!5f7oXtI{Egl@3v?QADvu z5yeV}C{{W|u|^Ta8buT<9imw25XBlr6l)YwtaONCr9%{J6j7{EM6uE#ij@vgtWiX< zMiIqIhbUG$M6pH@#TrEvD;=U(=@7*lMHFikQLJ=`Vx>bAYZOteQADxQA&Qj_QLIr! zu|^TaN{1*`Iz+KX5ycus6e}H~Sm_YO8buUq6j7{nh+?Hf6l)YwtWiX<(jkhK4pFR8 zM6pH@#Y%@LRystnMiIptMHDL?qFCt=#TrEvYZOtebckZ5LlkQiQQV}6VzN;w>#9i_ zJM0s07yEBVzF+d+?9MzHLcffcWC4zBmF;wcML_koVJkiUM>j|`0%PQP#m5#m1R)z5 zzRKCld@)cah^6O%IP5lkAMA{_&5yl>n)rhbPXJ zg2VrG?mu~8>}mNw3154vJ}vm&+`3csUVoM9^n)p|ybl`J>7(RpBHq@ucINd~^U?JB=^9+f4aGpr8coy))x4^To zz_GhFoQ_hazq-n-uRzvY>Mi1OSWV~X->HQS!ul|p2(`+Y=Nw?F8cT=Lt z86(KxU20IIK2olPa;n*=c`S~lZ8-fgRfndN!fA_SF=#)+fwgRZL|I{sZ0}S*OoN54 z6-3UkG1BnyHh_#{Vkwb3`v~d?GovcA#RyxT#Z5@;_!ik)$3B)yft@RQBY(qH8I^>k z5@tSqbwx6JF^g?Y84T3T6tU;+d_0T#kuW+93eh>gEO3#(dE@f?t5=iCDkHi?NRU;% z6w_advF@o+ZIX`y!{~q0)cBNgEEoL?6Gc8sHIh=$Cc3lBM>VE@?DCP)T+yF*`6zTQ zs(1M)s1cQW)#ED?xJ2*i@=;n5o!sT4NK~TV>he(-si@5I_%el8iXNo3@gD_WqV-)q z3da+Dy30plYN9{x^3g9JAL{Z^5G%T@%SQ#zIbA-gQ56T_@l8@=v;c-D{-YYBX?%4uZIpogg(&{a**F;+D;zF#aYIs8Ru zIE<5zj{^C4;Eb1#4|MrhBp(-c`B*F;MRhJddx?A;)#c*^`IyN^denu=7D5Q4`-wk4 zDj-pZ&Oj;7%QaG>UhXz(hD1HoZGrbl)W&Xet(K@I-9|k|RBYrHMF;*yiY=AWn|BCB zX8FP3rfzc`B$qjM7bfuEN1@gsnJhCD#xVY`NcjjB{|+?pR~1MZECFmq2G#Z28O@Of zYCrq4a>R0F76msTJS;O3F5Z87t9{2}Vv_M5M4q2*xO@zHNxikjQKO zY5g4}?2vEcZ;bPTf(R`TUg3r3;T1R@RMsX#xtNLO%6t@T&9j~(t!Iw)lu3+H+0A7a zMJ59tb3Ke*B6k(_FdqL*wr;*!|1ayygasKRbCABKSbZGIQ<@oB(bwq@l69GtDV@BD zS@N@Z_enj?#%kwoUS(Z1*Edoli>WEUi=;Een(1iD;Xk!wj`qXO=jf~Ugd#DanT^Gt zDK4eBO%@+`Y8h`+cMClWNu^p`{F#ZL-P4x0uQB<9B(q#?M~0~Q+>XUos{g-V3sy+4 z_D7l`txfws=(Qa+Y*F&|=D%HjZR^Q9TAP|8`y+Z|>q7J?F=YcAQ?j-XY9dLR|Cz?D zdhIZOSLb{oFho9e({RAo@S= z{7dE;+!KFYkwZxw?71hMK+`35&Sr%>@VoPQ-k+b5{wP(4NYPHoWn(J>k4G-)yt;#juU)-!~A z+O1DeORO2AW%VWk^w^t`_ZhXgjhB)%bVI-X_LMsQ{zf4eKcQt#+7P=ep)179@n`p5 zLoyq1SI`9}9J_Pxs(z7Z`^orzi`!+=vR6L}=cM-Pg0r!y5N&YT)|rf)VBvT8rO*gl zfivYMR{>jB$r2pAMa;-z{kLG)?TY!#y=#vxu1aQwB3?=UTT_@-G-sse@@X`Gr;O!M^pe6!Sw*^&zxZ zRwh}MHqDk0`u8kb_#YJ$$_grcGBKDu${So=FfH_1Y(>rMTq^c{O0Onr*3Koay3I(T zKKvPd;@R-An}1fN9}quk;@R36U!uPm@x=0Y&uglkagHl1BZ;vrX}G*&^R7h_VuQ^0 z(9;uReb6!RQehGmwsB>MW0K_1Uq>Fa>bElgmHzcq-14sLvjNQJzEDAMJl&kJ#S7>L zL|)}|7-g4>VUtb|F=o$jZ|gs8rapUyK5b^qQ@QA(Pc>UjSDK>!34Xx;ILCKA&FVyB z;M5Lx@D8k>`)q)_v!oH!xKme4flrt&78EZJd74YZ&)7*`zD+xW=MX6(HZWp*30ca! zG*lw*ne7~5ErNcDdC^o}KQ&+dFRtpdfxUG{EojztpxTdNJvAigOi3jZiJh>U@4(CH zK*^IPyhI@v9~3scR6bhYW@{vh0)nN!5rIvlpFX|u@mdbtN#3i1Cv11C zu9l>;6xsKD4^VSGkI8hGD4v^a0SKco6=ANOJ^2(vI+PdpIAJNEH^Nk>@D%1>I80$N zObu3L8AbBcd8CgF6CH;}>n7Nj`GUB0tWlB&)r+r0exVDHG?tYRh+j@&8>TAnYo(wLSfR`D8zQL&t|L}m%MQIc0(r}`J13Sk<` zaHjCg;3-^*P!**P4BaA&)4*De_r(zcr3SCpeHpPp2ApD3*q{jIXRiZuAVYB48VFvudm$@SUcB$Gvh5AI? zrxiYN-!e5DFRKFb&z1KFPeiyAxg6^0e8%5>)mDX{ZLRO?2kSpcg4Yv&IYT=}+R7+f zLua&q3ep;ebllJc95U?Um2bP&KCkRf+M9zgS3lSu8mQIH108Ztfe_hTlUMdOD*tB5;xj@z!(MM_ zbgxi~cc|F^(0G~sREm}wdHhv3OVp_)2j|J`mONpfXtRwBPf5w+i4Am$hota3t5wCc1ELs8n1;OO3%qp4qoMdz> z=rc!)gA`1Zlk<3H=*b{-{-0)0w3^5?dqRF=`PHNysi*hVw#}2q8odzUe-!J>SLE$h z8>`r%%ZKqL6qKERP}*63S^jqaLx;fESgL%*FX}0IN*o&7r}RedS-5)1Ug=bU+qBu` zw)gk_$a_LPtz+R51}pzy*+=?0E>U=kDu$M)W$j&Z+JdWoI?{`(fy}hfNm!C>UCkQ( zk9P|S$zUopA{5ZU(TXcz@XQ6F!rM@laZmu?P?Ry5+3CHj!sXmCDvEz~BV)?4#P z#wn7Kx>Zt(6Z|v&&B<7#Ujypqg{xFFqb&|}CR2+bv)oL8Qqx@IYWj(B;1?-#+ruxY z8YP{D5@JXjVLnxkV%EP$!2e1|c{=)vc#(-bjA|5Z8P5d?=P;n-Qx*$tz#qO3G9hTj z9>!L*j{K?jXYCDDV^q)dR;$KXwpE{`1{k1%+IC7)19U2qA&W)Z<*0^GWMshSLeS+O zO)ZK`E1x23PAGaZhW`EiGZIpqd`EL2BxM&>61bYcm>zts)DF7*Pq*L~C(-}?y4D8y z#I0t`+d9fEV94@1*5+%0nyeX2ZCpx^0BGtYFksf!{j9OSC#V$ z6h@jWg?Ow+-;6e7hu7dMykq{cuok$2a^Lot(G$)Fb52b-U7*~2d8kBSCY9U=7e@a6 zC7{)48d$c=DL`KR+Dry&$*Fl1HqsRwLQX*t0aF(Yh|GoaV$NiTJ-I~ZsoKM9b3HhF zl@|02tqvFE%C=y#t{fOCLMXTsxl(fWWTuYPt6rAg+ap=-v_%5qEk)E^RLTCTYH0^~ z;+wRV!j(R!LdwW)A1AC_p^`D#DpBZfe1hMSKW2*{cK?qS`Ox1zt|FoTKkKQLK+K~&?t4x^DHU!79a*jPO z`Hx7>MPs3KuDL6gYvGbiY>ZTZdM10L82IQ}1_H0ep>*8YV}|+%4!H}&f*Z4M$(F6> zvARRlF0;LT(=1@4ut{bBdG0*Lii6xDFZWGp{_iLe*E5z6bH+?hQYS2`$rbdo4Gb2j zxA4S>uX8{D(n>!+AjSd96&6?qJ7A%Hg=o}oLFYdu*F_|7DhVi1`K!_-m#XCaT;C;^ z-jfM5GKwS=Fa&!`e||SeL>x&D+QC`Ap5IcBu39scW|?jp2u6{bAYOg!ORfF5+m3;Av68tuWeMv-MbOOZMPX!R*s0j#tpDhNnsDddUoPkX^jZd5smKt&DP>}}nt+jDW+C)<8 zKg^&(IEFtH9ITz5r;_`t2a|TgC~~^}4{>3MtFbzVRJ^;wFXbFXR>cgi&gN5N^-wE9 zKL||1)gyVOE3(qnk({Tw)xMWg30l+#k4d9@`m29NTr3fPO}ffqOvuoy^T=vUnE48= z5~GT%6@{->Qep9EBSk(-ROF+RU^|TVhykqj4JG=2jUnSSZ7;W5Uu1-(RgfU17h^St zHpo-dr7Of(UZK-H&>gJc@y2=lQHB^raboF4ow6=@=k6cRG(U`zk^FfX` z>}aMvvcGOeI)^d)52WP~t9M8OF#XkU64=7W_A7g;t%n8Pm-q}rw$B7Urok3EiG9Er zt!-XezFBX$>iTS;Er76=jCm9m86X{T8dmp2EZNS_PP<{=pF|yV!#VjI`a|^B)K%TC zfaYY}ue!MJZ9aIm7bXbfCOd@Ld>)s@Els;pffcuXi9?a;VTpsO=B-z-VyoyYXl=>C@~!N`2=xvw-r8G* ze8GFR3jNgDE(*@tDhE4U>k_4G!NbdIefrzu=Wy zMVUZr>mMAnRWt~+w$z~imEnZ83MFFzLnTNY(EAmbp86keaGGL%J;7w=hZ>nsX84iB zyNQjBG7$nqV7>dH;CS$!R|GC7XwHt5#=yWFC8X)Vf$fwmc^OXQg~X+V7|kp4PuRnZ z1wf0e(Tt=lW04uq7X3ubYa)SuLL5t^g1Nuf`>Jawe?3}F%~d~(ocdU(kU%D8bfyQ0 zcW$@oz!%(?J||j>tiB_SNiRA})c2FlcFBQ&MNEXgQRy%+!D%&MuJA&z`tX_#8y6&UTs9$)B8*bAEN0s)$V*M8{GqdWB(v=E$XfX?h=< zbaz0X6*F<#eap@w!ra^nc8F{Rw@)uN*JAY{b;3te z-y&d>t)lNq_hhuvp|Y~QO|zbzOf)ShsvVn51FDgQDe|v>hc;>vVaesIcGL+qJE0>^ z=&%zy;Dq)$p*>D$rxV)YgzB8o%T8#E6MDf3J?n&?wnE6@2pQAv)(t7xm^KHy6cw0Z zAhCa3O2!gK{{B%)6#6F98&W3yl#WGCd??_IyIW3R+8zEsX5s(;ALy585ZUxMaH-88(G)u&ivWzis;*Zf;jKmhn?qBZTSd8jeiqh34L@^Ia z$tP_MewVDFmG!zaJQ+n;w&$MzkM$Zs#m;7hNf6-G03GdmCi;D@KtS0xN*oP;7XMS?%M_2zx zJO5XHk2>~GURXJs0BwIn(O3T~>N-o)c?b}%T<3NLA1H}C{D4gRH^1fI{PLxu(dFN~ z4Ph<4d-e|t>%#)@~yT{N!6~kZ~oUlk95iDLbw?n=12N;YsdLTkAge z&hsj>=6k360k1L`9Oij3-J|-!`oT^$QeH4=S|JCIpG(*GW;Ns=3?;*1NBW@>9vfLZ zgvMNzbwY15TcP?b5J=*{eX@SY^h>Fq34JJA@CLVQSh0_7q2t+3`X8@v_v2ccgL^hk zCefk#W1h(5ELA(T4KY>iI(lsJ-^a%2v-apy57;O-LyD0yuogdt)19d;_!|+2y63dE zD~;j9o*G%6c242ffxXcb;psK1$9ogCGL zi(JxS+!}3ji^|J-tqJK*vn$j?RiPK}3@OKF>&1;y#WDR{{kb7}Xde*v!5w-*H zxkvD~6!{+7U>Nq>k*4XkTTE4 z-nXxxb+p$ue{}`vM^8PxZVgxGL|Tss9$dkvSA{du8r?4`;O)1ha}#*8T9EIQ{0qC} z{_!P;ilo$=rPP0SN>#vrl|tH8xzScgm)^!5C9NO&pQ+gAKIDJqUH2C#nVcDtwR6yZ z^jf=*bnooDUmXYPjZv|NP&gaJ%`R8-O>LP3{u_d|h`Qd^c8pQezw7+E@!|OS1v*-j z>jl)(WmYOJCwn!BqZf13%)(0X)JFVM;DKRoihfvz_^9@U$3#B8xK2M@AK_M}7KwPl zR4NPK-mcHu;`jkJX6?+{=59hi^rXJK7t2$ky4kvp>%N0H<37S%Ly(Z<-?#u-hrX@p zWB)Vz!z25OnB$>M#Obs4h1azEpZOx3ny=4l*4ncC57o%`iaq)^@VoxwL~`h}cHsC; zFFp`Xy;Yy}GTT_&A0W5GRHU{a(uRhNnp@!?a5z=5Z~b?z zXtH9G-#!a=Na)B;u9_oX@qyS36CtQFx}9lkBPj1^#7G&-Hq-y^a`1v9ww*UkK?p{pR^t+oz?V!)U;>)SQ;-o zcO&#Pac0v|0Ya-m#jm-n`}hRh3*aAdkG^}@te0t$dmF77Hg$)atF-ngnh;<6J{&-p zu-jw7Zl7z-rPX!o$Jh}SFSA5AwGWM5MjM87ADO6EGy|;|zEk(eU{o{%4+|}&!yLFY z%7EFGT3x2bOu94|y`f|4i*OVnS&WJU@%3inrVl@0W+LkEHczb_Dh|7X zSzKmjIySBCTYE!IZeh)Ul8LOh*KNWX8RK#cDN3@Q1a&fsU$9b|7+~}@#_IX#r0D~+ z22VlgQ<@hZ!wus*!z)4ClWy*`Z)QYodYD*|lE@uL41ef=NEywhxZlff^*^le-IQn9 zp!7dxfb1b$oY2r zmh;JxkGdPA<+2M`Skr-m{+jR6auyM8f|`0PcE~D2b!1vcM=F|w_R+3NQR_>pP3>7j zcg%i#>YV&q_4_s&bcF6${rDu-+eiYR=tm#=QGC>m)7fU}N5!7#cdTAmmGhAL;WUC- z0!jRroakIV{8sHKbOvh%k7N9!(}d{uWbpl*q7^C%`~rvAXFAF=2J3SV7=!e|+BT0d z_kdDQEC@xTsU((EAcFrHWc$TCjpBX!wyfRy7g^i&xjXXTUYBUh+97z7?xqNk3bMXN zVdF3+WOyPh#=fkk$ysOen<^6Yrb2z2lvkTjo8hmyVqA^KUl=+Oo1o)z_?R(uUwB4) z*6vAJr}KA{csDoqzSa6>{l^KdZ{tHm^4b67hQK2rb)vQ%Qg}pngSz8FQJJdsS;xgY z(5wSl+dzk`xAU72ur?vwt`dT)T2^QjZ!u;yqbxFP>Vaul2lJ2P>G*gddF=9Qd+G;k zQ~T5m)K5&P@gx_9K8a1WJXO#+v!KLT$6A}%fV95F;F-CA{&o6| zS|e9g0O3OBSMiSg!>cl7K@n$YqU&`xoQ$IE$DmH)H6;?cSlAU@;vC683@Z2^4xz#r z{g`g}pTX15&iupvN00F4p1PCCs_*V-A#*^7sNmK34LrU1H;NidM=a+tBZnwKsg39) zf)DyAZYkUI>^tasgp^sx@?RXoz$f^`Z!=53z z9jEo+PwHdzD7{8ce+-v7sWpZ9Q(HnG1G>=_bZa^IEqpWMKc;YW#ZCr7y8F-#eAjl& z>1IO!e_*fd>FZ6_pz;7rw}F$WqKOGwbB}oGnUaUVM~iGgZvhmB{sdBUk``J?Cw^1sUbk1yIz-+8`1Df9nT=D(RV4jy|RwBYfyP^GV1-mlIp zkNUK_W~(J8{It3N@3YYyOGSQ_qBo)6p1U)5H@m0Z?8?O_W(tv_m+b8tsdRz$y<#wz zhQXY_N>0j2nA*u`P82777|o6CY&4fft`uZ$sg}`Px-yz8_a;(Ue>qn>tnYTW^gWT= zl6&HwyS~%C5#9f`5b2`S=@`}dFsj>kSMHm3P2c%Pu)ulRg`kle2aU%r1dSWN4m2zi zLc4MQOE7ekyW9T1ZI=&}yX;px%Xf>{fQH3BWUJrkAuRe983?vuP|}QvB7DrozatNB zbd%c$kZbc2hz+Hk;)qG~I^=*zV*=*^J7A+2OnRXIE+%%sBD@oN{h&F(Z#3Oi)z#IUJI5XGF(~^`!wFJ zMiCeOC{rH&UDKE+ckhNz#J;B23CqIf{Y`nVnU!Bl8AJ2lFdJ|=Ha?eN<6}l9#QGB1 zo5;k8v81Z@&{JIUV{LC!1GseDCsm`n;h#cUT_rBmAzgDJI%<7)?$aIwm)yluh1$ELS7$eCRz zUyFILP7-*I_XuY{TU=M?Zwm!1gQb0!Z?iz!#ox12poaoaAZf$Bbk;rxeDUkuu^>IG ztb|$YfPlo))kYeDP_=IEcHTR!A-r#4$#T{#l^)@WC^e=chi20=5ScSKl_SB|y)jEs zQi^JH2|TvUipy=S_qaih%YSivejLZiKPd;WV<6wDHCFy~lo6E}Wc3&SOTvR!AkR0vqKM=QCUPe(D!lImuP^L;o!+LBLX1Gf zI%@N+?fSsV2ijf1i+GQ)!zsBX)D%lXaYO97F!)N>b1)5yvo(@AL;X@;$X9(zNd~D3 zSyi#sH%d6mod1GO)&Gx_c-QnQqfh)GqAs= zPs#LHZyUUusA*U5;&FJ=`ZMMMbyjUk04#dEeLL4?_K(g02#N#usbs?!QvRwG)lQW& z);ssjSkIclrtG(GJONVhWy9w)Tcwh-2j8uyn5h0W;st+10LBzjXHIk(?Y#b~dz0xs zeIGwP_Z_o~^bTD04A$M1V+Ol|SMrW4UeC0ccQ|~PJ2-^V-xC{@`%dg)etowJ@emn2yW~JDg~8&A3?{3d!#ghb z(>OV?j;5>;Rq%s!r&gDjuQ@Z5{LDv4RH_(NUTrS#*O-&?%}_RKXa3D6 zIHKb!Azw{Oqw?k1F(+fa8{N|TEuuQ8Ca5Z}*dl6z^akV&4hDA%& z@&3%cD3eo!U7IZ4xG@?xnKewvlL4w|W4bi+Mg*G$mGKpQRF^tRR0^A~UoL##Aa$~$ z+9$lgT%V$3uU{TNnN9fJZpF({h~!OCc`ZDX@~wDT>Axz!(jq-CvUB;OT6$g*vwR;X z>Pi7r#oK+8r|^fb2euP3|C97efP`xHJ4+K>wc7nt#ff_`k&ZQ}7yP(C!U!lo?)?DZ z3{T<=JSlz8izyRnBUw!++aoh+jG^seQi!gvUAodI=-@8Q^C(+hwUp|N%Ddq|#8StP zK7T`jn_oh5LqVd&lL)-K=I_M+QASuxN0n40hGA{z2?W=$fYmQyKBQQ^j;2URji24$ z*pdWSr1$G5V0C&F~g zHZ@Og=ylp(B}&h7TZg}@Rzi3wKb}<&|1a7w$|yz0*1P;N1@?K~?upfFOjSJ&K>}#u(EIvKqrx86rWXRX&2BnL$VE^uQ3+ojVLGRgzIsU_4?b zgZT~rAVX#udwn0l!)DNg1*6vpYLoG(eC8yrtT#EOCHZfx>eo!EzXItw&9!nqY5!-rtmr*iB)Ekg6yl-azDTi zR63DHgkLsek%TqM!5kds!FOeoDK!3p;^8>lA)y2O^i-@7?Vm$ zjjzCv9>|58@fTE@HAHSvB?qsiMtbO_#AB2wCihhtJ5)$S9R+%cNKyiNNm}$MlThFj zeTRTGp2s@wf4iTNRQJDe&Z{+g?Mw5}2x)$wU5jjIu)WCO3d2w-Se0Kg)H2mBPR%b# z^H={nm1^tKF$<_yp#Y)xRVbT~ELhsQ972~9qQ9ce9r;l9Ls0NX*_l1-#@14pO>IZ2 zVk5%ZT_;Ub>#&w)hP+|zZ=X0`wZ>9XWV>ifYGoHrDQ2*de^DtnUN|L`#uZtiQvS<@ zQx;0fVwLi#3#Sy@fygB)<*OG?DdxM8;~z@H~p&EFu3G}!_U?F#_-ORKK#;PRR;`Zp%%1v|Ws0;5+*s`J}a;k8>d=c`+Ele7pE zXYCBFxtP{4uBMXI!x!iC+-1# zcVkh4+>GUl=KiDX6YT6)l3jtvT;kLiVO-M?k@HjTNNJLZz_oGl}XnQ%|d5?4E+XW&?vNUD46dyKaEdF?hR9S%W8r zW!*x*RT}nnpf43Fg1HugDe6cUtayf9aW*OAv4)v$b2<8y1Po;o0(>#s)W$*Pf;sm6f0TNoq^?&~I#q9ADOu9)Ykf-* zu0i|#&m3lfdE5WYUU!pPSVmb3%P3ULM+K~nmh}*H8C{%K9x%+sVRR_P|Ii&E)gRrl zKKzpTB_Uc!_#+qbZMRv^JV+L{`SlEgZw_@*Y9^xwap0OgpTX!J$kN@6czqhKg2zn+DCp&?fnn` zQ4%Y4W8>wQj&SFK`@Qy$jHED^k@k&^l7N>$F5Ilc&2K%4x!@50i%GGI<3FGHjL%;G zt7J*g`*O99-lV<15;ges`11(f9Q_Y!(oPRqf01@N#WWmsx5S2WSH!F|?Q~ACpN6A^ z+r(YPFG-j<&J#+!HpB`RQ>L>da#vBwyqn&R(?BfzUN! zt>VJT|0>CINFLVyLBXQf8c9+qKfG|6qRtXI!ge&Qy>Q`_f0LBYlXBCh`OkgXUe2$Y zpM?L3U*hwff3EhFuz-tdGTqM}^f5;vte*9sSi{xDk1)5)5$%M;u}|(MZXo$;N-je;+P@hN=|O+>KKj;e(qk>qyy8f$ z+U@<0R9a(FT=TGhsMFdWSU*&&djaQ!{)g8}K~>t&|6-;bZf_QyaBt1DL9simOw<;- ztD)plcWf3a!2Zqdnv%hyUOjB8uV&gMbPSI8{1(f;lY(85OHun}FBnU+3Qj8kG_mA{ zl61@OQf`SXlMSxR$Y*>cOJi)tRw@7E2%lW&KtWj9vquk{}9VO{rTr&^B(!bvnSb_dMuy0YHPS;yAtXp zSFZE8LQP2ASF_v;g_)CPtVtKywcHn05RhxPZ|43kxoHCB_fW*FM&I5P3#Yzk_})vD zo9ly@XB}4e*B?gL?F{DI`k~cFuoW3>6lBK+$#r69P}@!{gJb0^0qsJ*Q=jgB7V^)I zG+lwBV}dyI!?_=I^Camn$2I;c5heRKCy9}Gwa66wn@bY4w$c9Tm<&4j3#%)J1|@D8 z$1qpVnI^gR=n1c^M)3||;05_g#Bx^zK3xPoPRik=6hV@%YG~2w6Seoxa)TR;`ba+M z#m$lAUkRVCuVz!KSm}3F7+A7dFvK#s|TUDCG{2#eM>t zy@);`CtPBRau~Geb0^#L+k(ny*+j)?bCx`#+D?xIwoCyxKT+KIqQv_IrtjmYKi zA^9gh;zJs+YrFLP{C}A_d25De=8SayT(>4O=Q?>a16`l4Oi4fTe*4dL_us!JQ~nHB zf4}mNYsA9RRU^vgFJHJ~nY1FsINqMd?@E3-{BGhmkzYB#N`7H}Kj!ySe!t=OEWbbT z+rh8@Bgfl!^ZcA&65$D@%R`Homrhz9EM4j<3G=a=1AERxej2yEbk=-u}X0{=fSr zHXLvNJ#|KQ9&g{X>v;QA!XNQW*nPbH(B9+iHE(oo%cXpm_AQNT=M#L}%&+*hNoy&;tpIv{|>&M%#rVa9w_@DAF?UHam+VL{KWwhl>ey><*p4?}~ z4{ti&{#}0Zef^u}x6?ce_aARJ_>DSnT#m|Ih*Djn`Q6EH4Zk1r`!9Y6_?_g}7dn)~ zPdrI3<0tuZx2rrTjFo{--y!Sf)UGt^Y3*r-{vo0z9Oh7LZIWdtaScD zd0n)4X=xz1Vntvn6Ss6!z{Rv(A@ed2d|;(a@xai`yS|e(mwC#+70D;sHGaK%o4+3r z{&n2D{XPDd(%SxB6D0?8;6&IU3 zN|B7XFOq)c{Ic@WKxtXoin74`pduH^uHxw>uEon2EDbFzjW0pcUu}KA8e+6;85BBD zR{Gu0;3PvY_%g4#_L@bm;jZBeTqA_KmfsKbM+I&xT@WfOU(6^hUA$~@Fi^T?L22p2 zQsxVhndLkJ^PsDv0*jX}Exm94(!lc2vU^L*_fE?aqR=F-r$bDV#!5v%5xjo|wTmqfZ|PMuLS={Azee@?17t`VW~vJvHF z3q~wme6Rc#j3^H-T)bk0EXDV%2A4sf()r7-UEu0?xu?9ebct)_it@nNn*up1aFYZs zSXO*d(xSLFtRCjNt+af_(p3y_v6>D!fuYM+m{TLmHOqqa{VU3Yu8I5!ET6xuG_Z8V ziY2V%i{>w08Y(MwQpqw;Ici$DrmYCfU$~GN!W1blU$I~@NVG7pdU5c6RYpg(i{VMi zmV=dMKD$bCn$0pl-&Q=~o}4wAYg`hTHhpU0%<&UlWu^C(t|?tGG)pyw;)5#!%jO3c z+^4Hty-#Om}Yi(I8TAUwcsmc@Zl*?;TUPJOsD;b4pZtR2t~~E#74kZ;S2cc=pI?GrKB(;wZNS=UzHKaa$krx^<3A|vAXpr^VE2->^1$%cNb*j zDw;FmS>+4T9!U$+-Hv#bp}lf4CYMqR!VwDi{Jv1Nesk$|)rI1MR>TY3x$~ToPj|J_ zXQeG)!l{pLinReD6yz6CShm;k)bM~OMBA$sw5C=Wnf~PD7cEx4T7Rg?6&GwM8{4D6 z+=Yc11x0EUpD7xWDvzJnWt6lHP4x|~3L@=wd0b@;mD;nc+=cFfNPgQbwNw;cd0YYF z%U48=8#gZ85@-{@Ss!Wey*?MFN`3L#m&VXPMG*Ursh;`9mxjPL>p;JKP=_%j3OfdN z7(L+`++qAtbr?Ib*VD{?eqca{@s;tVac;_tl%-46xhb=Ra*MN7VP2*xEGkhMf;>7u zxeHWkMz-?Q_yQr7TBvmG^LxsDDziw{`Bus&NG&W4lu)4BNdFAB`m})9XIn~;H z@YM1c_iiVn+_+Y5suP*Qf>Q!hZs0#ReWK}~zRaCF=F;Z$&LEj2I@JW!W zPBJ&>tF5N>pka~EX}o++%@FA;cxtTBtG=)5U?evrb|k!-0%G{3Qy9c~z!z^d z24=xZv%)JyVFrEiw3O9e;%_FuhxPL6KzT!LMUAgfMU?TLa>-jhre1s~ucsBSsb3kd z>quq5v%+Uv&=HW3t=y)kQPUKTO1Lg*hi34mWmDbVcBs0Bu2s6Oq!hYxr>3Q6%$=8+ zb@u%1oZP(p1qFpg#S0geEI!9mR_^sxR901=x4fpduHJusAQ);`v9hu0g2ahQlO|7@ zIxTrRHQit3`A(jwGTPAP%5|tJuL}igRLtN*ha5Ka@P7RV3>gZ#RJ?{7u zhL1S$q>(3|a_Ys3Eb&);r=TM7J#EzKqhrUM5jS?+nd9RVCZwD-W9F>cbIx6|^arKO zE?jld5C6m7yOh77t~{i4N?ivDOf`C|E2~2)5_7Yh%rg17_vFL5OrUf(g>QUZEx=1oWe_*i|EQ64u8)tSMhS`{OR7ldyrF!LV&h_uBS` z?jzk_`)OsMnx>FZO<9wxp0B9Y)io^z%4@wT;hqdVW(lpPnpVZj$0p#C__<<(W`A5P z>zpzo%My;0&nhX%a=@ZSW^)MbKAX&sQvL5Tq@x_Qui6 z9Lrlu(=CB2ooxjf+3v-qg<11*-Pvk!MxlzItm11_{8a6cbdFp^&P;?EZi>rYQ{(d2 z2k2E)*SUycH)9oNeT&Ch+C-(!S5A*T(x1b}qCk`MaAJcA2?>(U z4kGH7oqp?ca)yFV$>(k&H38A-a|@?V-Pf5>|HT1N@$uH+75 z%d`&Tb?}0y!Mhf=!5^Y8dN#yH3Brq|dCfa^v0U=>-Yyf_%41Opt%E4GGnC@nSW>6YzVqE_%JSP0gPA zVclK^OiZT8tfbQ)<%&hW+kcn&=J}-V2c67glcr2%_}Mda)auAv{XbMmlOfH7%!G(Q zfh-RrGNVLzS0<$8{88o{`~1mdgPcby%R+|(Iek>l9hD^sq}7z1GAieb9t(~GvJpqN zI1L9QfUF#y1V)0B0g{h;zRCrk21bF?L0=L0{}nz_(7*5V>zkF=_xbhh>i75g_3iR& z(6{&v9C!#n-OQ2A8`SNpMQvmjd_Ap>ON~}>YP?ERlQA1en>UoU>sZ>SDpjNWD#R@N zD%#sMYOPwQu2R>kWaiT6sC1R7vQ@q+QYC7MTBf{~YiS9k9d+q-auoauG8PnP6=X0{ zEG&kyatpJVB-bP4EO%~^^cZ64>%<1*VuNF4uFC2<@qs^=;Z3NtE>!O^N5xC6FIZyl zZ$jiFVRjp%Y&a{eer3d+nh@I%Wwn=iZ-33%FQ#OC6RIaB*G*s)R=0xOQW}!>@A?~? zkoLl@ZL9jtoLY3tr#lZhrtGdk9b2Cdu513qneS}LzVyXYZd^3uz?<8SuS~5U{^Jw= zcJvdu&%FKa%^zfK_-fbB9-Hvl1$S39U47gGF|)7z!>}t48&!JR>Wi2D>YS^R&X_Xm z<&U4-bNv8gMB?uq7&-$hgVB*n9pJ zuFKDT)%W-Kmi{L#i~Y@SH~oJ1$hn^C$#Z^qWbwS)PXEh-`%<1>viFaVKKqX`;|mY3 zyDV%zdq_m$M#eG`>O#12B?Ajl&^(=b*G{@0$E6&q36}f~>iPYGr-E%e+!-xlF6;>FhcN{VKjeo!MYMt3u`@ zn3YUanZ^0MB}Iz2r$`kQxbqo2F#(m4Q>5lH-8VlgJ6oj|7plUHc?+2mDOCAcXcuJ^ zNml(tX%%&6|1Z~Rg#uptV-qyZMzlE> z02_Y;`+==LqN~Fg4VXBoJg?U8DywG(mqtehPkOppuQp*gUN2*~X1Q1j4Aj>%6yT4G zp^+O{w$9|9+F!#jgAu47vRL%w`8HUv6+918)pC`i z=Fwi~s|;#x^i!&u-_0!gDb`DaEa0D#B^pbanU|BHe05Cz&~?{IWCRjGP?T6p#o| zP+CmDRg;q;Ut>tI9wD_fTpL0$oxi`)gdS-JCQ z?&ju+ozoNJU1us5r5YMbR65O-FQcMT*(=0)Nf?n1U%YYQ^kJfy8@+w z&;&12QhFh=tf9Jw`Iq2?I$z}qZ*>yOhoz;K`aAno+fajFleAx!`aApODGP?RTkHg{!2VRY-g`@+_*vNR`zFiD`yRKt%my4x;a0 zFaLY`*Yi0lKH}?6cX$o>TUHb)1UnNgwL1HQPGbqU2#7ie9&y0hDD&?cer0)isVwf) z)7_#mD_xODJ(IR2qfQpzy!rKdiCE?4<+1`PUHb$qdPJ_l?CB?XnM%!~ceSuI$6Zod zkWpNiVO4|3n7|kGmQ9d9mgAmd1~EE_BMCwaGO$ux@1>zuEb>>&w6UTMDJ>@;KDI$s z9<273(myE=O4mhH8HMSoy4ZV$SRSMWAmP12wGAd%zDAPE*MdaT1u$JA4L}@fzTN|W z^$NO6eMKM~j<%NIUqMc!73OCxWVPB3sji*{F0IL0qsnFFCROIVM7B$0wN6DXb7#W# z+?maN>B&4>UuL#jn_VuKnn#D5wZH1dKm+S*YJAS*goz1><8vk^CQL~{1VTiZbjL;a z+oBSC0dcRctEgAzP||5xsqdwz$hg#%a%Ox&smhkVk?tG1#A8=&11kXZJSqNoBprRO z3#!Xq$Oy6Ihnx|M<3)&+U47mzW1R(29}E{_F0k!8@lwp4Aa>V$jaw)GqV>-I2JW50 z7Ck%sSTFK=;r}YOF`@f^bb3reqcdLrSFw{C0ShUU>a8jpEhAIutD8{43Xy!);8JNQ zrX-4_jSESbpg(?==+cWN-*escj;S^b^Sm+_?o~M%hzDjAxzd^W$UqIW+Rd{Y5yD02 z0j;+Py-dU#Sbz|@Sv_)43mRA&%d+IC_{@d^4Q98iNY+Rvq~;g7kpJ*2cNr@zrjmi8 zshC?+Zwi+9rA5Hn%CUw{s-2-~P)1oQ|eYeF8qn>w!+>rjOaK?EjfR#~ah zBiykOEtOV}Sa4kfZquq*tR;#p>3CHkYvF!zL9d1Z%Obt>p85-`10i{5#Eq8HLA=hZ^6hS45B)`Y_~FtX(M%$Q5~P$ExS4_m zEC}jlbyZ9g>7uvE1Qz*c4(S^RaR2U8iGwq zieBmzE4(T#Ks|}KY$HCfyhjc*u8>7a@``0y(;8_Axja!hoP}&z^rJPJx21ekQN756 z)v>HgmDf3<*F4S4cQU1n_#`7-!e^CaYe9HD8(>ACi2k>kvyt?KWnp!Ji@=RbgeGJ# zWVy1N3oW}>Kwih!*VQzc{`8EChy zqUK3N=u*%&gbS9|f=r~NLU0Xro)rkD=`KrjWnL-kt)v;j6e?-N#8V?ptGw?K(?Y#; zZHjHlU{exF&j0}wS<%J=kRAW%o^rV=|lSysq2 z01-3ExQM=);viodm#2b{r&X%V)HQ^38pH2qSpLx*)ss&_e+^AYR8^Euf>+*v?y;|s z6h>a-8fHUk5InA+b*(K!B&wW-Qr;%r>~xz+G-X-C*^MwDo=er#@*FDNZo_qL(4vTu zU?_5F&S^ixNgy69oTpa@%UxQwO@G?81a@Hvc|2F{+(Pqh=R@VCAj1wLQ4S!wE-el( zndUBuWn^^Pb=jAel6zApN9SL!c&DULVujfmsS}futvrZIwUXA>%VT9bBk3C706f=|(E@ zcGHrUO54u+Q&G?BGj6Q)ZraNtda%g{*q*qu-(BADjLg#fj8a)V2(TTqr^W7Fp;4+l z)F`hP!spp`6JdJb^@Qkg)acC}(oH3X;^#qJRPc>)bWv819ALO9bjT+8POk9HP0t87 zf_7tQHGZm&8Gvf!g-iYAG9%zG=NnAF2W@1gBf1&166jTV1EpmiHiKcc0_kK+i#p5j z9lbz?OmdxNsA;#@03WZ^~dSY+&H@+ou0<3x{2MQ zTbC4mjC@^@MVoCuiCV9#HL!MMF0hsRm24_vFklU;?cp!d6~)%R9&P!$l+j@XpC~u6Z4mIzZs(a>ZyLr^82~7%rNEIMo+u(eZ)iT z{l#)0?WQ%#{>KjHV%HA;CCqP|5eZxLlff+X7Fhn2TAYtwCAb7MT6(`jeL3nIVLJ|X z_}8L;;>_K~t)OTYaRryo*=-bN?lzW!+N|Bi(_k8C;`#WqcN-tUL3r2v-Nrlc9C#sk ze>Ubh5f=67`1Kt6ePICR0sWxMMzyO+-HP;ja8_>4t5w$+<2bp*FXKcjnU`tHXh`8J7~4^qus<3p8b3ac5StAr}aD~5Yb;7 zrH-~6t+vDOApG$?!cQVR(OYDNTWRr^_FwwFYSc5M!o1E>--7=sjgU zABfWLcYAj`w%cg7!?}mB|89jZdV-~dCweQaa4)s^Bm6BUoRN3zHmgX_S z^+xp1dFJ5oV=m~+USH-n;O4$4cP`$c{|ORt|35-_`;WPn6Iq=xS8(d^-vfl@mkZn$ z%X2jlvkH0Omj%SmTzTLZ2gF>yhcy<)!t(1G*0-JZ^*CJOV-)xZs9R$9Yr#I{FY2?Kya5}Jm z-{;pilcx{(&P4p^OmmAn=dny^VBw9!USumfy-nG0q_s*L{B)3gN*l)~B_#6F->`4D zu@!6sF<;T&0STZ4Tn=smFN1;m>92qb!A9@`7;s>>@shFI_)`?dsXay#NCBdsYVq0d z{g%BUmY$d&jrzo>XVDwQb8Npo#xD3DfIEh@+MQ8TUCHU+ZcjNAgX$@_Y)De-4{p6V zQf+n1!4672>o)f^KJ9L(mFD7^GLoS{N*gu{MB63|JUfbVx9#rbj4Q71zHJI`Js=^Y=EWV?IX6H)J8dJgFjLGWJo9MU0T;=SxSq(g+rd)aeHhlrT>v?mhhHF~Pz zhGBb*Uw~hOyTKjS^MWJx7<0jofT(|FJzt!Wt-E*&j^AUP1FFEaptN*x{%M?_5e%;M z%6?7%N|A)N6{UI)r++0=tEL_bTMw~wQx64tOgfuxS*H;1#2Zm+|4hki|4Oe2FY587Rl$lFrpY%Laxn5ah0m?k{?2WVc z7=qWc_81+YFn5pfdvG_X1>-mgB2>w07ow+WP35djvErnkO}Tch6rq0h03m9|f99er z7m`M;w$c_>lU-qTHLHsRV0I9YxYJJrCn-0NjZs4mb&Z#-(_tZ5z)?iOs%k%*?6GGj zUgwh5>5&i7w))Hl?R&VeSlMP}Mwew}pi&o?wqO;t)-xj{1x+fo11UZon3Y^pQ}=W@ zdnrW@U`o+X{^gaC2buG&kw+zcp%r8^XJ*NgUU=Qx+HZpNVyxGks`H0}6Cyn-ga#7I z$t`s8!!L(TO-hO{Yhrb9xwOI2KXb~@Ix^6d3Dm-nYRNr&jH{mPj>qoq{%o7qp#M!^ z+jrtrE4)n>%d?H1_Mhn^9%Ao#hj`~j>AfDMj`r6M{~^pTxi=EF=)XdEd*K~cxH~OA z0(-N;5)fngd+2ZW7{{P)LeKW!4*yj2Z^!&2aO!XO80Ug1oAwx^@84r2faC}E7(WFD z>bamD_1*A(_?E}_7#Y9YW9$S+KDfsyyKj&2@k0?7^*!jh4}wcE6Nufu@CtEqLSOd3 zjs8CT{yO_kVT<0^&(WF9q9sm27e%SczaM(uWxuU_EYMLmBV||K9TyiIv0z=*pd0Uf z=SQcGcxBtU%@cl{dUg7=^I!dH>qB?E_s}Qj{$b(tFOK?R@$Hw+zUHkTjJ&t`o|v|N z=lf`ss^?7KfHT5%~B0AFRIXkoRv4eR1PcPgUQzkGC3|J&84qpQH2HT!M@~Qcp0?b) z7uTQLQJ+xt*`+_{T!cFsk8NySGr0fr>-HH>T=mbI{M+~3w)crI8_$2P?dCyG#k{p@ z>Ir}GCr)2{#GZ+VZ8eTMuB7U&pYQeFp11Fb!7ps-kUTu=t{2xxKAzci?Y|{2znFS* zspRMDm;U`XlBcKE%sNx@b@}7&uOx4qPW$08lE0&V8~10)<5zs2pDy`4;jElbC9k)< zcjYCL-^mYUc1WI&cx}+blJ7U>jkr(pe)uJ|?@Ios_8)MYl))4A{tPLHbr0;wm9qHj zgT`A@9`#pV_@$J|{l7f^EGd^MM?W7cWpnMA>Q|+F-Z=YvqZ}IU*n!R zN6Pxc-(7c;l=lba_x(i5yybzFGo;-A{@Z`eld?Z+%B9Cj`FjU^ku7zgUt;POsRvhI z-}Rc*g~TU{4w3pWyx{YK=Pgo~KArA8QR-9NDdne2o%-bQOFxi$bzIYP4@liQvoP?H)UWlPG5`4EtTSGW z`NP)Jp5J`=>!Kr z7%&sa+|Ot*2b>F*fTiFEU>Ud&tO6H-9|HNwyrm4XWPl}utI1#rmuzp2wmpU~VlkNRUUB(uvH z0pfr>w*e`qKXOaPO9LWtwBuTk)n!zI2G9&1u%1PK4(^_Q(lEA?yS9DZ>7u`Ct+%4E z4{~%!>b9C~8*-`*b0LV(%7Su;^U#n0uZyxm*PJZ`eq~JnTkGzs8mX4* z`V|~or2;4uU8`2P0^)_~*+HWs!gwJakp{1yILMPi2>b#cB2?NF0+U!AEInEzmc(eL zvtCCn43$<_lvV`lYt3>a%hV04x{O^-|NFQfe_sNB192C18LJ4R7`_?46n+&%hdbkk z=Cjzd^{+(lVbK5LE@J`^x7Wi*ukJF&fhEAU+mnBS*##GN8F#>=FX=MQ2VzJ35PeZU zf!@$dyNt!)IdClZ5QzRvi>u+A!N4_LMm)F-Yz2p3)@7^)FMzbnjI{Z(0dQ_nRt`HN z^9nfevQW6RXi;8ide*$GqSD0~?t(%&3@}?{1uL|$y(I_E;zD-~IRMwCn)K#Uq;?T> zWg!CDX-@jmB9l!%q=sZL$Ua|v!Y9KRW{Nlx$Ysveaq5)}ZG0TNR%0pIfyI`J*hJZ@ zaUSr+$Cky%E=FgvSH(+Hr}C~NFRqPXiS=A<@d{W%6|v=d4)RP<@}zh9lrl7ApI2pF z+*qwi;89j8IFHY^9$=opGSaT0iP`Or`yTcil+43>6$w~t4 zZgYs@oL_%jl6|x&;u=*xmTUA0yFqrR>mW^uDwzWFdC@x$KW#CZ@z#KErAU?5%5k^6 zaY3J>tt!qC>}9Q%ZDwo+X4ge|75>JLwSC45ts|15wm`0A2l}$#$VuDWK_@|&vese` z>yaQtqgx2#p&WCjWs;fQ3)DC1B$fr1M>565xgac7v2V{h7KBa9)`khiE(kf4c!fwJ z*VGV}RYsiH$sua8ahXk1Nac&EoQ5odLs3UKQ+NKnxy!im=`Q0%_|cbmm%#Dh2upp| zSt5C+8?rcd?DDvv!DpUJhWwiZ5O+F91&p=DtdV(?jl$Tg6jAcJAk&v@vkq$6^*C?k zSXyK)8?Dt?#}NLa$BQ}fh zv>mjLcDEcML&Q~_c-t*!TyYI`%yH=Sk0k{M`|?nsR>((&k5Blc<&|TQd zUy3vrlE3nKvu#K0cC%V9R{b2Ohk*F$NIx+d!+B}S#fg$61r3)L*Fxpu0P6;QPS`N& zr0j7V4Eh6ER~0?soy@an;EgKx{hUuP#RM zrcV1~Zagu4i}rCwZgtHpm6=z_*(F)-LXIGe4qZDsxLqkf08gCaEB!F#Lt`adMFrL%NBU#W=Ih$ltO0#6`~D2nAEby;jYX z;+Dx@AkN>Y-LKuIJdh|=qm z1Dq#}k>ap(gMkDkCD$TOK%s@QQ z`zf?9rJQskh((-JHa1HPg6z~}VU=B4miRo)u->yIu@DQA= z?H_b?v^`y$8H90Uh>@+aD{4HI>_lUC7j3BspvWGigZUzEoc2)V=vx`+ zsz?V?w{TWeWcP_=6)EaGFgUBUA;p_Rq^fzS*g;8)$3h0=2@on&8!Y)WZPyB zVV15sIBcI{Xl*Yx**a?c1o2P4SEHgl7TF;AS)2NGy-z)V zuQ44Yf-}G`!B4>&a3PSFNB%JE*Jonh_v5|B@+bCYbHJ2B{Z+brvmBT@X?BY8KJh#b9K8Lo>4GkM!dD( zM9juB@bPfOk*Thh-j{s0T)OTumN-A4Tpo{dh06J$d*!39T(f7Rhq|239A1bMzP^?s zEz_M>s51GV!HQhEa_24vg^Mx@l)G4jDnyKwb6m4zIKh#-oZ6y~)ho>627%&yxot)j z6uJej`5BAN-ds-l6zTO=sq{=XiB-_4cV%)K6+2T^I(E}#5JnfeP(|Zt%CR-I zhSoW<2{g{@A-FoIYK`@SN{p?=*^03*ev8Iy1JmpA2tx3 z()^+Vl`rw|vm>IiTlD5}T?^kQ5l-<}=}eZ9wr-N+WPg{JqnPT(DmOosmA_(Y*kilp zR=FgH9(%}T-l?GrpFVulHo>tfgStnj&phOSMj9CzsywCL!(MJy4xJ_i738Ixn}^7W zp0)}L7V2gl56tnFlz_V^$1Q*C2=;Q7>y~U_Gj}MU=9e&K+9Z22b(yF%xjrH~d9FAa zgNV!}arMx3NY_~gX1QG8eU-KWf)j#e%NF`1w~j`I5(d^ znQZ#xV1fX<$>|_w<}PQhH_@8R~5! zui0d%E29Vm$e93Upph)ro=nodOfuEn58}=-m8?R`_7vG|NyX0BA6A#?mQx-0pz047 z4Z>XVTdoCQzJWcobR5K)NUf?OiC0KsUL+CcpbM&>IcU*4Nu=>oStWA|6!#^uQ%7f~ zc}j}5%jRO`7UOf|kBB+Qx1TmkAEXktLLWLi{DRZ_;5ruUNKd@`D=YTg<_pL41$%9} zwI{^|xvpIDjCVjTyfYh)`Ba1qyCS%!n$^JSO{v1H-1(fvfyf2(5`~Nmt%|{T->erh zIC16aGdqH66bB28;%bbAQc@HiHMo9xyod9DeCFGsONUd7%)`~{tV?y2%;lk_xW#1Q zTvA}yZfii3TVf3&aG(#Ch-#SdjOoC9#tU;f;wW7$w(UmQp`Ozp4q`^_;xrR#mru?b z(VDs4H0{fnw4wMdpExDGDZ8a52}rSFa*mw6l#2;nAt@}C>Q0v`U~UMtzFVRxHAFO} zlJF?Am-<--Bw9mm(UGfk`08Swmdy}X>Az^mcVBrtGCgTE17qbBNM;~-g=zy4O3mt3V&eU);N9Re(Nyo}1`$0dz$^18!--*45-HQ?M)`ugAxQ6FQ(iX)FXkX6NzLY@ zxSGb<>ReAntamBh1Kl%=Z0Mu8aupQVo2ylwb!_GlL^~T;mkio!id)Yzp9qJyy=g7 zjZ0qGYdi%ezqr?U159{!ukqx|dySWXs0*+&>y5p}4d4qvrQtt?E@e%Jh117G#V&DL z@+wjCDXo?}_^7wM&YZJJMQMyT! zC#PQ~-lrOz%6p~%%WID~tu?(a2Zz-2^^z|vo{N|i%Myu6C11N;V`gMOhx55$;S~b= z%kAPT?_23%=|l#RIuVDeI7vX*Dy@Sygw6hX7eFEv$@zmQ&w)3s z=fA=XxAjlP_=j3*A%@`kCv(~M{PiK0o{)^yPtLDA1{@2H1NQGoOK}7& z^Wpa08glPOKe8+aSXMNNo+$ntrQhFDKLQVk(zo3m=AidBdbip7Hroy?7MTuNxbN2k zhwvO@=?#XX(Vyo5Kp3V&2mXExqs6wl8*VJ3U$6Td^-c zv1j`$e%p{XU%rt7`7X-)B`oi!K;FTg{z|;;xT6gJ?DtYM#GU;U_Y$7mO?4`;!<2CB zd#&VqBj4f?AlSsr1b0Tu)xG+-4_94~qrlm4P+ldI;w+BUv7W83bukx`y6q}a+M&#% z$utSG92{H8malS|Rxgk2O;%@^TT;%D>*B0Se9fEk%mXBYUl+8wIfV=Em{6h*jYx%@ zJJ~IC?(FjJGqTGgSg?GbaW3$I(`)t_^>7pT5%?+C2TsHOTeusDIUjlR*MESm>c;*1 z^&1$i5xKg@(mlky2QudHn3yACjvN*fqwj%?i8(%|-wFNt4eECg^JstnTWYEUza#iY z^rH^-r{5O+Pjq|g4d`Yg+ICO%p;0ymp+1CKD<^H(zjUNr-CELBU7)5McynUw-vysH@ zM5I3?yyNKk9z$%7ByNWjo5RS1LwQ37&_n!o|D;dZFYHF*75z{A>a7=T(W_MzOck@v#Fe+MAPY)N$un;mEvObB&+Mu-bFHt8w#CovX?APQ zjoHr9x?odNDYMzMTczd-F7hCjv|3-*CDdeW~rf-&o-s$bu$h){7 z^$fY8=HM|z6p^`lD~hGMwI}dzkZ&T*!&00TML7-F$A!r{zs+w+d{mZmuCZ;?KEZH;}AGq&Tgds6U+&kgiy*)_ZmzE^#}jb-138|ivm5HpZm4lLR2KUDdF7$p`W5NE^4YUz zvtlpce~SJu&$EXp{%|A1Bqj;@!+G(p*d!*{Q= zW*6qWSrIX%67^LQbv0bSkUb$bH-UbPx&1R3G04SCWxI3d^>l(W>k(5*nv-T;qs7XE zj)#aQ*inj{Ba0^T>lyAGW{2%=q6FZvw3TIQ90@DqEK4M3h(y5$lVPh#%)Wn&LNRhq%`?dia6<@w@r>ZaL{y05r-W(*mOz}LK+S>ol?Ys2M#u!QpAx5 zy=`*lfrF+~iY7UwXp&QkI4Q-!Pp1@3a!S!8rxZXaf*WA2?xQ=L*Y)hR_&ol-Q_DMeGAQZ&seMbn&8G|eeR z)0|Q?%_&9GoKiH+DMizqQZ&seMbn&8l&ygtNwOUlOC_ zvZ6}H*XGqFdIOisyhjmP8uMlx^Ntu1OOLXIuvMDA2uUYi#KBjRL(%ynV|DVyyd{CO z(Jf`O1VdukFCb$^-B*-Qv}BaET}wprxYMZI+$|T8JTx=e%t2>!d{$N{^eMT9m(2B< z&a}K62WaitXB-M%-WS1ryG*^Eu;?2Wzk|Jx_U3F!O5 zs!r4HO{hC9_1&m5@%QTxSvNN&2iP{@(o+a*V^Y~^rD=KD*&-*5;HL-!Gny&Y8&$g9 zk0;Wd?8Cr1nBG=AglEZM?J&)Zz6DU=N3i=wl2~h?UxcRs=>RF|Q0>PXN zx|mJWEbcC#*fjCTc0!)yZ`d0xC?-ydvT))l^Lm;lnv`VHB$FnaG{vN;CQXBC>+4Fz zg|Ijg7B|A;NLXA6i!)){U9$B&-C`XBu|Qwgv`PP$qn{+kev`bVq0)-lkn-xkT3yQF zc(sufN`}}B3j2S z5arcu-^2rvvJo9*L>hveOeDK6{aQzhU$cmyOo`$ZJ{=~q!Xg=KKZSE3O(X!>GL<)< zyS2HQo?U=xa%Xi~UU~*Xi!)V-bNbny33Ck;d@;88Jt=>VU-qHmGDoo!WTWkWrQbsH(TM} zWARCY_8UJ%zX*QP(mTL&E9&SlZS|Yz|9JHNgJJ{bg1+qaW&Q$gK8$h~`R?^`4m5jf za^1N!cNKD(HE*>28@BAasr!vb!H1v|teCdnNKe^sRD+*^4d9Bi_8VCU*&~q5MSh-K zalL28enZXNZyXAa1}6c|TA@vHxs}>BN2v{4!5j~#?c8<68?%4cy6h)$KYniZS53dp zKPLT8vs2ys4S^3_2Wr7hK&d&nWd&y6MK>KEf9;H{)aTGP|+v=izEJ@nA#U(DULclIX(@{)6sPEOpLx$@F; zW;_|Z_%C_KHGH%4U|OwZ>YcMq&qvQOd9lfJes1#Gr%gVuOY`bA3FHk2;T~PCdCi}% z*X(=c6=7HDhW@E=`-;qI!na;~Vl6!9Z|f6pg|9m0nJsU_lgI2@J~YivkJ`|7*`moS z(o}11W$jbCxHvMw<;s%%3bOTEpP(Q+%7>`C9^-uj?ZCZdzY#k+SXa%4)zA;d zsIpLkdghJ&#(+QVH}=6_fOha9cpJO|^w+LL|I~sJ2aJnOJYf9g1d~NwH$3tzYOd<5 zuVIN}r5qT@>}}MBNjtur*}$Q&a}OAsz)!(@U?&(g?|?B4WCIUa0e%8DfQP_~;6u;} z4$VAZoB}3+Ot2ILz!hLUxF0+R-UB(dk zunznZYyc9*x5Yi*(cQNV=j-g>PdxM)PoC=fQrX-L)p{CLSTFowo|A$#)69IV4OW_u zwG5vcdXjk(~3>OUsTSv15=~ zjtomNVtdQ$fjHG}%m{41v2PS})(h>;$<^gMo3jFnq<;aJ<5 z9g03WM;w-w$4wk-xni4Clp9YVfatisOO282!R@l*%SJ&n{$FpI z6%(X)IJv2kV@AK$x;a#rMckD>&YcMb&Ga+&mc=5rhR7Z^5wGV+2zJehOpsWX2s6C1 z29)eslpSJ->oZW+YfEBo4kVc=&>v1&*pgcUyX8V8bQugX6vS5d7}PQ5Cw$qDNLtw2 zLKLc4 z@XwlexivCket_JNnU~52R@roH%w$9^1$M2J9b^qUFfDjMNy?;$xg)HIG_cWA-{go_ zdT8!qb!k#UlDS`aC3`bD4+v}4?1_D7gA|HLVlm~js0u-SN+4p3b}E&hoC#W++Z=qiT}oN`2q^3{Ju0AL`(^ni{_xIm z#u-~{mnOhyX9#vmxTt$vhcfW%X#1qOP@y@>c( zdv?MNUF3CT?!)J)wO&<^d7UWR$ZBcRsyOOi3W-a9S>BcFmZd~x!{5QZl(G(2Ns3hF z3ni0emx=Y};)&jFs6Db8-$vHMUII1s{31Lwsw zDdZXyf(;7E28Cz?j2;0Y-N3?sr9!?zA>hEW`3kN~E*JX^9waYu6VM7AmRE^Wu28_C zPh2*M(*~wPam{%yvdbMm>V@&g)W9=Sk)NYtJ+9a?S1iJxnJKY3DY1pFSWafkvekYy zm6fni{YrbDWu-aM!cGQ}t2_98S|a^*4AOANAr*H5^D85mUpa~Sm6MT~J5{-uVHw2? z%V;G2#voT0rzQQ)MAl9u0w-{e=0qg$CNa-41=+D_$dFC9B;IDKSsY_I2T8(I%1UGk z=c;)slUsVuR`XT1Vkfi8|r0!P_sNbmv z)kErG^@!T6ey<)?kEt!{arFdKTwB#s>JRE^^^AH}J*S>mt?C8!qIyZatX@%nRIjSn z)a&XE^(XbFdP}{n{;b;6JIIv0r`}h8Q6H!e)i$+V{Z)OWcBsFpzpIZ`yZS`^L;X{I zs{W-uQ=hAy>I?Oy>QJ3(m)foNs4lfv?NeW={px`Fx03Tb{`)n+!|A8xoEGBa)YD2; z#l21EspZ_rRLkv5^~$f#R{_Q8gxu4#LakJds!3hYtpI{Se`` z!@BM-WORqzsc^T-Zk6&!bRhtUj| zzz@P*@SAY+DIG?qJfGTO9Giu`(>s`NVeMjchmkMOu^omVP9D=?tP}k+I*g5Q8{7)F z#&sC&@;tV~73E~S3JE%0mb;5C#B+z1a_fPZizoOv1f0k^?^IQjAp z<0^TEH^FPKz&+d!?}SU%;=X`%UWt3S`Nz12+u<5G?kChQxC(9&eYjQh*HOPjA0AwY z`=53gaq!@ubr_tMr840vxCLG-`aj3L=)=#zYvFCeS9ch6+*AuZ5-z!h@_^UE94(}h zukA1z;YPR_uKFeA0cT!MKEiEq7u?+3VGJ)O9>3}^lHtttxQDCY5WE(?3U0lfd=T?H zI*ga$;dk=B!tM8W7(*8l&I8nMxaD`0C*1lV`2Y`oh;+c4;TE{$Ve&!D;dZ$B5%OUX z=8uvOa2K2jH$F~2h(5el^x+oK-->(DhucLT9$Z3vp20m_0%yX5pT#{~1+Nu;4)<^? z+zOXGk9&ACJa{qjei8R@7n}|^zSLoO;dXcpJoshmBOC{BflJ^vxDoDzlV71eo`XNH zQy<~hKT#jyu0NBHaAq6%2(N`Vi8=f-+y=M9aqsY+vpKp29u2p_bKu5zdC%cycoiJ? z9`6@i1#f{{;P*xUecn%aEj*I*5L)3GaNJ)gPkDwL;p7jf4{$U5AlwGO2@n2|dJVV0 z!`STI{8#EVT=fz48Xmrb_X2K(uYw!@Mmpej_%*oX@3@Cs;9(s8zxHF?!^1zpJ)HR^ z?%|eB+{10~Mls(-dB7#`4tOoh&_i{>F1Ttp`2fdtkq>a=UfMh1uP6`U{j_&*3;aIZ zc7S|~F6rNCyeax{C!9H;(>T^ceBea5 z70!kS59~Cm;1YNZ+zfAk+u$wm@IjqMo0!9$Vh#^0!yFzD4?m>S$b?H^juli@G57hy`ZWi++@kh+z*Tfv&DdzCd3e1O*FK`K*3Ae#j!bf!)YsLKNPNM~GhFe7+ zZifdS(`gK@L?4cW+u(F~__5?GoO}ZL3b(+w%k%I~;~6*;-UgSz`{62hcope_C&S4j zI*lSY?nLqxZh^0b+u=>{;FHK#F^AjXDtKTu_TbU*W_S)fd?fh+SHY`AAKn0Go=o|| zE$}ut?i9-RJjxk%!ENvyIQdlE!)xKya4Wn49_+$BTm^4~H^U6*RO4y5hg;z}a2vb? z9(+3G0cXO^@aD;##%6eUGW8U0nbB!@e7r3<;_i*E4 z+{4XFa1Rgm;vO!6hu7kN1McCqKf*m6w+8oc*EP6@ORmK|+$fA_jROe z1McC?x8NRbgF|r1t<-OMhBv~4Z=*iIneYyHGd!@Ka)Mp(@Y{J$;1YNV+zdCuo8fEW zxI3tqa3lOCTyiJxE8GkZ^Air72zSBRaNJ$gOSrj(dI`7RO}&I$?jas<whI$D%!(Ms*E%g%af^UbD@1tJAjqo^Exa%Rx6W+Xq`T!4q zocaJaK0$pDeRvDp1-HR*Tggx1r^wGB{yj~8!kN#IpK#R+@;fNW_TT(xefR5 z=IywLtNx06xa%X_uf+Zi$^mYHy>QpxCRYukyxJbywtHj*CLCHxP{ z0bct#$9@CLZ+OWsR3xr1_q8(}6>R5Lsh-V7(hU2qB9xSMhieYjcl;mvSM z7v%uA!(DLPUdrJDct7spD!2r0fg6SYjeEEq-V7%j)Mt1tyb~_zzsneQA>qN};Z`^s zt{Sk*sDYc|wW1H-4kr)XWjrJ1@HV()&@MwR@F_WBm*Ik|j@f0*fj7fT;C8rC`1oB$ zGn_nPm$4acJaw1R2Diao@Nm~I@w2fs>EG}7v2o7mgkAPj16!XycLd{Og_Mk@P2uovdb8`nsCy088hIxj9o^F@Lcji z^fSo^xG{@-fLrF14{#UUDbLyD!zI{*6XCX;T}D2qhKF8?|CPIpICyQ3|)^j$cT z*_A%rj~qh$Fn=Saw|mLg8JI77_JA=u+C6G9E5R&;*{Kd@A

4aCa4E>-uoF5woi> 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 CzKrp4`uno^N-!V(`Ygtk^jX4s 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%0A1v3gUVuCG!sCmUQZ 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�y}3iW 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⩔*B}X;+L?9}!FsBh|UO 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

&Hn#n^(KEHXTy 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�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�sF#z|=YP65VnlMsVMzJk%N`oi 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 baJQTq=pK&*l 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 z�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

Pw)DWb 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

Q|?3J6kO{I5YivaR=kC4B^iYn`7+z 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

d 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 D%6bX@ literal 0 HcmV?d00001 diff --git a/crypto/external/bsd/openssh/dist/regress/dhgex.sh b/crypto/external/bsd/openssh/dist/regress/dhgex.sh new file mode 100644 index 000000000..57fca4a32 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/dhgex.sh @@ -0,0 +1,58 @@ +# $OpenBSD: dhgex.sh,v 1.2 2014/04/21 22:15:37 djm Exp $ +# Placed in the Public Domain. + +tid="dhgex" + +LOG=${TEST_SSH_LOGFILE} +rm -f ${LOG} +cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak + +kexs=`${SSH} -Q kex | grep diffie-hellman-group-exchange` + +ssh_test_dhgex() +{ + bits="$1"; shift + cipher="$1"; shift + kex="$1"; shift + + cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy + echo "KexAlgorithms=$kex" >> $OBJ/sshd_proxy + echo "Ciphers=$cipher" >> $OBJ/sshd_proxy + rm -f ${LOG} + opts="-oKexAlgorithms=$kex -oCiphers=$cipher" + groupsz="1024<$bits<8192" + verbose "$tid bits $bits $kex $cipher" + ${SSH} ${opts} $@ -vvv -F ${OBJ}/ssh_proxy somehost true + if [ $? -ne 0 ]; then + fail "ssh failed ($@)" + fi + # check what we request + grep "SSH2_MSG_KEX_DH_GEX_REQUEST($groupsz) sent" ${LOG} >/dev/null + if [ $? != 0 ]; then + got=`egrep "SSH2_MSG_KEX_DH_GEX_REQUEST(.*) sent" ${LOG}` + fail "$tid unexpected GEX sizes, expected $groupsz, got $got" + fi + # check what we got (depends on contents of system moduli file) + gotbits="`awk '/bits set:/{print $4}' ${LOG} | head -1 | cut -f2 -d/`" + if [ "$gotbits" -lt "$bits" ]; then + fatal "$tid expected $bits bit group, got $gotbits" + fi +} + +check() +{ + bits="$1"; shift + + for c in $@; do + for k in $kexs; do + ssh_test_dhgex $bits $c $k + done + done +} + +#check 2048 3des-cbc +check 3072 `${SSH} -Q cipher | grep 128` +check 3072 arcfour blowfish-cbc +check 7680 `${SSH} -Q cipher | grep 192` +check 8192 `${SSH} -Q cipher | grep 256` +check 8192 rijndael-cbc@lysator.liu.se chacha20-poly1305@openssh.com diff --git a/crypto/external/bsd/openssh/dist/regress/dsa_ssh2.prv b/crypto/external/bsd/openssh/dist/regress/dsa_ssh2.prv new file mode 100644 index 000000000..c93b40371 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/dsa_ssh2.prv @@ -0,0 +1,14 @@ +---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ---- +Subject: ssh-keygen test +Comment: "1024-bit dsa, Tue Jan 08 2002 22:00:23 +0100" +P2/56wAAAgIAAAAmZGwtbW9kcHtzaWdue2RzYS1uaXN0LXNoYTF9LGRoe3BsYWlufX0AAA +AEbm9uZQAAAcQAAAHAAAAAAAAABACwUfm3AxZTut3icBmwCcD48nY64HzuELlQ+vEqjIcR +Lo49es/DQTeLNQ+kdKRCfouosGNv0WqxRtF0tUsWdXxS37oHGa4QPugBdHRd7YlZGZv8kg +x7FsoepY7v7E683/97dv2zxL3AGagTEzWr7fl0yPexAaZoDvtQrrjX44BLmwAABACWQkvv +MxnD8eFkS1konFfMJ1CkuRfTN34CBZ6dY7VTSGemy4QwtFdMKmoufD0eKgy3p5WOeWCYKt +F4FhjHKZk/aaxFjjIbtkrnlvXg64QI11dSZyBN6/ViQkHPSkUDF+A6AAEhrNbQbAFSvao1 +kTvNtPCtL0AkUIduEMzGQfLCTAAAAKDeC043YVo9Zo0zAEeIA4uZh4LBCQAAA/9aj7Y5ik +ehygJ4qTDSlVypsPuV+n59tMS0e2pfrSG87yf5r94AKBmJeho5OO6wYaXCxsVB7AFbSUD6 +75AK8mHF4v1/+7SWKk5f8xlMCMSPZ9K0+j/W1d/q2qkhnnDZolOHDomLA+U00i5ya/jnTV +zyDPWLFpWK8u3xGBPAYX324gAAAKDHFvooRnaXdZbeWGTTqmgHB1GU9A== +---- END SSH2 ENCRYPTED PRIVATE KEY ---- diff --git a/crypto/external/bsd/openssh/dist/regress/dsa_ssh2.pub b/crypto/external/bsd/openssh/dist/regress/dsa_ssh2.pub new file mode 100644 index 000000000..215d73bae --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/dsa_ssh2.pub @@ -0,0 +1,13 @@ +---- BEGIN SSH2 PUBLIC KEY ---- +Subject: ssh-keygen test +Comment: "1024-bit dsa, Tue Jan 08 2002 22:00:23 +0100" +AAAAB3NzaC1kc3MAAACBALBR+bcDFlO63eJwGbAJwPjydjrgfO4QuVD68SqMhxEujj16z8 +NBN4s1D6R0pEJ+i6iwY2/RarFG0XS1SxZ1fFLfugcZrhA+6AF0dF3tiVkZm/ySDHsWyh6l +ju/sTrzf/3t2/bPEvcAZqBMTNavt+XTI97EBpmgO+1CuuNfjgEubAAAAFQDeC043YVo9Zo +0zAEeIA4uZh4LBCQAAAIEAlkJL7zMZw/HhZEtZKJxXzCdQpLkX0zd+AgWenWO1U0hnpsuE +MLRXTCpqLnw9HioMt6eVjnlgmCrReBYYxymZP2msRY4yG7ZK55b14OuECNdXUmcgTev1Yk +JBz0pFAxfgOgABIazW0GwBUr2qNZE7zbTwrS9AJFCHbhDMxkHywkwAAACAWo+2OYpHocoC +eKkw0pVcqbD7lfp+fbTEtHtqX60hvO8n+a/eACgZiXoaOTjusGGlwsbFQewBW0lA+u+QCv +JhxeL9f/u0lipOX/MZTAjEj2fStPo/1tXf6tqpIZ5w2aJThw6JiwPlNNIucmv4501c8gz1 +ixaVivLt8RgTwGF99uI= +---- END SSH2 PUBLIC KEY ---- diff --git a/crypto/external/bsd/openssh/dist/regress/dynamic-forward.sh b/crypto/external/bsd/openssh/dist/regress/dynamic-forward.sh new file mode 100644 index 000000000..dd67c9639 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/dynamic-forward.sh @@ -0,0 +1,59 @@ +# $OpenBSD: dynamic-forward.sh,v 1.11 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="dynamic forwarding" + +FWDPORT=`expr $PORT + 1` + +if have_prog nc && nc -h 2>&1 | grep "proxy address" >/dev/null; then + proxycmd="nc -x 127.0.0.1:$FWDPORT -X" +elif have_prog connect; then + proxycmd="connect -S 127.0.0.1:$FWDPORT -" +else + echo "skipped (no suitable ProxyCommand found)" + exit 0 +fi +trace "will use ProxyCommand $proxycmd" + +start_sshd + +for p in ${SSH_PROTOCOLS}; do + n=0 + error="1" + trace "start dynamic forwarding, fork to background" + while [ "$error" -ne 0 -a "$n" -lt 3 ]; do + n=`expr $n + 1` + ${SSH} -$p -F $OBJ/ssh_config -f -D $FWDPORT -q \ + -oExitOnForwardFailure=yes somehost exec sh -c \ + \'"echo \$\$ > $OBJ/remote_pid; exec sleep 444"\' + error=$? + if [ "$error" -ne 0 ]; then + trace "forward failed proto $p attempt $n err $error" + sleep $n + fi + done + if [ "$error" -ne 0 ]; then + fatal "failed to start dynamic forwarding proto $p" + fi + + for s in 4 5; do + for h in 127.0.0.1 localhost; do + trace "testing ssh protocol $p socks version $s host $h" + ${SSH} -F $OBJ/ssh_config \ + -o "ProxyCommand ${proxycmd}${s} $h $PORT" \ + somehost cat $DATA > $OBJ/ls.copy + test -f $OBJ/ls.copy || fail "failed copy $DATA" + cmp $DATA $OBJ/ls.copy || fail "corrupted copy of $DATA" + done + done + + if [ -f $OBJ/remote_pid ]; then + remote=`cat $OBJ/remote_pid` + trace "terminate remote shell, pid $remote" + if [ $remote -gt 1 ]; then + kill -HUP $remote + fi + else + fail "no pid file: $OBJ/remote_pid" + fi +done diff --git a/crypto/external/bsd/openssh/dist/regress/envpass.sh b/crypto/external/bsd/openssh/dist/regress/envpass.sh new file mode 100644 index 000000000..af7eafe3d --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/envpass.sh @@ -0,0 +1,60 @@ +# $OpenBSD: envpass.sh,v 1.4 2005/03/04 08:48:46 djm Exp $ +# Placed in the Public Domain. + +tid="environment passing" + +# NB accepted env vars are in test-exec.sh (_XXX_TEST_* and _XXX_TEST) + +# Prepare a custom config to test for a configuration parsing bug fixed in 4.0 +cat << EOF > $OBJ/ssh_proxy_envpass +Host test-sendenv-confparse-bug + SendEnv * +EOF +cat $OBJ/ssh_proxy >> $OBJ/ssh_proxy_envpass + +trace "pass env, don't accept" +verbose "test $tid: pass env, don't accept" +_TEST_ENV=blah ${SSH} -oSendEnv="*" -F $OBJ/ssh_proxy_envpass otherhost \ + sh << 'EOF' + test -z "$_TEST_ENV" +EOF +r=$? +if [ $r -ne 0 ]; then + fail "environment found" +fi + +trace "don't pass env, accept" +verbose "test $tid: don't pass env, accept" +_XXX_TEST_A=1 _XXX_TEST_B=2 ${SSH} -F $OBJ/ssh_proxy_envpass otherhost \ + sh << 'EOF' + test -z "$_XXX_TEST_A" && test -z "$_XXX_TEST_B" +EOF +r=$? +if [ $r -ne 0 ]; then + fail "environment found" +fi + +trace "pass single env, accept single env" +verbose "test $tid: pass single env, accept single env" +_XXX_TEST=blah ${SSH} -oSendEnv="_XXX_TEST" -F $OBJ/ssh_proxy_envpass \ + otherhost sh << 'EOF' + test X"$_XXX_TEST" = X"blah" +EOF +r=$? +if [ $r -ne 0 ]; then + fail "environment not found" +fi + +trace "pass multiple env, accept multiple env" +verbose "test $tid: pass multiple env, accept multiple env" +_XXX_TEST_A=1 _XXX_TEST_B=2 ${SSH} -oSendEnv="_XXX_TEST_*" \ + -F $OBJ/ssh_proxy_envpass otherhost \ + sh << 'EOF' + test X"$_XXX_TEST_A" = X"1" -a X"$_XXX_TEST_B" = X"2" +EOF +r=$? +if [ $r -ne 0 ]; then + fail "environment not found" +fi + +rm -f $OBJ/ssh_proxy_envpass diff --git a/crypto/external/bsd/openssh/dist/regress/exit-status.sh b/crypto/external/bsd/openssh/dist/regress/exit-status.sh new file mode 100644 index 000000000..397d8d732 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/exit-status.sh @@ -0,0 +1,24 @@ +# $OpenBSD: exit-status.sh,v 1.7 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="remote exit status" + +for p in ${SSH_PROTOCOLS}; do + for s in 0 1 4 5 44; do + trace "proto $p status $s" + verbose "test $tid: proto $p status $s" + ${SSH} -$p -F $OBJ/ssh_proxy otherhost exit $s + r=$? + if [ $r -ne $s ]; then + fail "exit code mismatch for protocol $p: $r != $s" + fi + + # same with early close of stdout/err + ${SSH} -$p -F $OBJ/ssh_proxy -n otherhost \ + exec sh -c \'"sleep 2; exec > /dev/null 2>&1; sleep 3; exit $s"\' + r=$? + if [ $r -ne $s ]; then + fail "exit code (with sleep) mismatch for protocol $p: $r != $s" + fi + done +done diff --git a/crypto/external/bsd/openssh/dist/regress/forcecommand.sh b/crypto/external/bsd/openssh/dist/regress/forcecommand.sh new file mode 100644 index 000000000..8a9b090ea --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/forcecommand.sh @@ -0,0 +1,44 @@ +# $OpenBSD: forcecommand.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="forced command" + +cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak + +cp /dev/null $OBJ/authorized_keys_$USER +for t in ${SSH_KEYTYPES}; do + printf 'command="true" ' >>$OBJ/authorized_keys_$USER + cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER +done + +for p in ${SSH_PROTOCOLS}; do + trace "forced command in key option proto $p" + ${SSH} -$p -F $OBJ/ssh_proxy somehost false \ || + fail "forced command in key proto $p" +done + +cp /dev/null $OBJ/authorized_keys_$USER +for t in ${SSH_KEYTYPES}; do + printf 'command="false" ' >> $OBJ/authorized_keys_$USER + cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER +done + +cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy +echo "ForceCommand true" >> $OBJ/sshd_proxy + +for p in ${SSH_PROTOCOLS}; do + trace "forced command in sshd_config overrides key option proto $p" + ${SSH} -$p -F $OBJ/ssh_proxy somehost false \ || + fail "forced command in key proto $p" +done + +cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy +echo "ForceCommand false" >> $OBJ/sshd_proxy +echo "Match User $USER" >> $OBJ/sshd_proxy +echo " ForceCommand true" >> $OBJ/sshd_proxy + +for p in ${SSH_PROTOCOLS}; do + trace "forced command with match proto $p" + ${SSH} -$p -F $OBJ/ssh_proxy somehost false \ || + fail "forced command in key proto $p" +done diff --git a/crypto/external/bsd/openssh/dist/regress/forward-control.sh b/crypto/external/bsd/openssh/dist/regress/forward-control.sh new file mode 100644 index 000000000..91957098f --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/forward-control.sh @@ -0,0 +1,168 @@ +# $OpenBSD: forward-control.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="sshd control of local and remote forwarding" + +LFWD_PORT=3320 +RFWD_PORT=3321 +CTL=$OBJ/ctl-sock +READY=$OBJ/ready + +wait_for_file_to_appear() { + _path=$1 + _n=0 + while test ! -f $_path ; do + test $_n -eq 1 && trace "waiting for $_path to appear" + _n=`expr $_n + 1` + test $_n -ge 20 && return 1 + sleep 1 + done + return 0 +} + +wait_for_process_to_exit() { + _pid=$1 + _n=0 + while kill -0 $_pid 2>/dev/null ; do + test $_n -eq 1 && trace "waiting for $_pid to exit" + _n=`expr $_n + 1` + test $_n -ge 20 && return 1 + sleep 1 + done + return 0 +} + +# usage: check_lfwd protocol Y|N message +check_lfwd() { + _proto=$1 + _expected=$2 + _message=$3 + rm -f $READY + ${SSH} -oProtocol=$_proto -F $OBJ/ssh_proxy \ + -L$LFWD_PORT:127.0.0.1:$PORT \ + -o ExitOnForwardFailure=yes \ + -n host exec sh -c \'"sleep 60 & echo \$! > $READY ; wait "\' \ + >/dev/null 2>&1 & + _sshpid=$! + wait_for_file_to_appear $READY || \ + fatal "check_lfwd ssh fail: $_message" + ${SSH} -F $OBJ/ssh_config -p $LFWD_PORT \ + -oConnectionAttempts=4 host true >/dev/null 2>&1 + _result=$? + kill $_sshpid `cat $READY` 2>/dev/null + wait_for_process_to_exit $_sshpid + if test "x$_expected" = "xY" -a $_result -ne 0 ; then + fail "check_lfwd failed (expecting success): $_message" + elif test "x$_expected" = "xN" -a $_result -eq 0 ; then + fail "check_lfwd succeeded (expecting failure): $_message" + elif test "x$_expected" != "xY" -a "x$_expected" != "xN" ; then + fatal "check_lfwd invalid argument \"$_expected\"" + else + verbose "check_lfwd done (expecting $_expected): $_message" + fi +} + +# usage: check_rfwd protocol Y|N message +check_rfwd() { + _proto=$1 + _expected=$2 + _message=$3 + rm -f $READY + ${SSH} -oProtocol=$_proto -F $OBJ/ssh_proxy \ + -R$RFWD_PORT:127.0.0.1:$PORT \ + -o ExitOnForwardFailure=yes \ + -n host exec sh -c \'"sleep 60 & echo \$! > $READY ; wait "\' \ + >/dev/null 2>&1 & + _sshpid=$! + wait_for_file_to_appear $READY + _result=$? + if test $_result -eq 0 ; then + ${SSH} -F $OBJ/ssh_config -p $RFWD_PORT \ + -oConnectionAttempts=4 host true >/dev/null 2>&1 + _result=$? + kill $_sshpid `cat $READY` 2>/dev/null + wait_for_process_to_exit $_sshpid + fi + if test "x$_expected" = "xY" -a $_result -ne 0 ; then + fail "check_rfwd failed (expecting success): $_message" + elif test "x$_expected" = "xN" -a $_result -eq 0 ; then + fail "check_rfwd succeeded (expecting failure): $_message" + elif test "x$_expected" != "xY" -a "x$_expected" != "xN" ; then + fatal "check_rfwd invalid argument \"$_expected\"" + else + verbose "check_rfwd done (expecting $_expected): $_message" + fi +} + +start_sshd +cp ${OBJ}/sshd_proxy ${OBJ}/sshd_proxy.bak +cp ${OBJ}/authorized_keys_${USER} ${OBJ}/authorized_keys_${USER}.bak + +# Sanity check: ensure the default config allows forwarding +for p in ${SSH_PROTOCOLS} ; do + check_lfwd $p Y "proto $p, default configuration" + check_rfwd $p Y "proto $p, default configuration" +done + +# Usage: all_tests yes|local|remote|no Y|N Y|N Y|N Y|N Y|N Y|N +all_tests() { + _tcpfwd=$1 + _plain_lfwd=$2 + _plain_rfwd=$3 + _nopermit_lfwd=$4 + _nopermit_rfwd=$5 + _permit_lfwd=$6 + _permit_rfwd=$7 + _badfwd=127.0.0.1:22 + _goodfwd=127.0.0.1:${PORT} + for _proto in ${SSH_PROTOCOLS} ; do + cp ${OBJ}/authorized_keys_${USER}.bak \ + ${OBJ}/authorized_keys_${USER} + _prefix="proto $_proto, AllowTcpForwarding=$_tcpfwd" + # No PermitOpen + ( cat ${OBJ}/sshd_proxy.bak ; + echo "AllowTcpForwarding $_tcpfwd" ) \ + > ${OBJ}/sshd_proxy + check_lfwd $_proto $_plain_lfwd "$_prefix" + check_rfwd $_proto $_plain_rfwd "$_prefix" + # PermitOpen via sshd_config that doesn't match + ( cat ${OBJ}/sshd_proxy.bak ; + echo "AllowTcpForwarding $_tcpfwd" ; + echo "PermitOpen $_badfwd" ) \ + > ${OBJ}/sshd_proxy + check_lfwd $_proto $_nopermit_lfwd "$_prefix, !PermitOpen" + check_rfwd $_proto $_nopermit_rfwd "$_prefix, !PermitOpen" + # PermitOpen via sshd_config that does match + ( cat ${OBJ}/sshd_proxy.bak ; + echo "AllowTcpForwarding $_tcpfwd" ; + echo "PermitOpen $_badfwd $_goodfwd" ) \ + > ${OBJ}/sshd_proxy + # NB. permitopen via authorized_keys should have same + # success/fail as via sshd_config + # permitopen via authorized_keys that doesn't match + sed "s/^/permitopen=\"$_badfwd\" /" \ + < ${OBJ}/authorized_keys_${USER}.bak \ + > ${OBJ}/authorized_keys_${USER} || fatal "sed 1 fail" + ( cat ${OBJ}/sshd_proxy.bak ; + echo "AllowTcpForwarding $_tcpfwd" ) \ + > ${OBJ}/sshd_proxy + check_lfwd $_proto $_nopermit_lfwd "$_prefix, !permitopen" + check_rfwd $_proto $_nopermit_rfwd "$_prefix, !permitopen" + # permitopen via authorized_keys that does match + sed "s/^/permitopen=\"$_badfwd\",permitopen=\"$_goodfwd\" /" \ + < ${OBJ}/authorized_keys_${USER}.bak \ + > ${OBJ}/authorized_keys_${USER} || fatal "sed 2 fail" + ( cat ${OBJ}/sshd_proxy.bak ; + echo "AllowTcpForwarding $_tcpfwd" ) \ + > ${OBJ}/sshd_proxy + check_lfwd $_proto $_permit_lfwd "$_prefix, permitopen" + check_rfwd $_proto $_permit_rfwd "$_prefix, permitopen" + done +} + +# no-permitopen mismatch-permitopen match-permitopen +# AllowTcpForwarding local remote local remote local remote +all_tests yes Y Y N Y Y Y +all_tests local Y N N N Y N +all_tests remote N Y N Y N Y +all_tests no N N N N N N diff --git a/crypto/external/bsd/openssh/dist/regress/forwarding.sh b/crypto/external/bsd/openssh/dist/regress/forwarding.sh new file mode 100644 index 000000000..fb4f35aff --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/forwarding.sh @@ -0,0 +1,143 @@ +# $OpenBSD: forwarding.sh,v 1.15 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="local and remote forwarding" + +DATA=/bin/ls${EXEEXT} + +start_sshd + +base=33 +last=$PORT +fwd="" +CTL=$OBJ/ctl-sock +rm -f $CTL + +for j in 0 1 2; do + for i in 0 1 2; do + a=$base$j$i + b=`expr $a + 50` + c=$last + # fwd chain: $a -> $b -> $c + fwd="$fwd -L$a:127.0.0.1:$b -R$b:127.0.0.1:$c" + last=$a + done +done +for p in ${SSH_PROTOCOLS}; do + q=`expr 3 - $p` + if ! ssh_version $q; then + q=$p + fi + trace "start forwarding, fork to background" + ${SSH} -$p -F $OBJ/ssh_config -f $fwd somehost sleep 10 + + trace "transfer over forwarded channels and check result" + ${SSH} -$q -F $OBJ/ssh_config -p$last -o 'ConnectionAttempts=4' \ + somehost cat ${DATA} > ${COPY} + test -s ${COPY} || fail "failed copy of ${DATA}" + cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}" + + sleep 10 +done + +for p in ${SSH_PROTOCOLS}; do +for d in L R; do + trace "exit on -$d forward failure, proto $p" + + # this one should succeed + ${SSH} -$p -F $OBJ/ssh_config \ + -$d ${base}01:127.0.0.1:$PORT \ + -$d ${base}02:127.0.0.1:$PORT \ + -$d ${base}03:127.0.0.1:$PORT \ + -$d ${base}04:127.0.0.1:$PORT \ + -oExitOnForwardFailure=yes somehost true + if [ $? != 0 ]; then + fail "connection failed, should not" + else + # this one should fail + ${SSH} -q -$p -F $OBJ/ssh_config \ + -$d ${base}01:127.0.0.1:$PORT \ + -$d ${base}02:127.0.0.1:$PORT \ + -$d ${base}03:127.0.0.1:$PORT \ + -$d ${base}01:127.0.0.1:$PORT \ + -$d ${base}04:127.0.0.1:$PORT \ + -oExitOnForwardFailure=yes somehost true + r=$? + if [ $r != 255 ]; then + fail "connection not termintated, but should ($r)" + fi + fi +done +done + +for p in ${SSH_PROTOCOLS}; do + trace "simple clear forwarding proto $p" + ${SSH} -$p -F $OBJ/ssh_config -oClearAllForwardings=yes somehost true + + trace "clear local forward proto $p" + ${SSH} -$p -f -F $OBJ/ssh_config -L ${base}01:127.0.0.1:$PORT \ + -oClearAllForwardings=yes somehost sleep 10 + if [ $? != 0 ]; then + fail "connection failed with cleared local forwarding" + else + # this one should fail + ${SSH} -$p -F $OBJ/ssh_config -p ${base}01 true \ + >>$TEST_REGRESS_LOGFILE 2>&1 && \ + fail "local forwarding not cleared" + fi + sleep 10 + + trace "clear remote forward proto $p" + ${SSH} -$p -f -F $OBJ/ssh_config -R ${base}01:127.0.0.1:$PORT \ + -oClearAllForwardings=yes somehost sleep 10 + if [ $? != 0 ]; then + fail "connection failed with cleared remote forwarding" + else + # this one should fail + ${SSH} -$p -F $OBJ/ssh_config -p ${base}01 true \ + >>$TEST_REGRESS_LOGFILE 2>&1 && \ + fail "remote forwarding not cleared" + fi + sleep 10 +done + +for p in 2; do + trace "stdio forwarding proto $p" + cmd="${SSH} -$p -F $OBJ/ssh_config" + $cmd -o "ProxyCommand $cmd -q -W localhost:$PORT somehost" \ + somehost true + if [ $? != 0 ]; then + fail "stdio forwarding proto $p" + fi +done + +echo "LocalForward ${base}01 127.0.0.1:$PORT" >> $OBJ/ssh_config +echo "RemoteForward ${base}02 127.0.0.1:${base}01" >> $OBJ/ssh_config +for p in ${SSH_PROTOCOLS}; do + trace "config file: start forwarding, fork to background" + ${SSH} -S $CTL -M -$p -F $OBJ/ssh_config -f somehost sleep 10 + + trace "config file: transfer over forwarded channels and check result" + ${SSH} -F $OBJ/ssh_config -p${base}02 -o 'ConnectionAttempts=4' \ + somehost cat ${DATA} > ${COPY} + test -s ${COPY} || fail "failed copy of ${DATA}" + cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}" + + ${SSH} -S $CTL -O exit somehost +done + +for p in 2; do + trace "transfer over chained unix domain socket forwards and check result" + rm -f $OBJ/unix-[123].fwd + ${SSH} -f -F $OBJ/ssh_config -R${base}01:[$OBJ/unix-1.fwd] somehost sleep 10 + ${SSH} -f -F $OBJ/ssh_config -L[$OBJ/unix-1.fwd]:[$OBJ/unix-2.fwd] somehost sleep 10 + ${SSH} -f -F $OBJ/ssh_config -R[$OBJ/unix-2.fwd]:[$OBJ/unix-3.fwd] somehost sleep 10 + ${SSH} -f -F $OBJ/ssh_config -L[$OBJ/unix-3.fwd]:127.0.0.1:$PORT somehost sleep 10 + ${SSH} -F $OBJ/ssh_config -p${base}01 -o 'ConnectionAttempts=4' \ + somehost cat ${DATA} > ${COPY} + test -s ${COPY} || fail "failed copy ${DATA}" + cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}" + + #wait + sleep 10 +done diff --git a/crypto/external/bsd/openssh/dist/regress/host-expand.sh b/crypto/external/bsd/openssh/dist/regress/host-expand.sh new file mode 100644 index 000000000..2a95bfe1b --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/host-expand.sh @@ -0,0 +1,19 @@ +# $OpenBSD: host-expand.sh,v 1.4 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="expand %h and %n" + +echo 'PermitLocalCommand yes' >> $OBJ/ssh_proxy +printf 'LocalCommand printf "%%%%s\\n" "%%n" "%%h"\n' >> $OBJ/ssh_proxy + +cat >$OBJ/expect <$OBJ/actual + diff $OBJ/expect $OBJ/actual || fail "$tid proto $p" +done + diff --git a/crypto/external/bsd/openssh/dist/regress/hostkey-agent.sh b/crypto/external/bsd/openssh/dist/regress/hostkey-agent.sh new file mode 100644 index 000000000..094700da6 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/hostkey-agent.sh @@ -0,0 +1,53 @@ +# $OpenBSD: hostkey-agent.sh,v 1.6 2015/07/10 06:23:25 markus Exp $ +# Placed in the Public Domain. + +tid="hostkey agent" + +rm -f $OBJ/agent-key.* $OBJ/ssh_proxy.orig $OBJ/known_hosts.orig + +trace "start agent" +eval `${SSHAGENT} -s` > /dev/null +r=$? +[ $r -ne 0 ] && fatal "could not start ssh-agent: exit code $r" + +grep -vi 'hostkey' $OBJ/sshd_proxy > $OBJ/sshd_proxy.orig +echo "HostKeyAgent $SSH_AUTH_SOCK" >> $OBJ/sshd_proxy.orig + +trace "load hostkeys" +for k in `${SSH} -Q key-plain` ; do + ${SSHKEYGEN} -qt $k -f $OBJ/agent-key.$k -N '' || fatal "ssh-keygen $k" + ( + printf 'localhost-with-alias,127.0.0.1,::1 ' + cat $OBJ/agent-key.$k.pub + ) >> $OBJ/known_hosts.orig + ${SSHADD} $OBJ/agent-key.$k >/dev/null 2>&1 || \ + fatal "couldn't load key $OBJ/agent-key.$k" + echo "Hostkey $OBJ/agent-key.${k}" >> $OBJ/sshd_proxy.orig + # Remove private key so the server can't use it. + rm $OBJ/agent-key.$k || fatal "couldn't rm $OBJ/agent-key.$k" +done +cp $OBJ/known_hosts.orig $OBJ/known_hosts + +unset SSH_AUTH_SOCK + +for ps in no yes; do + for k in `${SSH} -Q key-plain` ; do + verbose "key type $k privsep=$ps" + cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy + echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy + echo "HostKeyAlgorithms $k" >> $OBJ/sshd_proxy + opts="-oHostKeyAlgorithms=$k -F $OBJ/ssh_proxy" + cp $OBJ/known_hosts.orig $OBJ/known_hosts + SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'` + if [ $? -ne 0 ]; then + fail "protocol $p privsep=$ps failed" + fi + if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then + fail "bad SSH_CONNECTION key type $k privsep=$ps" + fi + done +done + +trace "kill agent" +${SSHAGENT} -k > /dev/null + diff --git a/crypto/external/bsd/openssh/dist/regress/hostkey-rotate.sh b/crypto/external/bsd/openssh/dist/regress/hostkey-rotate.sh new file mode 100644 index 000000000..3aa8c40c0 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/hostkey-rotate.sh @@ -0,0 +1,128 @@ +# $OpenBSD: hostkey-rotate.sh,v 1.4 2015/07/10 06:23:25 markus Exp $ +# Placed in the Public Domain. + +tid="hostkey rotate" + +# Need full names here since they are used in HostKeyAlgorithms +HOSTKEY_TYPES="ecdsa-sha2-nistp256 ssh-ed25519 ssh-rsa ssh-dss" + +rm -f $OBJ/hkr.* $OBJ/ssh_proxy.orig + +grep -vi 'hostkey' $OBJ/sshd_proxy > $OBJ/sshd_proxy.orig +echo "UpdateHostkeys=yes" >> $OBJ/ssh_proxy +rm $OBJ/known_hosts + +trace "prepare hostkeys" +nkeys=0 +all_algs="" +for k in `${SSH} -Q key-plain` ; do + ${SSHKEYGEN} -qt $k -f $OBJ/hkr.$k -N '' || fatal "ssh-keygen $k" + echo "Hostkey $OBJ/hkr.${k}" >> $OBJ/sshd_proxy.orig + nkeys=`expr $nkeys + 1` + test "x$all_algs" = "x" || all_algs="${all_algs}," + all_algs="${all_algs}$k" +done + +dossh() { + # All ssh should succeed in this test + ${SSH} -F $OBJ/ssh_proxy "$@" x true || fail "ssh $@ failed" +} + +expect_nkeys() { + _expected=$1 + _message=$2 + _n=`wc -l $OBJ/known_hosts | awk '{ print $1 }'` || fatal "wc failed" + [ "x$_n" = "x$_expected" ] || fail "$_message (got $_n wanted $_expected)" +} + +check_key_present() { + _type=$1 + _kfile=$2 + test "x$_kfile" = "x" && _kfile="$OBJ/hkr.${_type}.pub" + _kpub=`awk "/$_type /"' { print $2 }' < $_kfile` || \ + fatal "awk failed" + fgrep "$_kpub" $OBJ/known_hosts > /dev/null +} + +cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy + +# Connect to sshd with StrictHostkeyChecking=no +verbose "learn hostkey with StrictHostKeyChecking=no" +>$OBJ/known_hosts +dossh -oHostKeyAlgorithms=ssh-ed25519 -oStrictHostKeyChecking=no +# Verify no additional keys learned +expect_nkeys 1 "unstrict connect keys" +check_key_present ssh-ed25519 || fail "unstrict didn't learn key" + +# Connect to sshd as usual +verbose "learn additional hostkeys" +dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=$all_algs +# Check that other keys learned +expect_nkeys $nkeys "learn hostkeys" +check_key_present ssh-rsa || fail "didn't learn keys" + +# Check each key type +for k in `${SSH} -Q key-plain` ; do + verbose "learn additional hostkeys, type=$k" + dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=$k,$all_algs + expect_nkeys $nkeys "learn hostkeys $k" + check_key_present $k || fail "didn't learn $k" +done + +# Change one hostkey (non primary) and relearn +verbose "learn changed non-primary hostkey" +mv $OBJ/hkr.ssh-rsa.pub $OBJ/hkr.ssh-rsa.pub.old +rm -f $OBJ/hkr.ssh-rsa +${SSHKEYGEN} -qt ssh-rsa -f $OBJ/hkr.ssh-rsa -N '' || fatal "ssh-keygen $k" +dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=$all_algs +# Check that the key was replaced +expect_nkeys $nkeys "learn hostkeys" +check_key_present ssh-rsa $OBJ/hkr.ssh-rsa.pub.old && fail "old key present" +check_key_present ssh-rsa || fail "didn't learn changed key" + +# Add new hostkey (primary type) to sshd and connect +verbose "learn new primary hostkey" +${SSHKEYGEN} -qt ssh-rsa -f $OBJ/hkr.ssh-rsa-new -N '' || fatal "ssh-keygen $k" +( cat $OBJ/sshd_proxy.orig ; echo HostKey $OBJ/hkr.ssh-rsa-new ) \ + > $OBJ/sshd_proxy +# Check new hostkey added +dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=ssh-rsa,$all_algs +expect_nkeys `expr $nkeys + 1` "learn hostkeys" +check_key_present ssh-rsa || fail "current key missing" +check_key_present ssh-rsa $OBJ/hkr.ssh-rsa-new.pub || fail "new key missing" + +# Remove old hostkey (primary type) from sshd +verbose "rotate primary hostkey" +cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy +mv $OBJ/hkr.ssh-rsa.pub $OBJ/hkr.ssh-rsa.pub.old +mv $OBJ/hkr.ssh-rsa-new.pub $OBJ/hkr.ssh-rsa.pub +mv $OBJ/hkr.ssh-rsa-new $OBJ/hkr.ssh-rsa +# Check old hostkey removed +dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=ssh-rsa,$all_algs +expect_nkeys $nkeys "learn hostkeys" +check_key_present ssh-rsa $OBJ/hkr.ssh-rsa.pub.old && fail "old key present" +check_key_present ssh-rsa || fail "didn't learn changed key" + +# Connect again, forcing rotated key +verbose "check rotate primary hostkey" +dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=ssh-rsa +expect_nkeys 1 "learn hostkeys" +check_key_present ssh-rsa || fail "didn't learn changed key" + +# $OpenBSD: hostkey-rotate.sh,v 1.4 2015/07/10 06:23:25 markus Exp $ +# Placed in the Public Domain. + +tid="hostkey rotate" + +# Prepare hostkeys file with one key + +# Connect to sshd + +# Check that other keys learned + +# Change one hostkey (non primary) + +# Connect to sshd + +# Check that the key was replaced + diff --git a/crypto/external/bsd/openssh/dist/regress/integrity.sh b/crypto/external/bsd/openssh/dist/regress/integrity.sh new file mode 100644 index 000000000..1d4976771 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/integrity.sh @@ -0,0 +1,75 @@ +# $OpenBSD: integrity.sh,v 1.16 2015/03/24 20:22:17 markus Exp $ +# Placed in the Public Domain. + +tid="integrity" +cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak + +# start at byte 2900 (i.e. after kex) and corrupt at different offsets +# XXX the test hangs if we modify the low bytes of the packet length +# XXX and ssh tries to read... +tries=10 +startoffset=2900 +macs=`${SSH} -Q mac` +# The following are not MACs, but ciphers with integrated integrity. They are +# handled specially below. +macs="$macs `${SSH} -Q cipher-auth`" + +# avoid DH group exchange as the extra traffic makes it harder to get the +# offset into the stream right. +echo "KexAlgorithms diffie-hellman-group14-sha1,diffie-hellman-group1-sha1" \ + >> $OBJ/ssh_proxy + +# sshd-command for proxy (see test-exec.sh) +cmd="$SUDO sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy" + +for m in $macs; do + trace "test $tid: mac $m" + elen=0 + epad=0 + emac=0 + ecnt=0 + skip=0 + for off in `jot $tries $startoffset`; do + skip=`expr $skip - 1` + if [ $skip -gt 0 ]; then + # avoid modifying the high bytes of the length + continue + fi + cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy + # modify output from sshd at offset $off + pxy="proxycommand=$cmd | $OBJ/modpipe -wm xor:$off:1" + if ${SSH} -Q cipher-auth | grep "^${m}\$" >/dev/null 2>&1 ; then + echo "Ciphers=$m" >> $OBJ/sshd_proxy + macopt="-c $m" + else + echo "Ciphers=aes128-ctr" >> $OBJ/sshd_proxy + echo "MACs=$m" >> $OBJ/sshd_proxy + macopt="-m $m -c aes128-ctr" + fi + verbose "test $tid: $m @$off" + ${SSH} $macopt -2F $OBJ/ssh_proxy -o "$pxy" \ + -oServerAliveInterval=1 -oServerAliveCountMax=30 \ + 999.999.999.999 'printf "%4096s" " "' >/dev/null + if [ $? -eq 0 ]; then + fail "ssh -m $m succeeds with bit-flip at $off" + fi + ecnt=`expr $ecnt + 1` + out=$(tail -2 $TEST_SSH_LOGFILE | egrep -v "^debug" | \ + tr -s '\r\n' '.') + case "$out" in + Bad?packet*) elen=`expr $elen + 1`; skip=3;; + Corrupted?MAC* | *message?authentication?code?incorrect*) + emac=`expr $emac + 1`; skip=0;; + padding*) epad=`expr $epad + 1`; skip=0;; + *) fail "unexpected error mac $m at $off: $out";; + esac + done + verbose "test $tid: $ecnt errors: mac $emac padding $epad length $elen" + if [ $emac -eq 0 ]; then + fail "$m: no mac errors" + fi + expect=`expr $ecnt - $epad - $elen` + if [ $emac -ne $expect ]; then + fail "$m: expected $expect mac errors, got $emac" + fi +done diff --git a/crypto/external/bsd/openssh/dist/regress/kextype.sh b/crypto/external/bsd/openssh/dist/regress/kextype.sh new file mode 100644 index 000000000..e27189904 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/kextype.sh @@ -0,0 +1,25 @@ +# $OpenBSD: kextype.sh,v 1.6 2015/03/24 20:19:15 markus Exp $ +# Placed in the Public Domain. + +tid="login with different key exchange algorithms" + +TIME=/usr/bin/time +cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak +cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak + +# Make server accept all key exchanges. +ALLKEX=`${SSH} -Q kex` +KEXOPT=`echo $ALLKEX | tr ' ' ,` +echo "KexAlgorithms=$KEXOPT" >> $OBJ/sshd_proxy + +tries="1 2 3 4" +for k in `${SSH} -Q kex`; do + verbose "kex $k" + for i in $tries; do + ${SSH} -F $OBJ/ssh_proxy -o KexAlgorithms=$k x true + if [ $? -ne 0 ]; then + fail "ssh kex $k" + fi + done +done + diff --git a/crypto/external/bsd/openssh/dist/regress/key-options.sh b/crypto/external/bsd/openssh/dist/regress/key-options.sh new file mode 100644 index 000000000..7a68ad358 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/key-options.sh @@ -0,0 +1,71 @@ +# $OpenBSD: key-options.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="key options" + +origkeys="$OBJ/authkeys_orig" +authkeys="$OBJ/authorized_keys_${USER}" +cp $authkeys $origkeys + +# Test command= forced command +for p in ${SSH_PROTOCOLS}; do + for c in 'command="echo bar"' 'no-pty,command="echo bar"'; do + sed "s/.*/$c &/" $origkeys >$authkeys + verbose "key option proto $p $c" + r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost echo foo` + if [ "$r" = "foo" ]; then + fail "key option forced command not restricted" + fi + if [ "$r" != "bar" ]; then + fail "key option forced command not executed" + fi + done +done + +# Test no-pty +sed 's/.*/no-pty &/' $origkeys >$authkeys +for p in ${SSH_PROTOCOLS}; do + verbose "key option proto $p no-pty" + r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost tty` + if [ -f "$r" ]; then + fail "key option failed proto $p no-pty (pty $r)" + fi +done + +# Test environment= +echo 'PermitUserEnvironment yes' >> $OBJ/sshd_proxy +sed 's/.*/environment="FOO=bar" &/' $origkeys >$authkeys +for p in ${SSH_PROTOCOLS}; do + verbose "key option proto $p environment" + r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost 'echo $FOO'` + if [ "$r" != "bar" ]; then + fail "key option environment not set" + fi +done + +# Test from= restriction +start_sshd +for p in ${SSH_PROTOCOLS}; do + for f in 127.0.0.1 '127.0.0.0\/8'; do + cat $origkeys >$authkeys + ${SSH} -$p -q -F $OBJ/ssh_proxy somehost true + if [ $? -ne 0 ]; then + fail "key option proto $p failed without restriction" + fi + + sed 's/.*/from="'"$f"'" &/' $origkeys >$authkeys + from=`head -1 $authkeys | cut -f1 -d ' '` + verbose "key option proto $p $from" + r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost 'echo true'` + if [ "$r" = "true" ]; then + fail "key option proto $p $from not restricted" + fi + + r=`${SSH} -$p -q -F $OBJ/ssh_config somehost 'echo true'` + if [ "$r" != "true" ]; then + fail "key option proto $p $from not allowed but should be" + fi + done +done + +rm -f "$origkeys" diff --git a/crypto/external/bsd/openssh/dist/regress/keygen-change.sh b/crypto/external/bsd/openssh/dist/regress/keygen-change.sh new file mode 100644 index 000000000..e56185050 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/keygen-change.sh @@ -0,0 +1,28 @@ +# $OpenBSD: keygen-change.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="change passphrase for key" + +S1="secret1" +S2="2secret" + +KEYTYPES=`${SSH} -Q key-plain` +if ssh_version 1; then + KEYTYPES="${KEYTYPES} rsa1" +fi + +for t in $KEYTYPES; 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/crypto/external/bsd/openssh/dist/regress/keygen-convert.sh b/crypto/external/bsd/openssh/dist/regress/keygen-convert.sh new file mode 100644 index 000000000..ad0e9c637 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/keygen-convert.sh @@ -0,0 +1,33 @@ +# $OpenBSD: keygen-convert.sh,v 1.1 2009/11/09 04:20:04 dtucker Exp $ +# Placed in the Public Domain. + +tid="convert keys" + +for t in rsa dsa; do + # generate user key for agent + trace "generating $t key" + rm -f $OBJ/$t-key + ${SSHKEYGEN} -q -N "" -t $t -f $OBJ/$t-key + + trace "export $t private to rfc4716 public" + ${SSHKEYGEN} -q -e -f $OBJ/$t-key >$OBJ/$t-key-rfc || \ + fail "export $t private to rfc4716 public" + + trace "export $t public to rfc4716 public" + ${SSHKEYGEN} -q -e -f $OBJ/$t-key.pub >$OBJ/$t-key-rfc.pub || \ + fail "$t public to rfc4716 public" + + cmp $OBJ/$t-key-rfc $OBJ/$t-key-rfc.pub || \ + fail "$t rfc4716 exports differ between public and private" + + trace "import $t rfc4716 public" + ${SSHKEYGEN} -q -i -f $OBJ/$t-key-rfc >$OBJ/$t-rfc-imported || \ + fail "$t import rfc4716 public" + + cut -f1,2 -d " " $OBJ/$t-key.pub >$OBJ/$t-key-nocomment.pub + cmp $OBJ/$t-key-nocomment.pub $OBJ/$t-rfc-imported || \ + fail "$t imported differs from original" + + rm -f $OBJ/$t-key $OBJ/$t-key.pub $OBJ/$t-key-rfc $OBJ/$t-key-rfc.pub \ + $OBJ/$t-rfc-imported $OBJ/$t-key-nocomment.pub +done diff --git a/crypto/external/bsd/openssh/dist/regress/keygen-knownhosts.sh b/crypto/external/bsd/openssh/dist/regress/keygen-knownhosts.sh new file mode 100644 index 000000000..693cd0e75 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/keygen-knownhosts.sh @@ -0,0 +1,197 @@ +# $OpenBSD: keygen-knownhosts.sh,v 1.3 2015/07/17 03:34:27 djm Exp $ +# Placed in the Public Domain. + +tid="ssh-keygen known_hosts" + +rm -f $OBJ/kh.* + +# Generate some keys for testing (just ed25519 for speed) and make a hosts file. +for x in host-a host-b host-c host-d host-e host-f host-a2 host-b2; do + ${SSHKEYGEN} -qt ed25519 -f $OBJ/kh.$x -C "$x" -N "" || \ + fatal "ssh-keygen failed" + # Add a comment that we expect should be preserved. + echo "# $x" >> $OBJ/kh.hosts + ( + case "$x" in + host-a|host-b) printf "$x " ;; + host-c) printf "@cert-authority $x " ;; + host-d) printf "@revoked $x " ;; + host-e) printf "host-e* " ;; + host-f) printf "host-f,host-g,host-h " ;; + host-a2) printf "host-a " ;; + host-b2) printf "host-b " ;; + esac + cat $OBJ/kh.${x}.pub + # Blank line should be preserved. + echo "" >> $OBJ/kh.hosts + ) >> $OBJ/kh.hosts +done + +# Generate a variant with an invalid line. We'll use this for most tests, +# because keygen should be able to cope and it should be preserved in any +# output file. +cat $OBJ/kh.hosts >> $OBJ/kh.invalid +echo "host-i " >> $OBJ/kh.invalid + +cp $OBJ/kh.invalid $OBJ/kh.invalid.orig +cp $OBJ/kh.hosts $OBJ/kh.hosts.orig + +expect_key() { + _host=$1 + _hosts=$2 + _key=$3 + _line=$4 + _mark=$5 + _marker="" + test "x$_mark" = "xCA" && _marker="@cert-authority " + test "x$_mark" = "xREVOKED" && _marker="@revoked " + test "x$_line" != "x" && + echo "# Host $_host found: line $_line $_mark" >> $OBJ/kh.expect + printf "${_marker}$_hosts " >> $OBJ/kh.expect + cat $OBJ/kh.${_key}.pub >> $OBJ/kh.expect || + fatal "${_key}.pub missing" +} + +check_find() { + _host=$1 + _name=$2 + _keygenopt=$3 + ${SSHKEYGEN} $_keygenopt -f $OBJ/kh.invalid -F $_host > $OBJ/kh.result + if ! diff -w $OBJ/kh.expect $OBJ/kh.result ; then + fail "didn't find $_name" + fi +} + +# Find key +rm -f $OBJ/kh.expect +expect_key host-a host-a host-a 2 +expect_key host-a host-a host-a2 20 +check_find host-a "simple find" + +# find CA key +rm -f $OBJ/kh.expect +expect_key host-c host-c host-c 8 CA +check_find host-c "find CA key" + +# find revoked key +rm -f $OBJ/kh.expect +expect_key host-d host-d host-d 11 REVOKED +check_find host-d "find revoked key" + +# find key with wildcard +rm -f $OBJ/kh.expect +expect_key host-e.somedomain "host-e*" host-e 14 +check_find host-e.somedomain "find wildcard key" + +# find key among multiple hosts +rm -f $OBJ/kh.expect +expect_key host-h "host-f,host-g,host-h " host-f 17 +check_find host-h "find multiple hosts" + +check_hashed_find() { + _host=$1 + _name=$2 + _file=$3 + test "x$_file" = "x" && _file=$OBJ/kh.invalid + ${SSHKEYGEN} -f $_file -HF $_host | grep '|1|' | \ + sed "s/^[^ ]*/$_host/" > $OBJ/kh.result + if ! diff -w $OBJ/kh.expect $OBJ/kh.result ; then + fail "didn't find $_name" + fi +} + +# Find key and hash +rm -f $OBJ/kh.expect +expect_key host-a host-a host-a +expect_key host-a host-a host-a2 +check_hashed_find host-a "find simple and hash" + +# Find CA key and hash +rm -f $OBJ/kh.expect +expect_key host-c host-c host-c "" CA +# CA key output is not hashed. +check_find host-c "find simple and hash" -H + +# Find revoked key and hash +rm -f $OBJ/kh.expect +expect_key host-d host-d host-d "" REVOKED +# Revoked key output is not hashed. +check_find host-d "find simple and hash" -H + +# find key with wildcard and hash +rm -f $OBJ/kh.expect +expect_key host-e "host-e*" host-e "" +# Key with wildcard hostname should not be hashed. +check_find host-e "find wildcard key" -H + +# find key among multiple hosts +rm -f $OBJ/kh.expect +# Comma-separated hostnames should be expanded and hashed. +expect_key host-f "host-h " host-f +expect_key host-g "host-h " host-f +expect_key host-h "host-h " host-f +check_hashed_find host-h "find multiple hosts" + +# Attempt remove key on invalid file. +cp $OBJ/kh.invalid.orig $OBJ/kh.invalid +${SSHKEYGEN} -qf $OBJ/kh.invalid -R host-a 2>/dev/null +diff $OBJ/kh.invalid $OBJ/kh.invalid.orig || fail "remove on invalid succeeded" + +# Remove key +cp $OBJ/kh.hosts.orig $OBJ/kh.hosts +${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-a 2>/dev/null +grep -v "^host-a " $OBJ/kh.hosts.orig > $OBJ/kh.expect +diff $OBJ/kh.hosts $OBJ/kh.expect || fail "remove simple" + +# Remove CA key +cp $OBJ/kh.hosts.orig $OBJ/kh.hosts +${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-c 2>/dev/null +# CA key should not be removed. +diff $OBJ/kh.hosts $OBJ/kh.hosts.orig || fail "remove CA" + +# Remove revoked key +cp $OBJ/kh.hosts.orig $OBJ/kh.hosts +${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-d 2>/dev/null +# revoked key should not be removed. +diff $OBJ/kh.hosts $OBJ/kh.hosts.orig || fail "remove revoked" + +# Remove wildcard +cp $OBJ/kh.hosts.orig $OBJ/kh.hosts +${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-e.blahblah 2>/dev/null +grep -v "^host-e[*] " $OBJ/kh.hosts.orig > $OBJ/kh.expect +diff $OBJ/kh.hosts $OBJ/kh.expect || fail "remove wildcard" + +# Remove multiple +cp $OBJ/kh.hosts.orig $OBJ/kh.hosts +${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-h 2>/dev/null +grep -v "^host-f," $OBJ/kh.hosts.orig > $OBJ/kh.expect +diff $OBJ/kh.hosts $OBJ/kh.expect || fail "remove wildcard" + +# Attempt hash on invalid file +cp $OBJ/kh.invalid.orig $OBJ/kh.invalid +${SSHKEYGEN} -qf $OBJ/kh.invalid -H 2>/dev/null && fail "hash invalid succeeded" +diff $OBJ/kh.invalid $OBJ/kh.invalid.orig || fail "invalid file modified" + +# Hash valid file +cp $OBJ/kh.hosts.orig $OBJ/kh.hosts +${SSHKEYGEN} -qf $OBJ/kh.hosts -H 2>/dev/null || fail "hash failed" +diff $OBJ/kh.hosts.old $OBJ/kh.hosts.orig || fail "backup differs" +grep "^host-[abfgh]" $OBJ/kh.hosts && fail "original hostnames persist" + +cp $OBJ/kh.hosts $OBJ/kh.hashed.orig + +# Test lookup +rm -f $OBJ/kh.expect +expect_key host-a host-a host-a +expect_key host-a host-a host-a2 +check_hashed_find host-a "find simple in hashed" $OBJ/kh.hosts + +# Test multiple expanded +rm -f $OBJ/kh.expect +expect_key host-h host-h host-f +check_hashed_find host-h "find simple in hashed" $OBJ/kh.hosts + +# Test remove +cp $OBJ/kh.hashed.orig $OBJ/kh.hashed +${SSHKEYGEN} -qf $OBJ/kh.hashed -R host-a 2>/dev/null +${SSHKEYGEN} -qf $OBJ/kh.hashed -F host-a && fail "found key after hashed remove" diff --git a/crypto/external/bsd/openssh/dist/regress/keys-command.sh b/crypto/external/bsd/openssh/dist/regress/keys-command.sh new file mode 100644 index 000000000..700273b66 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/keys-command.sh @@ -0,0 +1,76 @@ +# $OpenBSD: keys-command.sh,v 1.3 2015/05/21 06:40:02 djm Exp $ +# Placed in the Public Domain. + +tid="authorized keys from command" + +if test -z "$SUDO" ; then + echo "skipped (SUDO not set)" + echo "need SUDO to create file in /var/run, test won't work without" + exit 0 +fi + +rm -f $OBJ/keys-command-args + +touch $OBJ/keys-command-args +chmod a+rw $OBJ/keys-command-args + +expected_key_text=`awk '{ print $2 }' < $OBJ/rsa.pub` +expected_key_fp=`$SSHKEYGEN -lf $OBJ/rsa.pub | awk '{ print $2 }'` + +# Establish a AuthorizedKeysCommand in /var/run where it will have +# acceptable directory permissions. +KEY_COMMAND="/var/run/keycommand_${LOGNAME}" +cat << _EOF | $SUDO sh -c "rm -f '$KEY_COMMAND' ; cat > '$KEY_COMMAND'" +#!/bin/sh +echo args: "\$@" >> $OBJ/keys-command-args +echo "$PATH" | grep -q mekmitasdigoat && exit 7 +test "x\$1" != "x${LOGNAME}" && exit 1 +if test $# -eq 6 ; then + test "x\$2" != "xblah" && exit 2 + test "x\$3" != "x${expected_key_text}" && exit 3 + test "x\$4" != "xssh-rsa" && exit 4 + test "x\$5" != "x${expected_key_fp}" && exit 5 + test "x\$6" != "xblah" && exit 6 +fi +exec cat "$OBJ/authorized_keys_${LOGNAME}" +_EOF +$SUDO chmod 0755 "$KEY_COMMAND" + +if [ -x $KEY_COMMAND ]; then + cp $OBJ/sshd_proxy $OBJ/sshd_proxy.bak + + verbose "AuthorizedKeysCommand with arguments" + ( + grep -vi AuthorizedKeysFile $OBJ/sshd_proxy.bak + echo AuthorizedKeysFile none + echo AuthorizedKeysCommand $KEY_COMMAND %u blah %k %t %f blah + echo AuthorizedKeysCommandUser ${LOGNAME} + ) > $OBJ/sshd_proxy + + # Ensure that $PATH is sanitised in sshd + env PATH=$PATH:/sbin/mekmitasdigoat \ + ${SSH} -F $OBJ/ssh_proxy somehost true + if [ $? -ne 0 ]; then + fail "connect failed" + fi + + verbose "AuthorizedKeysCommand without arguments" + # Check legacy behavior of no-args resulting in username being passed. + ( + grep -vi AuthorizedKeysFile $OBJ/sshd_proxy.bak + echo AuthorizedKeysFile none + echo AuthorizedKeysCommand $KEY_COMMAND + echo AuthorizedKeysCommandUser ${LOGNAME} + ) > $OBJ/sshd_proxy + + # Ensure that $PATH is sanitised in sshd + env PATH=$PATH:/sbin/mekmitasdigoat \ + ${SSH} -F $OBJ/ssh_proxy somehost true + if [ $? -ne 0 ]; then + fail "connect failed" + fi +else + echo "SKIPPED: $KEY_COMMAND not executable (/var/run mounted noexec?)" +fi + +$SUDO rm -f $KEY_COMMAND diff --git a/crypto/external/bsd/openssh/dist/regress/keyscan.sh b/crypto/external/bsd/openssh/dist/regress/keyscan.sh new file mode 100644 index 000000000..886f3295a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/keyscan.sh @@ -0,0 +1,24 @@ +# $OpenBSD: keyscan.sh,v 1.4 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="keyscan" + +# remove DSA hostkey +rm -f ${OBJ}/host.dsa + +start_sshd + +KEYTYPES="rsa dsa" +if ssh_version 1; then + KEYTYPES="${KEYTYPES} rsa1" +fi + +for t in $KEYTYPES; do + trace "keyscan type $t" + ${SSHKEYSCAN} -t $t -p $PORT 127.0.0.1 127.0.0.1 127.0.0.1 \ + > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then + fail "ssh-keyscan -t $t failed with: $r" + fi +done diff --git a/crypto/external/bsd/openssh/dist/regress/keytype.sh b/crypto/external/bsd/openssh/dist/regress/keytype.sh new file mode 100644 index 000000000..8f697788f --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/keytype.sh @@ -0,0 +1,73 @@ +# $OpenBSD: keytype.sh,v 1.4 2015/07/10 06:23:25 markus Exp $ +# Placed in the Public Domain. + +tid="login with different key types" + +TIME=`which time 2>/dev/null` +if test ! -x "$TIME"; then + TIME="" +fi + +cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak +cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak + +# Traditional and builtin key types. +ktypes="dsa-1024 rsa-2048 rsa-3072 ed25519-512" +# Types not present in all OpenSSL versions. +for i in `$SSH -Q key`; do + case "$i" in + ecdsa-sha2-nistp256) ktypes="$ktypes ecdsa-256" ;; + ecdsa-sha2-nistp384) ktypes="$ktypes ecdsa-384" ;; + ecdsa-sha2-nistp521) ktypes="$ktypes ecdsa-521" ;; + esac +done + +for kt in $ktypes; do + rm -f $OBJ/key.$kt + bits=`echo ${kt} | awk -F- '{print $2}'` + type=`echo ${kt} | awk -F- '{print $1}'` + printf "keygen $type, $bits bits:\t" + ${TIME} ${SSHKEYGEN} -b $bits -q -N '' -t $type -f $OBJ/key.$kt ||\ + fail "ssh-keygen for type $type, $bits bits failed" +done + +tries="1 2 3" +for ut in $ktypes; do + htypes=$ut + #htypes=$ktypes + for ht in $htypes; do + case $ht in + dsa-1024) t=ssh-dss;; + ecdsa-256) t=ecdsa-sha2-nistp256;; + ecdsa-384) t=ecdsa-sha2-nistp384;; + ecdsa-521) t=ecdsa-sha2-nistp521;; + ed25519-512) t=ssh-ed25519;; + rsa-*) t=ssh-rsa;; + esac + trace "ssh connect, userkey $ut, hostkey $ht" + ( + grep -v HostKey $OBJ/sshd_proxy_bak + echo HostKey $OBJ/key.$ht + echo PubkeyAcceptedKeyTypes $t + echo HostKeyAlgorithms $t + ) > $OBJ/sshd_proxy + ( + grep -v IdentityFile $OBJ/ssh_proxy_bak + echo IdentityFile $OBJ/key.$ut + echo PubkeyAcceptedKeyTypes $t + echo HostKeyAlgorithms $t + ) > $OBJ/ssh_proxy + ( + printf 'localhost-with-alias,127.0.0.1,::1 ' + cat $OBJ/key.$ht.pub + ) > $OBJ/known_hosts + cat $OBJ/key.$ut.pub > $OBJ/authorized_keys_$USER + for i in $tries; do + printf "userkey $ut, hostkey ${ht}:\t" + ${TIME} ${SSH} -F $OBJ/ssh_proxy 999.999.999.999 true + if [ $? -ne 0 ]; then + fail "ssh userkey $ut, hostkey $ht failed" + fi + done + done +done diff --git a/crypto/external/bsd/openssh/dist/regress/krl.sh b/crypto/external/bsd/openssh/dist/regress/krl.sh new file mode 100644 index 000000000..1077358ff --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/krl.sh @@ -0,0 +1,185 @@ +# $OpenBSD: krl.sh,v 1.6 2015/01/30 01:11:39 djm Exp $ +# Placed in the Public Domain. + +tid="key revocation lists" + +# If we don't support ecdsa keys then this tell will be much slower. +ECDSA=ecdsa +if test "x$TEST_SSH_ECC" != "xyes"; then + ECDSA=rsa +fi + +# Do most testing with ssh-keygen; it uses the same verification code as sshd. + +# Old keys will interfere with ssh-keygen. +rm -f $OBJ/revoked-* $OBJ/krl-* + +# Generate a CA key +$SSHKEYGEN -t $ECDSA -f $OBJ/revoked-ca -C "" -N "" > /dev/null || + fatal "$SSHKEYGEN CA failed" +$SSHKEYGEN -t ed25519 -f $OBJ/revoked-ca2 -C "" -N "" > /dev/null || + fatal "$SSHKEYGEN CA2 failed" + +# A specification that revokes some certificates by serial numbers +# The serial pattern is chosen to ensure the KRL includes list, range and +# bitmap sections. +cat << EOF >> $OBJ/revoked-serials +serial: 1-4 +serial: 10 +serial: 15 +serial: 30 +serial: 50 +serial: 999 +# The following sum to 500-799 +serial: 500 +serial: 501 +serial: 502 +serial: 503-600 +serial: 700-797 +serial: 798 +serial: 799 +serial: 599-701 +# Some multiple consecutive serial number ranges +serial: 10000-20000 +serial: 30000-40000 +EOF + +# A specification that revokes some certificated by key ID. +touch $OBJ/revoked-keyid +for n in 1 2 3 4 10 15 30 50 `jot 500 300` 999 1000 1001 1002; do + test "x$n" = "x499" && continue + # Fill in by-ID revocation spec. + echo "id: revoked $n" >> $OBJ/revoked-keyid +done + +keygen() { + N=$1 + f=$OBJ/revoked-`printf "%04d" $N` + # Vary the keytype. We use mostly ECDSA since this is fastest by far. + keytype=$ECDSA + case $N in + 2 | 10 | 510 | 1001) keytype=rsa;; + 4 | 30 | 520 | 1002) keytype=ed25519;; + esac + $SSHKEYGEN -t $keytype -f $f -C "" -N "" > /dev/null \ + || fatal "$SSHKEYGEN failed" + # Sign cert + $SSHKEYGEN -s $OBJ/revoked-ca -z $n -I "revoked $N" $f >/dev/null 2>&1 \ + || fatal "$SSHKEYGEN sign failed" + echo $f +} + +# Generate some keys. +verbose "$tid: generating test keys" +REVOKED_SERIALS="1 4 10 50 500 510 520 799 999" +for n in $REVOKED_SERIALS ; do + f=`keygen $n` + RKEYS="$RKEYS ${f}.pub" + RCERTS="$RCERTS ${f}-cert.pub" +done +UNREVOKED_SERIALS="5 9 14 16 29 49 51 499 800 1010 1011" +UNREVOKED="" +for n in $UNREVOKED_SERIALS ; do + f=`keygen $n` + UKEYS="$UKEYS ${f}.pub" + UCERTS="$UCERTS ${f}-cert.pub" +done + +genkrls() { + OPTS=$1 +$SSHKEYGEN $OPTS -kf $OBJ/krl-empty - /dev/null || fatal "$SSHKEYGEN KRL failed" +$SSHKEYGEN $OPTS -kf $OBJ/krl-keys $RKEYS \ + >/dev/null || fatal "$SSHKEYGEN KRL failed" +$SSHKEYGEN $OPTS -kf $OBJ/krl-cert $RCERTS \ + >/dev/null || fatal "$SSHKEYGEN KRL failed" +$SSHKEYGEN $OPTS -kf $OBJ/krl-all $RKEYS $RCERTS \ + >/dev/null || fatal "$SSHKEYGEN KRL failed" +$SSHKEYGEN $OPTS -kf $OBJ/krl-ca $OBJ/revoked-ca.pub \ + >/dev/null || fatal "$SSHKEYGEN KRL failed" +# This should fail as KRLs from serial/key-id spec need the CA specified. +$SSHKEYGEN $OPTS -kf $OBJ/krl-serial $OBJ/revoked-serials \ + >/dev/null 2>&1 && fatal "$SSHKEYGEN KRL succeeded unexpectedly" +$SSHKEYGEN $OPTS -kf $OBJ/krl-keyid $OBJ/revoked-keyid \ + >/dev/null 2>&1 && fatal "$SSHKEYGEN KRL succeeded unexpectedly" +# These should succeed; they specify an explicit CA key. +$SSHKEYGEN $OPTS -kf $OBJ/krl-serial -s $OBJ/revoked-ca \ + $OBJ/revoked-serials >/dev/null || fatal "$SSHKEYGEN KRL failed" +$SSHKEYGEN $OPTS -kf $OBJ/krl-keyid -s $OBJ/revoked-ca.pub \ + $OBJ/revoked-keyid >/dev/null || fatal "$SSHKEYGEN KRL failed" +# These should succeed; they specify an wildcard CA key. +$SSHKEYGEN $OPTS -kf $OBJ/krl-serial-wild -s NONE $OBJ/revoked-serials \ + >/dev/null || fatal "$SSHKEYGEN KRL failed" +$SSHKEYGEN $OPTS -kf $OBJ/krl-keyid-wild -s NONE $OBJ/revoked-keyid \ + >/dev/null || fatal "$SSHKEYGEN KRL failed" +# Revoke the same serials with the second CA key to ensure a multi-CA +# KRL is generated. +$SSHKEYGEN $OPTS -kf $OBJ/krl-serial -u -s $OBJ/revoked-ca2 \ + $OBJ/revoked-serials >/dev/null || fatal "$SSHKEYGEN KRL failed" +} + +## XXX dump with trace and grep for set cert serials +## XXX test ranges near (u64)-1, etc. + +verbose "$tid: generating KRLs" +genkrls + +check_krl() { + KEY=$1 + KRL=$2 + EXPECT_REVOKED=$3 + TAG=$4 + $SSHKEYGEN -Qf $KRL $KEY >/dev/null + result=$? + if test "x$EXPECT_REVOKED" = "xyes" -a $result -eq 0 ; then + fatal "key $KEY not revoked by KRL $KRL: $TAG" + elif test "x$EXPECT_REVOKED" = "xno" -a $result -ne 0 ; then + fatal "key $KEY unexpectedly revoked by KRL $KRL: $TAG" + fi +} +test_rev() { + FILES=$1 + TAG=$2 + KEYS_RESULT=$3 + ALL_RESULT=$4 + SERIAL_RESULT=$5 + KEYID_RESULT=$6 + CERTS_RESULT=$7 + CA_RESULT=$8 + SERIAL_WRESULT=$9 + KEYID_WRESULT=$10 + verbose "$tid: checking revocations for $TAG" + for f in $FILES ; do + check_krl $f $OBJ/krl-empty no "$TAG" + check_krl $f $OBJ/krl-keys $KEYS_RESULT "$TAG" + check_krl $f $OBJ/krl-all $ALL_RESULT "$TAG" + check_krl $f $OBJ/krl-serial $SERIAL_RESULT "$TAG" + check_krl $f $OBJ/krl-keyid $KEYID_RESULT "$TAG" + check_krl $f $OBJ/krl-cert $CERTS_RESULT "$TAG" + check_krl $f $OBJ/krl-ca $CA_RESULT "$TAG" + check_krl $f $OBJ/krl-serial-wild $SERIAL_WRESULT "$TAG" + check_krl $f $OBJ/krl-keyid-wild $KEYID_WRESULT "$TAG" + done +} + +test_all() { + # wildcard + # keys all sr# k.ID cert CA sr.# k.ID + test_rev "$RKEYS" "revoked keys" yes yes no no no no no no + test_rev "$UKEYS" "unrevoked keys" no no no no no no no no + test_rev "$RCERTS" "revoked certs" yes yes yes yes yes yes yes yes + test_rev "$UCERTS" "unrevoked certs" no no no no no yes no no +} + +test_all + +# Check update. Results should be identical. +verbose "$tid: testing KRL update" +for f in $OBJ/krl-keys $OBJ/krl-cert $OBJ/krl-all \ + $OBJ/krl-ca $OBJ/krl-serial $OBJ/krl-keyid \ + $OBJ/krl-serial-wild $OBJ/krl-keyid-wild; do + cp -f $OBJ/krl-empty $f + genkrls -u +done + +test_all diff --git a/crypto/external/bsd/openssh/dist/regress/limit-keytype.sh b/crypto/external/bsd/openssh/dist/regress/limit-keytype.sh new file mode 100644 index 000000000..2de037bd1 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/limit-keytype.sh @@ -0,0 +1,80 @@ +# $OpenBSD: limit-keytype.sh,v 1.1 2015/01/13 07:49:49 djm Exp $ +# Placed in the Public Domain. + +tid="restrict pubkey type" + +rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/user_key* +rm -f $OBJ/authorized_principals_$USER $OBJ/cert_user_key* + +mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig +mv $OBJ/ssh_proxy $OBJ/ssh_proxy.orig + +# Create a CA key +${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_ca_key ||\ + fatal "ssh-keygen failed" + +# Make some keys and a certificate. +${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key1 || \ + fatal "ssh-keygen failed" +${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_key2 || \ + fatal "ssh-keygen failed" +${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_key3 || \ + fatal "ssh-keygen failed" +${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \ + -z $$ -n ${USER},mekmitasdigoat $OBJ/user_key3 || + fatal "couldn't sign user_key1" +# Copy the private key alongside the cert to allow better control of when +# it is offered. +mv $OBJ/user_key3-cert.pub $OBJ/cert_user_key3.pub +cp -p $OBJ/user_key3 $OBJ/cert_user_key3 + +grep -v IdentityFile $OBJ/ssh_proxy.orig > $OBJ/ssh_proxy + +opts="-oProtocol=2 -F $OBJ/ssh_proxy -oIdentitiesOnly=yes" +fullopts="$opts -i $OBJ/cert_user_key3 -i $OBJ/user_key1 -i $OBJ/user_key2" + +echo mekmitasdigoat > $OBJ/authorized_principals_$USER +cat $OBJ/user_key1.pub > $OBJ/authorized_keys_$USER +cat $OBJ/user_key2.pub >> $OBJ/authorized_keys_$USER + +prepare_config() { + ( + grep -v "Protocol" $OBJ/sshd_proxy.orig + echo "Protocol 2" + echo "AuthenticationMethods publickey" + echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" + echo "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" + for x in "$@" ; do + echo "$x" + done + ) > $OBJ/sshd_proxy +} + +prepare_config + +# Check we can log in with all key types. +${SSH} $opts -i $OBJ/cert_user_key3 proxy true || fatal "cert failed" +${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" +${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed" + +# Allow plain Ed25519 and RSA. The certificate should fail. +verbose "privsep=$privsep allow rsa,ed25519" +prepare_config "PubkeyAcceptedKeyTypes ssh-rsa,ssh-ed25519" +${SSH} $opts -i $OBJ/cert_user_key3 proxy true && fatal "cert succeeded" +${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" +${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed" + +# Allow Ed25519 only. +verbose "privsep=$privsep allow ed25519" +prepare_config "PubkeyAcceptedKeyTypes ssh-ed25519" +${SSH} $opts -i $OBJ/cert_user_key3 proxy true && fatal "cert succeeded" +${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" +${SSH} $opts -i $OBJ/user_key2 proxy true && fatal "key2 succeeded" + +# Allow all certs. Plain keys should fail. +verbose "privsep=$privsep allow cert only" +prepare_config "PubkeyAcceptedKeyTypes ssh-*-cert-v01@openssh.com" +${SSH} $opts -i $OBJ/cert_user_key3 proxy true || fatal "cert failed" +${SSH} $opts -i $OBJ/user_key1 proxy true && fatal "key1 succeeded" +${SSH} $opts -i $OBJ/user_key2 proxy true && fatal "key2 succeeded" + diff --git a/crypto/external/bsd/openssh/dist/regress/localcommand.sh b/crypto/external/bsd/openssh/dist/regress/localcommand.sh new file mode 100644 index 000000000..220f19a4d --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/localcommand.sh @@ -0,0 +1,15 @@ +# $OpenBSD: localcommand.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="localcommand" + +echo 'PermitLocalCommand yes' >> $OBJ/ssh_proxy +echo 'LocalCommand echo foo' >> $OBJ/ssh_proxy + +for p in ${SSH_PROTOCOLS}; do + verbose "test $tid: proto $p localcommand" + a=`${SSH} -F $OBJ/ssh_proxy -$p somehost true` + if [ "$a" != "foo" ] ; then + fail "$tid proto $p" + fi +done diff --git a/crypto/external/bsd/openssh/dist/regress/login-timeout.sh b/crypto/external/bsd/openssh/dist/regress/login-timeout.sh new file mode 100644 index 000000000..eb76f554b --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/login-timeout.sh @@ -0,0 +1,32 @@ +# $OpenBSD: login-timeout.sh,v 1.7 2014/03/13 20:44:49 djm Exp $ +# Placed in the Public Domain. + +tid="connect after login grace timeout" + +trace "test login grace with privsep" +cp $OBJ/sshd_config $OBJ/sshd_config.orig +grep -vi LoginGraceTime $OBJ/sshd_config.orig > $OBJ/sshd_config +echo "LoginGraceTime 10s" >> $OBJ/sshd_config +echo "MaxStartups 1" >> $OBJ/sshd_config +start_sshd + +(echo SSH-2.0-fake; sleep 60) | telnet 127.0.0.1 ${PORT} >/dev/null 2>&1 & +sleep 15 +${SSH} -F $OBJ/ssh_config somehost true +if [ $? -ne 0 ]; then + fail "ssh connect after login grace timeout failed with privsep" +fi + +$SUDO kill `$SUDO cat $PIDFILE` + +trace "test login grace without privsep" +echo "UsePrivilegeSeparation no" >> $OBJ/sshd_config +start_sshd +sleep 1 + +(echo SSH-2.0-fake; sleep 60) | telnet 127.0.0.1 ${PORT} >/dev/null 2>&1 & +sleep 15 +${SSH} -F $OBJ/ssh_config somehost true +if [ $? -ne 0 ]; then + fail "ssh connect after login grace timeout failed without privsep" +fi diff --git a/crypto/external/bsd/openssh/dist/regress/modpipe.c b/crypto/external/bsd/openssh/dist/regress/modpipe.c new file mode 100755 index 000000000..e854f9e07 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/modpipe.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2012 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* $OpenBSD: modpipe.c,v 1.6 2013/11/21 03:16:47 djm Exp $ */ + +#include "includes.h" + +#include +#include +#include +#include +#include +#include +#include +#include "openbsd-compat/getopt_long.c" + +static void err(int, const char *, ...) __attribute__((format(printf, 2, 3))); +static void errx(int, const char *, ...) __attribute__((format(printf, 2, 3))); + +static void +err(int r, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + fprintf(stderr, "%s: ", strerror(errno)); + vfprintf(stderr, fmt, args); + fputc('\n', stderr); + va_end(args); + exit(r); +} + +static void +errx(int r, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + fputc('\n', stderr); + va_end(args); + exit(r); +} + +static void +usage(void) +{ + fprintf(stderr, "Usage: modpipe -w [-m modspec ...] < in > out\n"); + fprintf(stderr, "modspec is one of:\n"); + fprintf(stderr, " xor:offset:value - XOR \"value\" at \"offset\"\n"); + fprintf(stderr, " andor:offset:val1:val2 - AND \"val1\" then OR \"val2\" at \"offset\"\n"); + exit(1); +} + +#define MAX_MODIFICATIONS 256 +struct modification { + enum { MOD_XOR, MOD_AND_OR } what; + unsigned long long offset; + u_int8_t m1, m2; +}; + +static void +parse_modification(const char *s, struct modification *m) +{ + char what[16+1]; + int n, m1, m2; + + bzero(m, sizeof(*m)); + if ((n = sscanf(s, "%16[^:]%*[:]%llu%*[:]%i%*[:]%i", + what, &m->offset, &m1, &m2)) < 3) + errx(1, "Invalid modification spec \"%s\"", s); + if (strcasecmp(what, "xor") == 0) { + if (n > 3) + errx(1, "Invalid modification spec \"%s\"", s); + if (m1 < 0 || m1 > 0xff) + errx(1, "Invalid XOR modification value"); + m->what = MOD_XOR; + m->m1 = m1; + } else if (strcasecmp(what, "andor") == 0) { + if (n != 4) + errx(1, "Invalid modification spec \"%s\"", s); + if (m1 < 0 || m1 > 0xff) + errx(1, "Invalid AND modification value"); + if (m2 < 0 || m2 > 0xff) + errx(1, "Invalid OR modification value"); + m->what = MOD_AND_OR; + m->m1 = m1; + m->m2 = m2; + } else + errx(1, "Invalid modification type \"%s\"", what); +} + +int +main(int argc, char **argv) +{ + int ch; + u_char buf[8192]; + size_t total; + ssize_t r, s, o; + struct modification mods[MAX_MODIFICATIONS]; + u_int i, wflag = 0, num_mods = 0; + + while ((ch = getopt(argc, argv, "wm:")) != -1) { + switch (ch) { + case 'm': + if (num_mods >= MAX_MODIFICATIONS) + errx(1, "Too many modifications"); + parse_modification(optarg, &(mods[num_mods++])); + break; + case 'w': + wflag = 1; + break; + default: + usage(); + /* NOTREACHED */ + } + } + for (total = 0;;) { + r = s = read(STDIN_FILENO, buf, sizeof(buf)); + if (r == 0) + break; + if (r < 0) { + if (errno == EAGAIN || errno == EINTR) + continue; + err(1, "read"); + } + for (i = 0; i < num_mods; i++) { + if (mods[i].offset < total || + mods[i].offset >= total + s) + continue; + switch (mods[i].what) { + case MOD_XOR: + buf[mods[i].offset - total] ^= mods[i].m1; + break; + case MOD_AND_OR: + buf[mods[i].offset - total] &= mods[i].m1; + buf[mods[i].offset - total] |= mods[i].m2; + break; + } + } + for (o = 0; o < s; o += r) { + r = write(STDOUT_FILENO, buf, s - o); + if (r == 0) + break; + if (r < 0) { + if (errno == EAGAIN || errno == EINTR) + continue; + err(1, "write"); + } + } + total += s; + } + /* Warn if modifications not reached in input stream */ + r = 0; + for (i = 0; wflag && i < num_mods; i++) { + if (mods[i].offset < total) + continue; + r = 1; + fprintf(stderr, "modpipe: warning - mod %u not reached\n", i); + } + return r; +} diff --git a/crypto/external/bsd/openssh/dist/regress/multiplex.sh b/crypto/external/bsd/openssh/dist/regress/multiplex.sh new file mode 100644 index 000000000..acb9234d9 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/multiplex.sh @@ -0,0 +1,190 @@ +# $OpenBSD: multiplex.sh,v 1.27 2014/12/22 06:14:29 djm Exp $ +# Placed in the Public Domain. + +CTL=/tmp/openssh.regress.ctl-sock.$$ + +tid="connection multiplexing" + +NC=$OBJ/netcat + +trace "will use ProxyCommand $proxycmd" +if config_defined DISABLE_FD_PASSING ; then + echo "skipped (not supported on this platform)" + exit 0 +fi + +P=3301 # test port + +wait_for_mux_master_ready() +{ + for i in 1 2 3 4 5; do + ${SSH} -F $OBJ/ssh_config -S $CTL -Ocheck otherhost \ + >/dev/null 2>&1 && return 0 + sleep $i + done + fatal "mux master never becomes ready" +} + +start_sshd + +start_mux_master() +{ + trace "start master, fork to background" + ${SSH} -Nn2 -MS$CTL -F $OBJ/ssh_config -oSendEnv="_XXX_TEST" somehost \ + -E $TEST_REGRESS_LOGFILE 2>&1 & + # NB. $SSH_PID will be killed by test-exec.sh:cleanup on fatal errors. + SSH_PID=$! + wait_for_mux_master_ready +} + +start_mux_master + +verbose "test $tid: envpass" +trace "env passing over multiplexed connection" +_XXX_TEST=blah ${SSH} -F $OBJ/ssh_config -oSendEnv="_XXX_TEST" -S$CTL otherhost sh << 'EOF' + test X"$_XXX_TEST" = X"blah" +EOF +if [ $? -ne 0 ]; then + fail "environment not found" +fi + +verbose "test $tid: transfer" +rm -f ${COPY} +trace "ssh transfer over multiplexed connection and check result" +${SSH} -F $OBJ/ssh_config -S$CTL otherhost cat ${DATA} > ${COPY} +test -f ${COPY} || fail "ssh -Sctl: failed copy ${DATA}" +cmp ${DATA} ${COPY} || fail "ssh -Sctl: corrupted copy of ${DATA}" + +rm -f ${COPY} +trace "ssh transfer over multiplexed connection and check result" +${SSH} -F $OBJ/ssh_config -S $CTL otherhost cat ${DATA} > ${COPY} +test -f ${COPY} || fail "ssh -S ctl: failed copy ${DATA}" +cmp ${DATA} ${COPY} || fail "ssh -S ctl: corrupted copy of ${DATA}" + +rm -f ${COPY} +trace "sftp transfer over multiplexed connection and check result" +echo "get ${DATA} ${COPY}" | \ + ${SFTP} -S ${SSH} -F $OBJ/ssh_config -oControlPath=$CTL otherhost >>$TEST_REGRESS_LOGFILE 2>&1 +test -f ${COPY} || fail "sftp: failed copy ${DATA}" +cmp ${DATA} ${COPY} || fail "sftp: corrupted copy of ${DATA}" + +rm -f ${COPY} +trace "scp transfer over multiplexed connection and check result" +${SCP} -S ${SSH} -F $OBJ/ssh_config -oControlPath=$CTL otherhost:${DATA} ${COPY} >>$TEST_REGRESS_LOGFILE 2>&1 +test -f ${COPY} || fail "scp: failed copy ${DATA}" +cmp ${DATA} ${COPY} || fail "scp: corrupted copy of ${DATA}" + +rm -f ${COPY} +verbose "test $tid: forward" +trace "forward over TCP/IP and check result" +$NC -N -l 127.0.0.1 $((${PORT} + 1)) < ${DATA} > /dev/null & +netcat_pid=$! +${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L127.0.0.1:$((${PORT} + 2)):127.0.0.1:$((${PORT} + 1)) otherhost >>$TEST_SSH_LOGFILE 2>&1 +$NC 127.0.0.1 $((${PORT} + 2)) < /dev/null > ${COPY} +cmp ${DATA} ${COPY} || fail "ssh: corrupted copy of ${DATA}" +kill $netcat_pid 2>/dev/null +rm -f ${COPY} $OBJ/unix-[123].fwd + +trace "forward over UNIX and check result" +$NC -N -Ul $OBJ/unix-1.fwd < ${DATA} > /dev/null & +netcat_pid=$! +${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L$OBJ/unix-2.fwd:$OBJ/unix-1.fwd otherhost >>$TEST_SSH_LOGFILE 2>&1 +${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R$OBJ/unix-3.fwd:$OBJ/unix-2.fwd otherhost >>$TEST_SSH_LOGFILE 2>&1 +$NC -U $OBJ/unix-3.fwd < /dev/null > ${COPY} 2>/dev/null +cmp ${DATA} ${COPY} || fail "ssh: corrupted copy of ${DATA}" +kill $netcat_pid 2>/dev/null +rm -f ${COPY} $OBJ/unix-[123].fwd + +for s in 0 1 4 5 44; do + trace "exit status $s over multiplexed connection" + verbose "test $tid: status $s" + ${SSH} -F $OBJ/ssh_config -S $CTL otherhost exit $s + r=$? + if [ $r -ne $s ]; then + fail "exit code mismatch for protocol $p: $r != $s" + fi + + # same with early close of stdout/err + trace "exit status $s with early close over multiplexed connection" + ${SSH} -F $OBJ/ssh_config -S $CTL -n otherhost \ + exec sh -c \'"sleep 2; exec > /dev/null 2>&1; sleep 3; exit $s"\' + r=$? + if [ $r -ne $s ]; then + fail "exit code (with sleep) mismatch for protocol $p: $r != $s" + fi +done + +verbose "test $tid: cmd check" +${SSH} -F $OBJ/ssh_config -S $CTL -Ocheck otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \ + || fail "check command failed" + +verbose "test $tid: cmd forward local (TCP)" +${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L $P:localhost:$PORT otherhost \ + || fail "request local forward failed" +${SSH} -F $OBJ/ssh_config -p$P otherhost true \ + || fail "connect to local forward port failed" +${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -L $P:localhost:$PORT otherhost \ + || fail "cancel local forward failed" +${SSH} -F $OBJ/ssh_config -p$P otherhost true \ + && fail "local forward port still listening" + +verbose "test $tid: cmd forward remote (TCP)" +${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R $P:localhost:$PORT otherhost \ + || fail "request remote forward failed" +${SSH} -F $OBJ/ssh_config -p$P otherhost true \ + || fail "connect to remote forwarded port failed" +${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -R $P:localhost:$PORT otherhost \ + || fail "cancel remote forward failed" +${SSH} -F $OBJ/ssh_config -p$P otherhost true \ + && fail "remote forward port still listening" + +verbose "test $tid: cmd forward local (UNIX)" +${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L $OBJ/unix-1.fwd:localhost:$PORT otherhost \ + || fail "request local forward failed" +echo "" | $NC -U $OBJ/unix-1.fwd | grep "Protocol mismatch" >/dev/null 2>&1 \ + || fail "connect to local forward path failed" +${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -L $OBJ/unix-1.fwd:localhost:$PORT otherhost \ + || fail "cancel local forward failed" +N=$(echo "xyzzy" | $NC -U $OBJ/unix-1.fwd 2>&1 | grep "xyzzy" | wc -l) +test ${N} -eq 0 || fail "local forward path still listening" +rm -f $OBJ/unix-1.fwd + +verbose "test $tid: cmd forward remote (UNIX)" +${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R $OBJ/unix-1.fwd:localhost:$PORT otherhost \ + || fail "request remote forward failed" +echo "" | $NC -U $OBJ/unix-1.fwd | grep "Protocol mismatch" >/dev/null 2>&1 \ + || fail "connect to remote forwarded path failed" +${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -R $OBJ/unix-1.fwd:localhost:$PORT otherhost \ + || fail "cancel remote forward failed" +N=$(echo "xyzzy" | $NC -U $OBJ/unix-1.fwd 2>&1 | grep "xyzzy" | wc -l) +test ${N} -eq 0 || fail "remote forward path still listening" +rm -f $OBJ/unix-1.fwd + +verbose "test $tid: cmd exit" +${SSH} -F $OBJ/ssh_config -S $CTL -Oexit otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \ + || fail "send exit command failed" + +# Wait for master to exit +wait $SSH_PID +kill -0 $SSH_PID >/dev/null 2>&1 && fail "exit command failed" + +# Restart master and test -O stop command with master using -N +verbose "test $tid: cmd stop" +trace "restart master, fork to background" +start_mux_master + +# start a long-running command then immediately request a stop +${SSH} -F $OBJ/ssh_config -S $CTL otherhost "sleep 10; exit 0" \ + >>$TEST_REGRESS_LOGFILE 2>&1 & +SLEEP_PID=$! +${SSH} -F $OBJ/ssh_config -S $CTL -Ostop otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \ + || fail "send stop command failed" + +# wait until both long-running command and master have exited. +wait $SLEEP_PID +[ $! != 0 ] || fail "waiting for concurrent command" +wait $SSH_PID +[ $! != 0 ] || fail "waiting for master stop" +kill -0 $SSH_PID >/dev/null 2>&1 && fatal "stop command failed" +SSH_PID="" # Already gone, so don't kill in cleanup + diff --git a/crypto/external/bsd/openssh/dist/regress/multipubkey.sh b/crypto/external/bsd/openssh/dist/regress/multipubkey.sh new file mode 100644 index 000000000..e9d15306f --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/multipubkey.sh @@ -0,0 +1,66 @@ +# $OpenBSD: multipubkey.sh,v 1.1 2014/12/22 08:06:03 djm Exp $ +# Placed in the Public Domain. + +tid="multiple pubkey" + +rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/user_key* +rm -f $OBJ/authorized_principals_$USER $OBJ/cert_user_key* + +mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig +mv $OBJ/ssh_proxy $OBJ/ssh_proxy.orig + +# Create a CA key +${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_ca_key ||\ + fatal "ssh-keygen failed" + +# Make some keys and a certificate. +${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key1 || \ + fatal "ssh-keygen failed" +${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key2 || \ + fatal "ssh-keygen failed" +${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \ + -z $$ -n ${USER},mekmitasdigoat $OBJ/user_key1 || + fail "couldn't sign user_key1" +# Copy the private key alongside the cert to allow better control of when +# it is offered. +mv $OBJ/user_key1-cert.pub $OBJ/cert_user_key1.pub +cp -p $OBJ/user_key1 $OBJ/cert_user_key1 + +grep -v IdentityFile $OBJ/ssh_proxy.orig > $OBJ/ssh_proxy + +opts="-oProtocol=2 -F $OBJ/ssh_proxy -oIdentitiesOnly=yes" +opts="$opts -i $OBJ/cert_user_key1 -i $OBJ/user_key1 -i $OBJ/user_key2" + +for privsep in no yes; do + ( + grep -v "Protocol" $OBJ/sshd_proxy.orig + echo "Protocol 2" + echo "UsePrivilegeSeparation $privsep" + echo "AuthenticationMethods publickey,publickey" + echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" + echo "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" + ) > $OBJ/sshd_proxy + + # Single key should fail. + rm -f $OBJ/authorized_principals_$USER + cat $OBJ/user_key1.pub > $OBJ/authorized_keys_$USER + ${SSH} $opts proxy true && fail "ssh succeeded with key" + + # Single key with same-public cert should fail. + echo mekmitasdigoat > $OBJ/authorized_principals_$USER + cat $OBJ/user_key1.pub > $OBJ/authorized_keys_$USER + ${SSH} $opts proxy true && fail "ssh succeeded with key+cert" + + # Multiple plain keys should succeed. + rm -f $OBJ/authorized_principals_$USER + cat $OBJ/user_key1.pub $OBJ/user_key2.pub > \ + $OBJ/authorized_keys_$USER + ${SSH} $opts proxy true || fail "ssh failed with multiple keys" + # Cert and different key should succeed + + # Key and different-public cert should succeed. + echo mekmitasdigoat > $OBJ/authorized_principals_$USER + cat $OBJ/user_key2.pub > $OBJ/authorized_keys_$USER + ${SSH} $opts proxy true || fail "ssh failed with key/cert" +done + diff --git a/crypto/external/bsd/openssh/dist/regress/netcat.c b/crypto/external/bsd/openssh/dist/regress/netcat.c new file mode 100644 index 000000000..6234ba019 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/netcat.c @@ -0,0 +1,1696 @@ +/* $OpenBSD: netcat.c,v 1.126 2014/10/30 16:08:31 tedu Exp $ */ +/* + * Copyright (c) 2001 Eric Jackson + * + * 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 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. + */ + +/* + * Re-written nc(1) for OpenBSD. Original implementation by + * *Hobbit* . + */ + +#include "includes.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "atomicio.h" + +#ifdef HAVE_POLL_H +#include +#else +# ifdef HAVE_SYS_POLL_H +# include +# endif +#endif + +/* Telnet options from arpa/telnet.h */ +#define IAC 255 +#define DONT 254 +#define DO 253 +#define WONT 252 +#define WILL 251 + +#ifndef SUN_LEN +#define SUN_LEN(su) \ + (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) +#endif + +#define PORT_MAX 65535 +#define PORT_MAX_LEN 6 +#define UNIX_DG_TMP_SOCKET_SIZE 19 + +#define POLL_STDIN 0 +#define POLL_NETOUT 1 +#define POLL_NETIN 2 +#define POLL_STDOUT 3 +#define BUFSIZE 16384 + +/* Command Line Options */ +int dflag; /* detached, no stdin */ +int Fflag; /* fdpass sock to stdout */ +unsigned int iflag; /* Interval Flag */ +int kflag; /* More than one connect */ +int lflag; /* Bind to local port */ +int Nflag; /* shutdown() network socket */ +int nflag; /* Don't do name look up */ +char *Pflag; /* Proxy username */ +char *pflag; /* Localport flag */ +int rflag; /* Random ports flag */ +char *sflag; /* Source Address */ +int tflag; /* Telnet Emulation */ +int uflag; /* UDP - Default to TCP */ +int vflag; /* Verbosity */ +int xflag; /* Socks proxy */ +int zflag; /* Port Scan Flag */ +int Dflag; /* sodebug */ +int Iflag; /* TCP receive buffer size */ +int Oflag; /* TCP send buffer size */ +int Sflag; /* TCP MD5 signature option */ +int Tflag = -1; /* IP Type of Service */ +int rtableid = -1; + +int timeout = -1; +int family = AF_UNSPEC; +char *portlist[PORT_MAX+1]; +char *unix_dg_tmp_socket; + +void atelnet(int, unsigned char *, unsigned int); +void build_ports(char *); +void help(void); +int local_listen(char *, char *, struct addrinfo); +void readwrite(int); +void fdpass(int nfd) __attribute__((noreturn)); +int remote_connect(const char *, const char *, struct addrinfo); +int timeout_connect(int, const struct sockaddr *, socklen_t); +int socks_connect(const char *, const char *, struct addrinfo, + const char *, const char *, struct addrinfo, int, const char *); +int udptest(int); +int unix_bind(char *); +int unix_connect(char *); +int unix_listen(char *); +void set_common_sockopts(int); +int map_tos(char *, int *); +void report_connect(const struct sockaddr *, socklen_t); +void usage(int); +ssize_t drainbuf(int, unsigned char *, size_t *); +ssize_t fillbuf(int, unsigned char *, size_t *); + +static void err(int, const char *, ...) __attribute__((format(printf, 2, 3))); +static void errx(int, const char *, ...) __attribute__((format(printf, 2, 3))); +static void warn(const char *, ...) __attribute__((format(printf, 1, 2))); + +static void +err(int r, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + fprintf(stderr, "%s: ", strerror(errno)); + vfprintf(stderr, fmt, args); + fputc('\n', stderr); + va_end(args); + exit(r); +} + +static void +errx(int r, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + fputc('\n', stderr); + va_end(args); + exit(r); +} + +static void +warn(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + fprintf(stderr, "%s: ", strerror(errno)); + vfprintf(stderr, fmt, args); + fputc('\n', stderr); + va_end(args); +} + +int +main(int argc, char *argv[]) +{ + int ch, s, ret, socksv; + char *host, *uport; + struct addrinfo hints; + struct servent *sv; + socklen_t len; + struct sockaddr_storage cliaddr; + char *proxy = NULL; + const char *errstr, *proxyhost = "", *proxyport = NULL; + struct addrinfo proxyhints; + char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE]; + + ret = 1; + s = 0; + socksv = 5; + host = NULL; + uport = NULL; + sv = NULL; + + while ((ch = getopt(argc, argv, + "46DdFhI:i:klNnO:P:p:rSs:tT:UuV:vw:X:x:z")) != -1) { + switch (ch) { + case '4': + family = AF_INET; + break; + case '6': + family = AF_INET6; + break; + case 'U': + family = AF_UNIX; + break; + case 'X': + if (strcasecmp(optarg, "connect") == 0) + socksv = -1; /* HTTP proxy CONNECT */ + else if (strcmp(optarg, "4") == 0) + socksv = 4; /* SOCKS v.4 */ + else if (strcmp(optarg, "5") == 0) + socksv = 5; /* SOCKS v.5 */ + else + errx(1, "unsupported proxy protocol"); + break; + case 'd': + dflag = 1; + break; + case 'F': + Fflag = 1; + break; + case 'h': + help(); + break; + case 'i': + iflag = strtonum(optarg, 0, UINT_MAX, &errstr); + if (errstr) + errx(1, "interval %s: %s", errstr, optarg); + break; + case 'k': + kflag = 1; + break; + case 'l': + lflag = 1; + break; + case 'N': + Nflag = 1; + break; + case 'n': + nflag = 1; + break; + case 'P': + Pflag = optarg; + break; + case 'p': + pflag = optarg; + break; + case 'r': + rflag = 1; + break; + case 's': + sflag = optarg; + break; + case 't': + tflag = 1; + break; + case 'u': + uflag = 1; + break; +#ifdef SO_RTABLE + case 'V': + rtableid = (int)strtonum(optarg, 0, + RT_TABLEID_MAX, &errstr); + if (errstr) + errx(1, "rtable %s: %s", errstr, optarg); + break; +#endif + case 'v': + vflag = 1; + break; + case 'w': + timeout = strtonum(optarg, 0, INT_MAX / 1000, &errstr); + if (errstr) + errx(1, "timeout %s: %s", errstr, optarg); + timeout *= 1000; + break; + case 'x': + xflag = 1; + if ((proxy = strdup(optarg)) == NULL) + errx(1, "strdup"); + break; + case 'z': + zflag = 1; + break; + case 'D': + Dflag = 1; + break; + case 'I': + Iflag = strtonum(optarg, 1, 65536 << 14, &errstr); + if (errstr != NULL) + errx(1, "TCP receive window %s: %s", + errstr, optarg); + break; + case 'O': + Oflag = strtonum(optarg, 1, 65536 << 14, &errstr); + if (errstr != NULL) + errx(1, "TCP send window %s: %s", + errstr, optarg); + break; + case 'S': + Sflag = 1; + break; + case 'T': + errstr = NULL; + errno = 0; + if (map_tos(optarg, &Tflag)) + break; + if (strlen(optarg) > 1 && optarg[0] == '0' && + optarg[1] == 'x') + Tflag = (int)strtol(optarg, NULL, 16); + else + Tflag = (int)strtonum(optarg, 0, 255, + &errstr); + if (Tflag < 0 || Tflag > 255 || errstr || errno) + errx(1, "illegal tos value %s", optarg); + break; + default: + usage(1); + } + } + argc -= optind; + argv += optind; + + /* Cruft to make sure options are clean, and used properly. */ + if (argv[0] && !argv[1] && family == AF_UNIX) { + host = argv[0]; + uport = NULL; + } else if (argv[0] && !argv[1]) { + if (!lflag) + usage(1); + uport = argv[0]; + host = NULL; + } else if (argv[0] && argv[1]) { + host = argv[0]; + uport = argv[1]; + } else + usage(1); + + if (lflag && sflag) + errx(1, "cannot use -s and -l"); + if (lflag && pflag) + errx(1, "cannot use -p and -l"); + if (lflag && zflag) + errx(1, "cannot use -z and -l"); + if (!lflag && kflag) + errx(1, "must use -l with -k"); + + /* Get name of temporary socket for unix datagram client */ + if ((family == AF_UNIX) && uflag && !lflag) { + if (sflag) { + unix_dg_tmp_socket = sflag; + } else { + strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc.XXXXXXXXXX", + UNIX_DG_TMP_SOCKET_SIZE); + if (mktemp(unix_dg_tmp_socket_buf) == NULL) + err(1, "mktemp"); + unix_dg_tmp_socket = unix_dg_tmp_socket_buf; + } + } + + /* Initialize addrinfo structure. */ + if (family != AF_UNIX) { + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = family; + hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; + hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; + if (nflag) + hints.ai_flags |= AI_NUMERICHOST; + } + + if (xflag) { + if (uflag) + errx(1, "no proxy support for UDP mode"); + + if (lflag) + errx(1, "no proxy support for listen"); + + if (family == AF_UNIX) + errx(1, "no proxy support for unix sockets"); + + /* XXX IPv6 transport to proxy would probably work */ + if (family == AF_INET6) + errx(1, "no proxy support for IPv6"); + + if (sflag) + errx(1, "no proxy support for local source address"); + + proxyhost = strsep(&proxy, ":"); + proxyport = proxy; + + memset(&proxyhints, 0, sizeof(struct addrinfo)); + proxyhints.ai_family = family; + proxyhints.ai_socktype = SOCK_STREAM; + proxyhints.ai_protocol = IPPROTO_TCP; + if (nflag) + proxyhints.ai_flags |= AI_NUMERICHOST; + } + + if (lflag) { + int connfd; + ret = 0; + + if (family == AF_UNIX) { + if (uflag) + s = unix_bind(host); + else + s = unix_listen(host); + } + + /* Allow only one connection at a time, but stay alive. */ + for (;;) { + if (family != AF_UNIX) + s = local_listen(host, uport, hints); + if (s < 0) + err(1, "local_listen"); + /* + * For UDP and -k, don't connect the socket, let it + * receive datagrams from multiple socket pairs. + */ + if (uflag && kflag) + readwrite(s); + /* + * For UDP and not -k, we will use recvfrom() initially + * to wait for a caller, then use the regular functions + * to talk to the caller. + */ + else if (uflag && !kflag) { + int rv, plen; + char buf[16384]; + struct sockaddr_storage z; + + len = sizeof(z); + plen = 2048; + rv = recvfrom(s, buf, plen, MSG_PEEK, + (struct sockaddr *)&z, &len); + if (rv < 0) + err(1, "recvfrom"); + + rv = connect(s, (struct sockaddr *)&z, len); + if (rv < 0) + err(1, "connect"); + + if (vflag) + report_connect((struct sockaddr *)&z, len); + + readwrite(s); + } else { + len = sizeof(cliaddr); + connfd = accept(s, (struct sockaddr *)&cliaddr, + &len); + if (connfd == -1) { + /* For now, all errnos are fatal */ + err(1, "accept"); + } + if (vflag) + report_connect((struct sockaddr *)&cliaddr, len); + + readwrite(connfd); + close(connfd); + } + + if (family != AF_UNIX) + close(s); + else if (uflag) { + if (connect(s, NULL, 0) < 0) + err(1, "connect"); + } + + if (!kflag) + break; + } + } else if (family == AF_UNIX) { + ret = 0; + + if ((s = unix_connect(host)) > 0 && !zflag) { + readwrite(s); + close(s); + } else + ret = 1; + + if (uflag) + unlink(unix_dg_tmp_socket); + exit(ret); + + } else { + int i = 0; + + /* Construct the portlist[] array. */ + build_ports(uport); + + /* Cycle through portlist, connecting to each port. */ + for (i = 0; portlist[i] != NULL; i++) { + if (s) + close(s); + + if (xflag) + s = socks_connect(host, portlist[i], hints, + proxyhost, proxyport, proxyhints, socksv, + Pflag); + else + s = remote_connect(host, portlist[i], hints); + + if (s < 0) + continue; + + ret = 0; + if (vflag || zflag) { + /* For UDP, make sure we are connected. */ + if (uflag) { + if (udptest(s) == -1) { + ret = 1; + continue; + } + } + + /* Don't look up port if -n. */ + if (nflag) + sv = NULL; + else { + sv = getservbyport( + ntohs(atoi(portlist[i])), + uflag ? "udp" : "tcp"); + } + + fprintf(stderr, + "Connection to %s %s port [%s/%s] " + "succeeded!\n", host, portlist[i], + uflag ? "udp" : "tcp", + sv ? sv->s_name : "*"); + } + if (Fflag) + fdpass(s); + else if (!zflag) + readwrite(s); + } + } + + if (s) + close(s); + + exit(ret); +} + +/* + * unix_bind() + * Returns a unix socket bound to the given path + */ +int +unix_bind(char *path) +{ + struct sockaddr_un sun_sa; + int s; + + /* Create unix domain socket. */ + if ((s = socket(AF_UNIX, uflag ? SOCK_DGRAM : SOCK_STREAM, + 0)) < 0) + return (-1); + + memset(&sun_sa, 0, sizeof(struct sockaddr_un)); + sun_sa.sun_family = AF_UNIX; + + if (strlcpy(sun_sa.sun_path, path, sizeof(sun_sa.sun_path)) >= + sizeof(sun_sa.sun_path)) { + close(s); + errno = ENAMETOOLONG; + return (-1); + } + + if (bind(s, (struct sockaddr *)&sun_sa, SUN_LEN(&sun_sa)) < 0) { + close(s); + return (-1); + } + return (s); +} + +/* + * unix_connect() + * Returns a socket connected to a local unix socket. Returns -1 on failure. + */ +int +unix_connect(char *path) +{ + struct sockaddr_un sun_sa; + int s; + + if (uflag) { + if ((s = unix_bind(unix_dg_tmp_socket)) < 0) + return (-1); + } else { + if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + return (-1); + } + (void)fcntl(s, F_SETFD, FD_CLOEXEC); + + memset(&sun_sa, 0, sizeof(struct sockaddr_un)); + sun_sa.sun_family = AF_UNIX; + + if (strlcpy(sun_sa.sun_path, path, sizeof(sun_sa.sun_path)) >= + sizeof(sun_sa.sun_path)) { + close(s); + errno = ENAMETOOLONG; + return (-1); + } + if (connect(s, (struct sockaddr *)&sun_sa, SUN_LEN(&sun_sa)) < 0) { + close(s); + return (-1); + } + return (s); + +} + +/* + * unix_listen() + * Create a unix domain socket, and listen on it. + */ +int +unix_listen(char *path) +{ + int s; + if ((s = unix_bind(path)) < 0) + return (-1); + + if (listen(s, 5) < 0) { + close(s); + return (-1); + } + return (s); +} + +/* + * remote_connect() + * Returns a socket connected to a remote host. Properly binds to a local + * port or source address if needed. Returns -1 on failure. + */ +int +remote_connect(const char *host, const char *port, struct addrinfo hints) +{ + struct addrinfo *res, *res0; + int s, error; +#if defined(SO_RTABLE) || defined(SO_BINDANY) + int on = 1; +#endif + + if ((error = getaddrinfo(host, port, &hints, &res))) + errx(1, "getaddrinfo: %s", gai_strerror(error)); + + res0 = res; + do { + if ((s = socket(res0->ai_family, res0->ai_socktype, + res0->ai_protocol)) < 0) + continue; + +#ifdef SO_RTABLE + if (rtableid >= 0 && (setsockopt(s, SOL_SOCKET, SO_RTABLE, + &rtableid, sizeof(rtableid)) == -1)) + err(1, "setsockopt SO_RTABLE"); +#endif + /* Bind to a local port or source address if specified. */ + if (sflag || pflag) { + struct addrinfo ahints, *ares; + +#ifdef SO_BINDANY + /* try SO_BINDANY, but don't insist */ + setsockopt(s, SOL_SOCKET, SO_BINDANY, &on, sizeof(on)); +#endif + memset(&ahints, 0, sizeof(struct addrinfo)); + ahints.ai_family = res0->ai_family; + ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; + ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; + ahints.ai_flags = AI_PASSIVE; + if ((error = getaddrinfo(sflag, pflag, &ahints, &ares))) + errx(1, "getaddrinfo: %s", gai_strerror(error)); + + if (bind(s, (struct sockaddr *)ares->ai_addr, + ares->ai_addrlen) < 0) + err(1, "bind failed"); + freeaddrinfo(ares); + } + + set_common_sockopts(s); + + if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0) + break; + else if (vflag) + warn("connect to %s port %s (%s) failed", host, port, + uflag ? "udp" : "tcp"); + + close(s); + s = -1; + } while ((res0 = res0->ai_next) != NULL); + + freeaddrinfo(res); + + return (s); +} + +int +timeout_connect(int s, const struct sockaddr *name, socklen_t namelen) +{ + struct pollfd pfd; + socklen_t optlen; + int flags = 0, optval; + int ret; + + if (timeout != -1) { + flags = fcntl(s, F_GETFL, 0); + if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1) + err(1, "set non-blocking mode"); + } + + if ((ret = connect(s, name, namelen)) != 0 && errno == EINPROGRESS) { + pfd.fd = s; + pfd.events = POLLOUT; + if ((ret = poll(&pfd, 1, timeout)) == 1) { + optlen = sizeof(optval); + if ((ret = getsockopt(s, SOL_SOCKET, SO_ERROR, + &optval, &optlen)) == 0) { + errno = optval; + ret = optval == 0 ? 0 : -1; + } + } else if (ret == 0) { + errno = ETIMEDOUT; + ret = -1; + } else + err(1, "poll failed"); + } + + if (timeout != -1 && fcntl(s, F_SETFL, flags) == -1) + err(1, "restoring flags"); + + return (ret); +} + +/* + * local_listen() + * Returns a socket listening on a local port, binds to specified source + * address. Returns -1 on failure. + */ +int +local_listen(char *host, char *port, struct addrinfo hints) +{ + struct addrinfo *res, *res0; + int s, ret, x = 1; + int error; + + /* Allow nodename to be null. */ + hints.ai_flags |= AI_PASSIVE; + + /* + * In the case of binding to a wildcard address + * default to binding to an ipv4 address. + */ + if (host == NULL && hints.ai_family == AF_UNSPEC) + hints.ai_family = AF_INET; + + if ((error = getaddrinfo(host, port, &hints, &res))) + errx(1, "getaddrinfo: %s", gai_strerror(error)); + + res0 = res; + do { + if ((s = socket(res0->ai_family, res0->ai_socktype, + res0->ai_protocol)) < 0) + continue; + +#ifdef SO_RTABLE + if (rtableid >= 0 && (setsockopt(s, SOL_SOCKET, SO_RTABLE, + &rtableid, sizeof(rtableid)) == -1)) + err(1, "setsockopt SO_RTABLE"); +#endif +#ifdef SO_REUSEPORT + ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x)); + if (ret == -1) + err(1, "setsockopt"); +#endif + set_common_sockopts(s); + + if (bind(s, (struct sockaddr *)res0->ai_addr, + res0->ai_addrlen) == 0) + break; + + close(s); + s = -1; + } while ((res0 = res0->ai_next) != NULL); + + if (!uflag && s != -1) { + if (listen(s, 1) < 0) + err(1, "listen"); + } + + freeaddrinfo(res); + + return (s); +} + +/* + * readwrite() + * Loop that polls on the network file descriptor and stdin. + */ +void +readwrite(int net_fd) +{ + struct pollfd pfd[4]; + int stdin_fd = STDIN_FILENO; + int stdout_fd = STDOUT_FILENO; + unsigned char netinbuf[BUFSIZE]; + size_t netinbufpos = 0; + unsigned char stdinbuf[BUFSIZE]; + size_t stdinbufpos = 0; + int n, num_fds; + ssize_t ret; + + /* don't read from stdin if requested */ + if (dflag) + stdin_fd = -1; + + /* stdin */ + pfd[POLL_STDIN].fd = stdin_fd; + pfd[POLL_STDIN].events = POLLIN; + + /* network out */ + pfd[POLL_NETOUT].fd = net_fd; + pfd[POLL_NETOUT].events = 0; + + /* network in */ + pfd[POLL_NETIN].fd = net_fd; + pfd[POLL_NETIN].events = POLLIN; + + /* stdout */ + pfd[POLL_STDOUT].fd = stdout_fd; + pfd[POLL_STDOUT].events = 0; + + while (1) { + /* both inputs are gone, buffers are empty, we are done */ + if (pfd[POLL_STDIN].fd == -1 && pfd[POLL_NETIN].fd == -1 + && stdinbufpos == 0 && netinbufpos == 0) { + close(net_fd); + return; + } + /* both outputs are gone, we can't continue */ + if (pfd[POLL_NETOUT].fd == -1 && pfd[POLL_STDOUT].fd == -1) { + close(net_fd); + return; + } + /* listen and net in gone, queues empty, done */ + if (lflag && pfd[POLL_NETIN].fd == -1 + && stdinbufpos == 0 && netinbufpos == 0) { + close(net_fd); + return; + } + + /* help says -i is for "wait between lines sent". We read and + * write arbitrary amounts of data, and we don't want to start + * scanning for newlines, so this is as good as it gets */ + if (iflag) + sleep(iflag); + + /* poll */ + num_fds = poll(pfd, 4, timeout); + + /* treat poll errors */ + if (num_fds == -1) { + close(net_fd); + err(1, "polling error"); + } + + /* timeout happened */ + if (num_fds == 0) + return; + + /* treat socket error conditions */ + for (n = 0; n < 4; n++) { + if (pfd[n].revents & (POLLERR|POLLNVAL)) { + pfd[n].fd = -1; + } + } + /* reading is possible after HUP */ + if (pfd[POLL_STDIN].events & POLLIN && + pfd[POLL_STDIN].revents & POLLHUP && + ! (pfd[POLL_STDIN].revents & POLLIN)) + pfd[POLL_STDIN].fd = -1; + + if (pfd[POLL_NETIN].events & POLLIN && + pfd[POLL_NETIN].revents & POLLHUP && + ! (pfd[POLL_NETIN].revents & POLLIN)) + pfd[POLL_NETIN].fd = -1; + + if (pfd[POLL_NETOUT].revents & POLLHUP) { + if (Nflag) + shutdown(pfd[POLL_NETOUT].fd, SHUT_WR); + pfd[POLL_NETOUT].fd = -1; + } + /* if HUP, stop watching stdout */ + if (pfd[POLL_STDOUT].revents & POLLHUP) + pfd[POLL_STDOUT].fd = -1; + /* if no net out, stop watching stdin */ + if (pfd[POLL_NETOUT].fd == -1) + pfd[POLL_STDIN].fd = -1; + /* if no stdout, stop watching net in */ + if (pfd[POLL_STDOUT].fd == -1) { + if (pfd[POLL_NETIN].fd != -1) + shutdown(pfd[POLL_NETIN].fd, SHUT_RD); + pfd[POLL_NETIN].fd = -1; + } + + /* try to read from stdin */ + if (pfd[POLL_STDIN].revents & POLLIN && stdinbufpos < BUFSIZE) { + ret = fillbuf(pfd[POLL_STDIN].fd, stdinbuf, + &stdinbufpos); + /* error or eof on stdin - remove from pfd */ + if (ret == 0 || ret == -1) + pfd[POLL_STDIN].fd = -1; + /* read something - poll net out */ + if (stdinbufpos > 0) + pfd[POLL_NETOUT].events = POLLOUT; + /* filled buffer - remove self from polling */ + if (stdinbufpos == BUFSIZE) + pfd[POLL_STDIN].events = 0; + } + /* try to write to network */ + if (pfd[POLL_NETOUT].revents & POLLOUT && stdinbufpos > 0) { + ret = drainbuf(pfd[POLL_NETOUT].fd, stdinbuf, + &stdinbufpos); + if (ret == -1) + pfd[POLL_NETOUT].fd = -1; + /* buffer empty - remove self from polling */ + if (stdinbufpos == 0) + pfd[POLL_NETOUT].events = 0; + /* buffer no longer full - poll stdin again */ + if (stdinbufpos < BUFSIZE) + pfd[POLL_STDIN].events = POLLIN; + } + /* try to read from network */ + if (pfd[POLL_NETIN].revents & POLLIN && netinbufpos < BUFSIZE) { + ret = fillbuf(pfd[POLL_NETIN].fd, netinbuf, + &netinbufpos); + if (ret == -1) + pfd[POLL_NETIN].fd = -1; + /* eof on net in - remove from pfd */ + if (ret == 0) { + shutdown(pfd[POLL_NETIN].fd, SHUT_RD); + pfd[POLL_NETIN].fd = -1; + } + /* read something - poll stdout */ + if (netinbufpos > 0) + pfd[POLL_STDOUT].events = POLLOUT; + /* filled buffer - remove self from polling */ + if (netinbufpos == BUFSIZE) + pfd[POLL_NETIN].events = 0; + /* handle telnet */ + if (tflag) + atelnet(pfd[POLL_NETIN].fd, netinbuf, + netinbufpos); + } + /* try to write to stdout */ + if (pfd[POLL_STDOUT].revents & POLLOUT && netinbufpos > 0) { + ret = drainbuf(pfd[POLL_STDOUT].fd, netinbuf, + &netinbufpos); + if (ret == -1) + pfd[POLL_STDOUT].fd = -1; + /* buffer empty - remove self from polling */ + if (netinbufpos == 0) + pfd[POLL_STDOUT].events = 0; + /* buffer no longer full - poll net in again */ + if (netinbufpos < BUFSIZE) + pfd[POLL_NETIN].events = POLLIN; + } + + /* stdin gone and queue empty? */ + if (pfd[POLL_STDIN].fd == -1 && stdinbufpos == 0) { + if (pfd[POLL_NETOUT].fd != -1 && Nflag) + shutdown(pfd[POLL_NETOUT].fd, SHUT_WR); + pfd[POLL_NETOUT].fd = -1; + } + /* net in gone and queue empty? */ + if (pfd[POLL_NETIN].fd == -1 && netinbufpos == 0) { + pfd[POLL_STDOUT].fd = -1; + } + } +} + +ssize_t +drainbuf(int fd, unsigned char *buf, size_t *bufpos) +{ + ssize_t n; + ssize_t adjust; + + n = write(fd, buf, *bufpos); + /* don't treat EAGAIN, EINTR as error */ + if (n == -1 && (errno == EAGAIN || errno == EINTR)) + n = -2; + if (n <= 0) + return n; + /* adjust buffer */ + adjust = *bufpos - n; + if (adjust > 0) + memmove(buf, buf + n, adjust); + *bufpos -= n; + return n; +} + + +ssize_t +fillbuf(int fd, unsigned char *buf, size_t *bufpos) +{ + size_t num = BUFSIZE - *bufpos; + ssize_t n; + + n = read(fd, buf + *bufpos, num); + /* don't treat EAGAIN, EINTR as error */ + if (n == -1 && (errno == EAGAIN || errno == EINTR)) + n = -2; + if (n <= 0) + return n; + *bufpos += n; + return n; +} + +/* + * fdpass() + * Pass the connected file descriptor to stdout and exit. + */ +void +fdpass(int nfd) +{ +#if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR)) + struct msghdr msg; +#ifndef HAVE_ACCRIGHTS_IN_MSGHDR + union { + struct cmsghdr hdr; + char buf[CMSG_SPACE(sizeof(int))]; + } cmsgbuf; + struct cmsghdr *cmsg; +#endif + struct iovec vec; + char ch = '\0'; + struct pollfd pfd; + ssize_t r; + + memset(&msg, 0, sizeof(msg)); +#ifdef HAVE_ACCRIGHTS_IN_MSGHDR + msg.msg_accrights = (caddr_t)&nfd; + msg.msg_accrightslen = sizeof(nfd); +#else + memset(&cmsgbuf, 0, sizeof(cmsgbuf)); + msg.msg_control = (caddr_t)&cmsgbuf.buf; + msg.msg_controllen = sizeof(cmsgbuf.buf); + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + *(int *)CMSG_DATA(cmsg) = nfd; +#endif + + vec.iov_base = &ch; + vec.iov_len = 1; + msg.msg_iov = &vec; + msg.msg_iovlen = 1; + + bzero(&pfd, sizeof(pfd)); + pfd.fd = STDOUT_FILENO; + for (;;) { + r = sendmsg(STDOUT_FILENO, &msg, 0); + if (r == -1) { + if (errno == EAGAIN || errno == EINTR) { + pfd.events = POLLOUT; + if (poll(&pfd, 1, -1) == -1) + err(1, "poll"); + continue; + } + err(1, "sendmsg"); + } else if (r == -1) + errx(1, "sendmsg: unexpected return value %zd", r); + else + break; + } + exit(0); +#else + errx(1, "%s: file descriptor passing not supported", __func__); +#endif +} + +/* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */ +void +atelnet(int nfd, unsigned char *buf, unsigned int size) +{ + unsigned char *p, *end; + unsigned char obuf[4]; + + if (size < 3) + return; + end = buf + size - 2; + + for (p = buf; p < end; p++) { + if (*p != IAC) + continue; + + obuf[0] = IAC; + p++; + if ((*p == WILL) || (*p == WONT)) + obuf[1] = DONT; + else if ((*p == DO) || (*p == DONT)) + obuf[1] = WONT; + else + continue; + + p++; + obuf[2] = *p; + if (atomicio(vwrite, nfd, obuf, 3) != 3) + warn("Write Error!"); + } +} + +/* + * build_ports() + * Build an array of ports in portlist[], listing each port + * that we should try to connect to. + */ +void +build_ports(char *p) +{ + const char *errstr; + char *n; + int hi, lo, cp; + int x = 0; + + if ((n = strchr(p, '-')) != NULL) { + *n = '\0'; + n++; + + /* Make sure the ports are in order: lowest->highest. */ + hi = strtonum(n, 1, PORT_MAX, &errstr); + if (errstr) + errx(1, "port number %s: %s", errstr, n); + lo = strtonum(p, 1, PORT_MAX, &errstr); + if (errstr) + errx(1, "port number %s: %s", errstr, p); + + if (lo > hi) { + cp = hi; + hi = lo; + lo = cp; + } + + /* Load ports sequentially. */ + for (cp = lo; cp <= hi; cp++) { + portlist[x] = calloc(1, PORT_MAX_LEN); + if (portlist[x] == NULL) + errx(1, "calloc"); + snprintf(portlist[x], PORT_MAX_LEN, "%d", cp); + x++; + } + + /* Randomly swap ports. */ + if (rflag) { + int y; + char *c; + + for (x = 0; x <= (hi - lo); x++) { + y = (arc4random() & 0xFFFF) % (hi - lo); + c = portlist[x]; + portlist[x] = portlist[y]; + portlist[y] = c; + } + } + } else { + hi = strtonum(p, 1, PORT_MAX, &errstr); + if (errstr) + errx(1, "port number %s: %s", errstr, p); + portlist[0] = strdup(p); + if (portlist[0] == NULL) + errx(1, "strdup"); + } +} + +/* + * udptest() + * Do a few writes to see if the UDP port is there. + * Fails once PF state table is full. + */ +int +udptest(int s) +{ + int i, ret; + + for (i = 0; i <= 3; i++) { + if (write(s, "X", 1) == 1) + ret = 1; + else + ret = -1; + } + return (ret); +} + +void +set_common_sockopts(int s) +{ + int x = 1; + +#ifdef TCP_MD5SIG + if (Sflag) { + if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG, + &x, sizeof(x)) == -1) + err(1, "setsockopt"); + } +#endif + if (Dflag) { + if (setsockopt(s, SOL_SOCKET, SO_DEBUG, + &x, sizeof(x)) == -1) + err(1, "setsockopt"); + } + if (Tflag != -1) { + if (setsockopt(s, IPPROTO_IP, IP_TOS, + &Tflag, sizeof(Tflag)) == -1) + err(1, "set IP ToS"); + } + if (Iflag) { + if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, + &Iflag, sizeof(Iflag)) == -1) + err(1, "set TCP receive buffer size"); + } + if (Oflag) { + if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, + &Oflag, sizeof(Oflag)) == -1) + err(1, "set TCP send buffer size"); + } +} + +int +map_tos(char *s, int *val) +{ + /* DiffServ Codepoints and other TOS mappings */ + const struct toskeywords { + const char *keyword; + int val; + } *t, toskeywords[] = { + { "af11", IPTOS_DSCP_AF11 }, + { "af12", IPTOS_DSCP_AF12 }, + { "af13", IPTOS_DSCP_AF13 }, + { "af21", IPTOS_DSCP_AF21 }, + { "af22", IPTOS_DSCP_AF22 }, + { "af23", IPTOS_DSCP_AF23 }, + { "af31", IPTOS_DSCP_AF31 }, + { "af32", IPTOS_DSCP_AF32 }, + { "af33", IPTOS_DSCP_AF33 }, + { "af41", IPTOS_DSCP_AF41 }, + { "af42", IPTOS_DSCP_AF42 }, + { "af43", IPTOS_DSCP_AF43 }, + { "critical", IPTOS_PREC_CRITIC_ECP }, + { "cs0", IPTOS_DSCP_CS0 }, + { "cs1", IPTOS_DSCP_CS1 }, + { "cs2", IPTOS_DSCP_CS2 }, + { "cs3", IPTOS_DSCP_CS3 }, + { "cs4", IPTOS_DSCP_CS4 }, + { "cs5", IPTOS_DSCP_CS5 }, + { "cs6", IPTOS_DSCP_CS6 }, + { "cs7", IPTOS_DSCP_CS7 }, + { "ef", IPTOS_DSCP_EF }, + { "inetcontrol", IPTOS_PREC_INTERNETCONTROL }, + { "lowdelay", IPTOS_LOWDELAY }, + { "netcontrol", IPTOS_PREC_NETCONTROL }, + { "reliability", IPTOS_RELIABILITY }, + { "throughput", IPTOS_THROUGHPUT }, + { NULL, -1 }, + }; + + for (t = toskeywords; t->keyword != NULL; t++) { + if (strcmp(s, t->keyword) == 0) { + *val = t->val; + return (1); + } + } + + return (0); +} + +void +report_connect(const struct sockaddr *sa, socklen_t salen) +{ + char remote_host[NI_MAXHOST]; + char remote_port[NI_MAXSERV]; + int herr; + int flags = NI_NUMERICSERV; + + if (nflag) + flags |= NI_NUMERICHOST; + + if ((herr = getnameinfo(sa, salen, + remote_host, sizeof(remote_host), + remote_port, sizeof(remote_port), + flags)) != 0) { + if (herr == EAI_SYSTEM) + err(1, "getnameinfo"); + else + errx(1, "getnameinfo: %s", gai_strerror(herr)); + } + + fprintf(stderr, + "Connection from %s %s " + "received!\n", remote_host, remote_port); +} + +void +help(void) +{ + usage(0); + fprintf(stderr, "\tCommand Summary:\n\ + \t-4 Use IPv4\n\ + \t-6 Use IPv6\n\ + \t-D Enable the debug socket option\n\ + \t-d Detach from stdin\n\ + \t-F Pass socket fd\n\ + \t-h This help text\n\ + \t-I length TCP receive buffer length\n\ + \t-i secs\t Delay interval for lines sent, ports scanned\n\ + \t-k Keep inbound sockets open for multiple connects\n\ + \t-l Listen mode, for inbound connects\n\ + \t-N Shutdown the network socket after EOF on stdin\n\ + \t-n Suppress name/port resolutions\n\ + \t-O length TCP send buffer length\n\ + \t-P proxyuser\tUsername for proxy authentication\n\ + \t-p port\t Specify local port for remote connects\n\ + \t-r Randomize remote ports\n\ + \t-S Enable the TCP MD5 signature option\n\ + \t-s addr\t Local source address\n\ + \t-T toskeyword\tSet IP Type of Service\n\ + \t-t Answer TELNET negotiation\n\ + \t-U Use UNIX domain socket\n\ + \t-u UDP mode\n\ + \t-V rtable Specify alternate routing table\n\ + \t-v Verbose\n\ + \t-w secs\t Timeout for connects and final net reads\n\ + \t-X proto Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\ + \t-x addr[:port]\tSpecify proxy address and port\n\ + \t-z Zero-I/O mode [used for scanning]\n\ + Port numbers can be individual or ranges: lo-hi [inclusive]\n"); + exit(1); +} + +void +usage(int ret) +{ + fprintf(stderr, + "usage: nc [-46DdFhklNnrStUuvz] [-I length] [-i interval] [-O length]\n" + "\t [-P proxy_username] [-p source_port] [-s source] [-T ToS]\n" + "\t [-V rtable] [-w timeout] [-X proxy_protocol]\n" + "\t [-x proxy_address[:port]] [destination] [port]\n"); + if (ret) + exit(1); +} + +/* *** src/usr.bin/nc/socks.c *** */ + + +/* $OpenBSD: socks.c,v 1.20 2012/03/08 09:56:28 espie Exp $ */ + +/* + * Copyright (c) 1999 Niklas Hallqvist. All rights reserved. + * Copyright (c) 2004, 2005 Damien Miller. 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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define SOCKS_PORT "1080" +#define HTTP_PROXY_PORT "3128" +#define HTTP_MAXHDRS 64 +#define SOCKS_V5 5 +#define SOCKS_V4 4 +#define SOCKS_NOAUTH 0 +#define SOCKS_NOMETHOD 0xff +#define SOCKS_CONNECT 1 +#define SOCKS_IPV4 1 +#define SOCKS_DOMAIN 3 +#define SOCKS_IPV6 4 + +int remote_connect(const char *, const char *, struct addrinfo); +int socks_connect(const char *, const char *, struct addrinfo, + const char *, const char *, struct addrinfo, int, + const char *); + +static int +decode_addrport(const char *h, const char *p, struct sockaddr *addr, + socklen_t addrlen, int v4only, int numeric) +{ + int r; + struct addrinfo hints, *res; + + bzero(&hints, sizeof(hints)); + hints.ai_family = v4only ? PF_INET : PF_UNSPEC; + hints.ai_flags = numeric ? AI_NUMERICHOST : 0; + hints.ai_socktype = SOCK_STREAM; + r = getaddrinfo(h, p, &hints, &res); + /* Don't fatal when attempting to convert a numeric address */ + if (r != 0) { + if (!numeric) { + errx(1, "getaddrinfo(\"%.64s\", \"%.64s\"): %s", h, p, + gai_strerror(r)); + } + return (-1); + } + if (addrlen < res->ai_addrlen) { + freeaddrinfo(res); + errx(1, "internal error: addrlen < res->ai_addrlen"); + } + memcpy(addr, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + return (0); +} + +static int +proxy_read_line(int fd, char *buf, size_t bufsz) +{ + size_t off; + + for(off = 0;;) { + if (off >= bufsz) + errx(1, "proxy read too long"); + if (atomicio(read, fd, buf + off, 1) != 1) + err(1, "proxy read"); + /* Skip CR */ + if (buf[off] == '\r') + continue; + if (buf[off] == '\n') { + buf[off] = '\0'; + break; + } + off++; + } + return (off); +} + +static const char * +getproxypass(const char *proxyuser, const char *proxyhost) +{ + char prompt[512]; + static char pw[256]; + + snprintf(prompt, sizeof(prompt), "Proxy password for %s@%s: ", + proxyuser, proxyhost); + if (readpassphrase(prompt, pw, sizeof(pw), RPP_REQUIRE_TTY) == NULL) + errx(1, "Unable to read proxy passphrase"); + return (pw); +} + +int +socks_connect(const char *host, const char *port, + struct addrinfo hints __attribute__ ((__unused__)), + const char *proxyhost, const char *proxyport, struct addrinfo proxyhints, + int socksv, const char *proxyuser) +{ + int proxyfd, r, authretry = 0; + size_t hlen, wlen = 0; + unsigned char buf[1024]; + size_t cnt; + struct sockaddr_storage addr; + struct sockaddr_in *in4 = (struct sockaddr_in *)&addr; + struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&addr; + in_port_t serverport; + const char *proxypass = NULL; + + if (proxyport == NULL) + proxyport = (socksv == -1) ? HTTP_PROXY_PORT : SOCKS_PORT; + + /* Abuse API to lookup port */ + if (decode_addrport("0.0.0.0", port, (struct sockaddr *)&addr, + sizeof(addr), 1, 1) == -1) + errx(1, "unknown port \"%.64s\"", port); + serverport = in4->sin_port; + + again: + if (authretry++ > 3) + errx(1, "Too many authentication failures"); + + proxyfd = remote_connect(proxyhost, proxyport, proxyhints); + + if (proxyfd < 0) + return (-1); + + if (socksv == 5) { + if (decode_addrport(host, port, (struct sockaddr *)&addr, + sizeof(addr), 0, 1) == -1) + addr.ss_family = 0; /* used in switch below */ + + /* Version 5, one method: no authentication */ + buf[0] = SOCKS_V5; + buf[1] = 1; + buf[2] = SOCKS_NOAUTH; + cnt = atomicio(vwrite, proxyfd, buf, 3); + if (cnt != 3) + err(1, "write failed (%zu/3)", cnt); + + cnt = atomicio(read, proxyfd, buf, 2); + if (cnt != 2) + err(1, "read failed (%zu/3)", cnt); + + if (buf[1] == SOCKS_NOMETHOD) + errx(1, "authentication method negotiation failed"); + + switch (addr.ss_family) { + case 0: + /* Version 5, connect: domain name */ + + /* Max domain name length is 255 bytes */ + hlen = strlen(host); + if (hlen > 255) + errx(1, "host name too long for SOCKS5"); + buf[0] = SOCKS_V5; + buf[1] = SOCKS_CONNECT; + buf[2] = 0; + buf[3] = SOCKS_DOMAIN; + buf[4] = hlen; + memcpy(buf + 5, host, hlen); + memcpy(buf + 5 + hlen, &serverport, sizeof serverport); + wlen = 7 + hlen; + break; + case AF_INET: + /* Version 5, connect: IPv4 address */ + buf[0] = SOCKS_V5; + buf[1] = SOCKS_CONNECT; + buf[2] = 0; + buf[3] = SOCKS_IPV4; + memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr); + memcpy(buf + 8, &in4->sin_port, sizeof in4->sin_port); + wlen = 10; + break; + case AF_INET6: + /* Version 5, connect: IPv6 address */ + buf[0] = SOCKS_V5; + buf[1] = SOCKS_CONNECT; + buf[2] = 0; + buf[3] = SOCKS_IPV6; + memcpy(buf + 4, &in6->sin6_addr, sizeof in6->sin6_addr); + memcpy(buf + 20, &in6->sin6_port, + sizeof in6->sin6_port); + wlen = 22; + break; + default: + errx(1, "internal error: silly AF"); + } + + cnt = atomicio(vwrite, proxyfd, buf, wlen); + if (cnt != wlen) + err(1, "write failed (%zu/%zu)", cnt, wlen); + + cnt = atomicio(read, proxyfd, buf, 4); + if (cnt != 4) + err(1, "read failed (%zu/4)", cnt); + if (buf[1] != 0) + errx(1, "connection failed, SOCKS error %d", buf[1]); + switch (buf[3]) { + case SOCKS_IPV4: + cnt = atomicio(read, proxyfd, buf + 4, 6); + if (cnt != 6) + err(1, "read failed (%zu/6)", cnt); + break; + case SOCKS_IPV6: + cnt = atomicio(read, proxyfd, buf + 4, 18); + if (cnt != 18) + err(1, "read failed (%zu/18)", cnt); + break; + default: + errx(1, "connection failed, unsupported address type"); + } + } else if (socksv == 4) { + /* This will exit on lookup failure */ + decode_addrport(host, port, (struct sockaddr *)&addr, + sizeof(addr), 1, 0); + + /* Version 4 */ + buf[0] = SOCKS_V4; + buf[1] = SOCKS_CONNECT; /* connect */ + memcpy(buf + 2, &in4->sin_port, sizeof in4->sin_port); + memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr); + buf[8] = 0; /* empty username */ + wlen = 9; + + cnt = atomicio(vwrite, proxyfd, buf, wlen); + if (cnt != wlen) + err(1, "write failed (%zu/%zu)", cnt, wlen); + + cnt = atomicio(read, proxyfd, buf, 8); + if (cnt != 8) + err(1, "read failed (%zu/8)", cnt); + if (buf[1] != 90) + errx(1, "connection failed, SOCKS error %d", buf[1]); + } else if (socksv == -1) { + /* HTTP proxy CONNECT */ + + /* Disallow bad chars in hostname */ + if (strcspn(host, "\r\n\t []:") != strlen(host)) + errx(1, "Invalid hostname"); + + /* Try to be sane about numeric IPv6 addresses */ + if (strchr(host, ':') != NULL) { + r = snprintf(buf, sizeof(buf), + "CONNECT [%s]:%d HTTP/1.0\r\n", + host, ntohs(serverport)); + } else { + r = snprintf(buf, sizeof(buf), + "CONNECT %s:%d HTTP/1.0\r\n", + host, ntohs(serverport)); + } + if (r == -1 || (size_t)r >= sizeof(buf)) + errx(1, "hostname too long"); + r = strlen(buf); + + cnt = atomicio(vwrite, proxyfd, buf, r); + if (cnt != (size_t)r) + err(1, "write failed (%zu/%d)", cnt, r); + + if (authretry > 1) { + char resp[1024]; + + proxypass = getproxypass(proxyuser, proxyhost); + r = snprintf(buf, sizeof(buf), "%s:%s", + proxyuser, proxypass); + if (r == -1 || (size_t)r >= sizeof(buf) || + b64_ntop(buf, strlen(buf), resp, + sizeof(resp)) == -1) + errx(1, "Proxy username/password too long"); + r = snprintf(buf, sizeof(buf), "Proxy-Authorization: " + "Basic %s\r\n", resp); + if (r == -1 || (size_t)r >= sizeof(buf)) + errx(1, "Proxy auth response too long"); + r = strlen(buf); + if ((cnt = atomicio(vwrite, proxyfd, buf, r)) != (size_t)r) + err(1, "write failed (%zu/%d)", cnt, r); + } + + /* Terminate headers */ + if ((r = atomicio(vwrite, proxyfd, "\r\n", 2)) != 2) + err(1, "write failed (2/%d)", r); + + /* Read status reply */ + proxy_read_line(proxyfd, buf, sizeof(buf)); + if (proxyuser != NULL && + strncmp(buf, "HTTP/1.0 407 ", 12) == 0) { + if (authretry > 1) { + fprintf(stderr, "Proxy authentication " + "failed\n"); + } + close(proxyfd); + goto again; + } else if (strncmp(buf, "HTTP/1.0 200 ", 12) != 0 && + strncmp(buf, "HTTP/1.1 200 ", 12) != 0) + errx(1, "Proxy error: \"%s\"", buf); + + /* Headers continue until we hit an empty line */ + for (r = 0; r < HTTP_MAXHDRS; r++) { + proxy_read_line(proxyfd, buf, sizeof(buf)); + if (*buf == '\0') + break; + } + if (*buf != '\0') + errx(1, "Too many proxy headers received"); + } else + errx(1, "Unknown proxy protocol %d", socksv); + + return (proxyfd); +} + diff --git a/crypto/external/bsd/openssh/dist/regress/portnum.sh b/crypto/external/bsd/openssh/dist/regress/portnum.sh new file mode 100644 index 000000000..c56b869a3 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/portnum.sh @@ -0,0 +1,34 @@ +# $OpenBSD: portnum.sh,v 1.2 2013/05/17 10:34:30 dtucker Exp $ +# Placed in the Public Domain. + +tid="port number parsing" + +badport() { + port=$1 + verbose "$tid: invalid port $port" + if ${SSH} -F $OBJ/ssh_proxy -p $port somehost true 2>/dev/null ; then + fail "$tid accepted invalid port $port" + fi +} +goodport() { + port=$1 + verbose "$tid: valid port $port" + if ${SSH} -F $OBJ/ssh_proxy -p $port somehost true 2>/dev/null ; then + : + else + fail "$tid rejected valid port $port" + fi +} + +badport 0 +badport 65536 +badport 131073 +badport 2000blah +badport blah2000 + +goodport 1 +goodport 22 +goodport 2222 +goodport 22222 +goodport 65535 + diff --git a/crypto/external/bsd/openssh/dist/regress/principals-command.sh b/crypto/external/bsd/openssh/dist/regress/principals-command.sh new file mode 100644 index 000000000..b90a8cf2c --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/principals-command.sh @@ -0,0 +1,145 @@ +# $OpenBSD: principals-command.sh,v 1.1 2015/05/21 06:44:25 djm Exp $ +# Placed in the Public Domain. + +tid="authorized principals command" + +rm -f $OBJ/user_ca_key* $OBJ/cert_user_key* +cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak + +if test -z "$SUDO" ; then + echo "skipped (SUDO not set)" + echo "need SUDO to create file in /var/run, test won't work without" + exit 0 +fi + +# Establish a AuthorizedPrincipalsCommand in /var/run where it will have +# acceptable directory permissions. +PRINCIPALS_CMD="/var/run/principals_command_${LOGNAME}" +cat << _EOF | $SUDO sh -c "cat > '$PRINCIPALS_CMD'" +#!/bin/sh +test "x\$1" != "x${LOGNAME}" && exit 1 +test -f "$OBJ/authorized_principals_${LOGNAME}" && + exec cat "$OBJ/authorized_principals_${LOGNAME}" +_EOF +test $? -eq 0 || fatal "couldn't prepare principals command" +$SUDO chmod 0755 "$PRINCIPALS_CMD" + +# Create a CA key and a user certificate. +${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_ca_key || \ + fatal "ssh-keygen of user_ca_key failed" +${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/cert_user_key || \ + fatal "ssh-keygen of cert_user_key failed" +${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \ + -z $$ -n ${USER},mekmitasdigoat $OBJ/cert_user_key || \ + fatal "couldn't sign cert_user_key" + +if [ -x $PRINCIPALS_CMD ]; then + # Test explicitly-specified principals + for privsep in yes no ; do + _prefix="privsep $privsep" + + # Setup for AuthorizedPrincipalsCommand + rm -f $OBJ/authorized_keys_$USER + ( + cat $OBJ/sshd_proxy_bak + echo "UsePrivilegeSeparation $privsep" + echo "AuthorizedKeysFile none" + echo "AuthorizedPrincipalsCommand $PRINCIPALS_CMD %u" + echo "AuthorizedPrincipalsCommandUser ${LOGNAME}" + echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" + ) > $OBJ/sshd_proxy + + # XXX test missing command + # XXX test failing command + + # Empty authorized_principals + verbose "$tid: ${_prefix} empty authorized_principals" + echo > $OBJ/authorized_principals_$USER + ${SSH} -2i $OBJ/cert_user_key \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect succeeded unexpectedly" + fi + + # Wrong authorized_principals + verbose "$tid: ${_prefix} wrong authorized_principals" + echo gregorsamsa > $OBJ/authorized_principals_$USER + ${SSH} -2i $OBJ/cert_user_key \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect succeeded unexpectedly" + fi + + # Correct authorized_principals + verbose "$tid: ${_prefix} correct authorized_principals" + echo mekmitasdigoat > $OBJ/authorized_principals_$USER + ${SSH} -2i $OBJ/cert_user_key \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -ne 0 ]; then + fail "ssh cert connect failed" + fi + + # authorized_principals with bad key option + verbose "$tid: ${_prefix} authorized_principals bad key opt" + echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_$USER + ${SSH} -2i $OBJ/cert_user_key \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect succeeded unexpectedly" + fi + + # authorized_principals with command=false + verbose "$tid: ${_prefix} authorized_principals command=false" + echo 'command="false" mekmitasdigoat' > \ + $OBJ/authorized_principals_$USER + ${SSH} -2i $OBJ/cert_user_key \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect succeeded unexpectedly" + fi + + # authorized_principals with command=true + verbose "$tid: ${_prefix} authorized_principals command=true" + echo 'command="true" mekmitasdigoat' > \ + $OBJ/authorized_principals_$USER + ${SSH} -2i $OBJ/cert_user_key \ + -F $OBJ/ssh_proxy somehost false >/dev/null 2>&1 + if [ $? -ne 0 ]; then + fail "ssh cert connect failed" + fi + + # Setup for principals= key option + rm -f $OBJ/authorized_principals_$USER + ( + cat $OBJ/sshd_proxy_bak + echo "UsePrivilegeSeparation $privsep" + ) > $OBJ/sshd_proxy + + # Wrong principals list + verbose "$tid: ${_prefix} wrong principals key option" + ( + printf 'cert-authority,principals="gregorsamsa" ' + cat $OBJ/user_ca_key.pub + ) > $OBJ/authorized_keys_$USER + ${SSH} -2i $OBJ/cert_user_key \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect succeeded unexpectedly" + fi + + # Correct principals list + verbose "$tid: ${_prefix} correct principals key option" + ( + printf 'cert-authority,principals="mekmitasdigoat" ' + cat $OBJ/user_ca_key.pub + ) > $OBJ/authorized_keys_$USER + ${SSH} -2i $OBJ/cert_user_key \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -ne 0 ]; then + fail "ssh cert connect failed" + fi + done +else + echo "SKIPPED: $PRINCIPALS_COMMAND not executable " \ + "(/var/run mounted noexec?)" +fi diff --git a/crypto/external/bsd/openssh/dist/regress/proto-mismatch.sh b/crypto/external/bsd/openssh/dist/regress/proto-mismatch.sh new file mode 100644 index 000000000..9e8024beb --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/proto-mismatch.sh @@ -0,0 +1,21 @@ +# $OpenBSD: proto-mismatch.sh,v 1.4 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="protocol version mismatch" + +mismatch () +{ + server=$1 + client=$2 + banner=`echo ${client} | ${SSHD} -o "Protocol=${server}" -i -f ${OBJ}/sshd_proxy` + r=$? + trace "sshd prints ${banner}" + if [ $r -ne 255 ]; then + fail "sshd prints ${banner} and accepts connect with version ${client}" + fi +} + +mismatch 2 SSH-1.5-HALLO +if ssh_version 1; then + mismatch 1 SSH-2.0-HALLO +fi diff --git a/crypto/external/bsd/openssh/dist/regress/proto-version.sh b/crypto/external/bsd/openssh/dist/regress/proto-version.sh new file mode 100644 index 000000000..cf4946115 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/proto-version.sh @@ -0,0 +1,36 @@ +# $OpenBSD: proto-version.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="sshd version with different protocol combinations" + +# we just start sshd in inetd mode and check the banner +check_version () +{ + version=$1 + expect=$2 + banner=`printf '' | ${SSHD} -o "Protocol=${version}" -i -f ${OBJ}/sshd_proxy` + case ${banner} in + SSH-1.99-*) + proto=199 + ;; + SSH-2.0-*) + proto=20 + ;; + SSH-1.5-*) + proto=15 + ;; + *) + proto=0 + ;; + esac + if [ ${expect} -ne ${proto} ]; then + fail "wrong protocol version ${banner} for ${version}" + fi +} + +check_version 2 20 +if ssh_version 1; then + check_version 2,1 199 + check_version 1,2 199 + check_version 1 15 +fi diff --git a/crypto/external/bsd/openssh/dist/regress/proxy-connect.sh b/crypto/external/bsd/openssh/dist/regress/proxy-connect.sh new file mode 100644 index 000000000..f816962b5 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/proxy-connect.sh @@ -0,0 +1,31 @@ +# $OpenBSD: proxy-connect.sh,v 1.8 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="proxy connect" + +mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig + +for ps in no yes; do + cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy + echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy + + for p in ${SSH_PROTOCOLS}; do + for c in no yes; do + verbose "plain username protocol $p privsep=$ps comp=$c" + opts="-$p -oCompression=$c -F $OBJ/ssh_proxy" + SSH_CONNECTION=`${SSH} $opts 999.999.999.999 'echo $SSH_CONNECTION'` + if [ $? -ne 0 ]; then + fail "ssh proxyconnect protocol $p privsep=$ps comp=$c failed" + fi + if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then + fail "bad SSH_CONNECTION protocol $p privsep=$ps comp=$c" + fi + done + done +done + +for p in ${SSH_PROTOCOLS}; do + verbose "username with style protocol $p" + ${SSH} -$p -F $OBJ/ssh_proxy ${USER}:style@999.999.999.999 true || \ + fail "ssh proxyconnect protocol $p failed" +done diff --git a/crypto/external/bsd/openssh/dist/regress/putty-ciphers.sh b/crypto/external/bsd/openssh/dist/regress/putty-ciphers.sh new file mode 100644 index 000000000..724a98cc1 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/putty-ciphers.sh @@ -0,0 +1,26 @@ +# $OpenBSD: putty-ciphers.sh,v 1.4 2013/05/17 04:29:14 dtucker Exp $ +# Placed in the Public Domain. + +tid="putty ciphers" + +if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then + echo "putty interop tests not enabled" + exit 0 +fi + +for c in aes blowfish 3des arcfour aes128-ctr aes192-ctr aes256-ctr ; do + verbose "$tid: cipher $c" + cp ${OBJ}/.putty/sessions/localhost_proxy \ + ${OBJ}/.putty/sessions/cipher_$c + echo "Cipher=$c" >> ${OBJ}/.putty/sessions/cipher_$c + + rm -f ${COPY} + env HOME=$PWD ${PLINK} -load cipher_$c -batch -i putty.rsa2 \ + 127.0.0.1 cat ${DATA} > ${COPY} + if [ $? -ne 0 ]; then + fail "ssh cat $DATA failed" + fi + cmp ${DATA} ${COPY} || fail "corrupted copy" +done +rm -f ${COPY} + diff --git a/crypto/external/bsd/openssh/dist/regress/putty-kex.sh b/crypto/external/bsd/openssh/dist/regress/putty-kex.sh new file mode 100644 index 000000000..1844d6599 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/putty-kex.sh @@ -0,0 +1,23 @@ +# $OpenBSD: putty-kex.sh,v 1.3 2013/05/17 04:29:14 dtucker Exp $ +# Placed in the Public Domain. + +tid="putty KEX" + +if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then + echo "putty interop tests not enabled" + exit 0 +fi + +for k in dh-gex-sha1 dh-group1-sha1 dh-group14-sha1 ; do + verbose "$tid: kex $k" + cp ${OBJ}/.putty/sessions/localhost_proxy \ + ${OBJ}/.putty/sessions/kex_$k + echo "KEX=$k" >> ${OBJ}/.putty/sessions/kex_$k + + env HOME=$PWD ${PLINK} -load kex_$k -batch -i putty.rsa2 \ + 127.0.0.1 true + if [ $? -ne 0 ]; then + fail "KEX $k failed" + fi +done + diff --git a/crypto/external/bsd/openssh/dist/regress/putty-transfer.sh b/crypto/external/bsd/openssh/dist/regress/putty-transfer.sh new file mode 100644 index 000000000..aec0e04ee --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/putty-transfer.sh @@ -0,0 +1,41 @@ +# $OpenBSD: putty-transfer.sh,v 1.3 2013/05/17 04:29:14 dtucker Exp $ +# Placed in the Public Domain. + +tid="putty transfer data" + +if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then + echo "putty interop tests not enabled" + exit 0 +fi + +# XXX support protocol 1 too +for p in 2; do + for c in 0 1 ; do + verbose "$tid: proto $p compression $c" + rm -f ${COPY} + cp ${OBJ}/.putty/sessions/localhost_proxy \ + ${OBJ}/.putty/sessions/compression_$c + echo "Compression=$c" >> ${OBJ}/.putty/sessions/kex_$k + env HOME=$PWD ${PLINK} -load compression_$c -batch \ + -i putty.rsa$p 127.0.0.1 cat ${DATA} > ${COPY} + if [ $? -ne 0 ]; then + fail "ssh cat $DATA failed" + fi + cmp ${DATA} ${COPY} || fail "corrupted copy" + + for s in 10 100 1k 32k 64k 128k 256k; do + trace "proto $p compression $c dd-size ${s}" + rm -f ${COPY} + dd if=$DATA obs=${s} 2> /dev/null | \ + env HOME=$PWD ${PLINK} -load compression_$c \ + -batch -i putty.rsa$p 127.0.0.1 \ + "cat > ${COPY}" + if [ $? -ne 0 ]; then + fail "ssh cat $DATA failed" + fi + cmp $DATA ${COPY} || fail "corrupted copy" + done + done +done +rm -f ${COPY} + diff --git a/crypto/external/bsd/openssh/dist/regress/reconfigure.sh b/crypto/external/bsd/openssh/dist/regress/reconfigure.sh new file mode 100644 index 000000000..eecddd3c7 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/reconfigure.sh @@ -0,0 +1,47 @@ +# $OpenBSD: reconfigure.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="simple connect after reconfigure" + +# we need the full path to sshd for -HUP +if test "x$USE_VALGRIND" = "x" ; then + case $SSHD in + /*) + # full path is OK + ;; + *) + # otherwise make fully qualified + SSHD=$OBJ/$SSHD + esac +fi + +start_sshd + +trace "connect before restart" +for p in ${SSH_PROTOCOLS} ; do + ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true + if [ $? -ne 0 ]; then + fail "ssh connect with protocol $p failed before reconfigure" + fi +done + +PID=`$SUDO cat $PIDFILE` +rm -f $PIDFILE +$SUDO kill -HUP $PID + +trace "wait for sshd to restart" +i=0; +while [ ! -f $PIDFILE -a $i -lt 10 ]; do + i=`expr $i + 1` + sleep $i +done + +test -f $PIDFILE || fatal "sshd did not restart" + +trace "connect after restart" +for p in ${SSH_PROTOCOLS} ; do + ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true + if [ $? -ne 0 ]; then + fail "ssh connect with protocol $p failed after reconfigure" + fi +done diff --git a/crypto/external/bsd/openssh/dist/regress/reexec.sh b/crypto/external/bsd/openssh/dist/regress/reexec.sh new file mode 100644 index 000000000..5c0a7b46f --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/reexec.sh @@ -0,0 +1,73 @@ +# $OpenBSD: reexec.sh,v 1.8 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="reexec tests" + +SSHD_ORIG=$SSHD +SSHD_COPY=$OBJ/sshd + +# Start a sshd and then delete it +start_sshd_copy () +{ + cp $SSHD_ORIG $SSHD_COPY + SSHD=$SSHD_COPY + start_sshd + SSHD=$SSHD_ORIG +} + +# Do basic copy tests +copy_tests () +{ + rm -f ${COPY} + for p in ${SSH_PROTOCOLS} ; do + verbose "$tid: proto $p" + ${SSH} -nqo "Protocol=$p" -F $OBJ/ssh_config somehost \ + cat ${DATA} > ${COPY} + if [ $? -ne 0 ]; then + fail "ssh cat $DATA failed" + fi + cmp ${DATA} ${COPY} || fail "corrupted copy" + rm -f ${COPY} + done +} + +verbose "test config passing" + +cp $OBJ/sshd_config $OBJ/sshd_config.orig +start_sshd +echo "InvalidXXX=no" >> $OBJ/sshd_config + +copy_tests + +$SUDO kill `$SUDO cat $PIDFILE` +rm -f $PIDFILE + +cp $OBJ/sshd_config.orig $OBJ/sshd_config + +# cygwin can't fork a deleted binary +if [ "$os" != "cygwin" ]; then + +verbose "test reexec fallback" + +start_sshd_copy +rm -f $SSHD_COPY + +copy_tests + +$SUDO kill `$SUDO cat $PIDFILE` +rm -f $PIDFILE + +verbose "test reexec fallback without privsep" + +cp $OBJ/sshd_config.orig $OBJ/sshd_config +echo "UsePrivilegeSeparation=no" >> $OBJ/sshd_config + +start_sshd_copy +rm -f $SSHD_COPY + +copy_tests + +$SUDO kill `$SUDO cat $PIDFILE` +rm -f $PIDFILE + +fi diff --git a/crypto/external/bsd/openssh/dist/regress/rekey.sh b/crypto/external/bsd/openssh/dist/regress/rekey.sh new file mode 100644 index 000000000..0d4444d03 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/rekey.sh @@ -0,0 +1,170 @@ +# $OpenBSD: rekey.sh,v 1.16 2015/02/14 12:43:16 markus Exp $ +# Placed in the Public Domain. + +tid="rekey" + +LOG=${TEST_SSH_LOGFILE} + +rm -f ${LOG} +cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak + +# Test rekeying based on data volume only. +# Arguments will be passed to ssh. +ssh_data_rekeying() +{ + _kexopt=$1 ; shift + _opts="$@" + if ! test -z "$_kexopts" ; then + cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy + echo "$_kexopt" >> $OBJ/sshd_proxy + _opts="$_opts -o$_kexopt" + fi + rm -f ${COPY} ${LOG} + _opts="$_opts -oCompression=no" + ${SSH} <${DATA} $_opts -v -F $OBJ/ssh_proxy somehost "cat > ${COPY}" + if [ $? -ne 0 ]; then + fail "ssh failed ($@)" + fi + cmp ${DATA} ${COPY} || fail "corrupted copy ($@)" + n=`grep 'NEWKEYS sent' ${LOG} | wc -l` + n=`expr $n - 1` + trace "$n rekeying(s)" + if [ $n -lt 1 ]; then + fail "no rekeying occured ($@)" + fi +} + +increase_datafile_size 300 + +opts="" +for i in `${SSH} -Q kex`; do + opts="$opts KexAlgorithms=$i" +done +for i in `${SSH} -Q cipher`; do + opts="$opts Ciphers=$i" +done +for i in `${SSH} -Q mac`; do + opts="$opts MACs=$i" +done + +for opt in $opts; do + verbose "client rekey $opt" + ssh_data_rekeying "$opt" -oRekeyLimit=256k +done + +# AEAD ciphers are magical so test with all KexAlgorithms +if ${SSH} -Q cipher-auth | grep '^.*$' >/dev/null 2>&1 ; then + for c in `${SSH} -Q cipher-auth`; do + for kex in `${SSH} -Q kex`; do + verbose "client rekey $c $kex" + ssh_data_rekeying "KexAlgorithms=$kex" -oRekeyLimit=256k -oCiphers=$c + done + done +fi + +for s in 16 1k 128k 256k; do + verbose "client rekeylimit ${s}" + ssh_data_rekeying "" -oCompression=no -oRekeyLimit=$s +done + +for s in 5 10; do + verbose "client rekeylimit default ${s}" + rm -f ${COPY} ${LOG} + ${SSH} < ${DATA} -oCompression=no -oRekeyLimit="default $s" -F \ + $OBJ/ssh_proxy somehost "cat >${COPY};sleep $s;sleep 3" + if [ $? -ne 0 ]; then + fail "ssh failed" + fi + cmp ${DATA} ${COPY} || fail "corrupted copy" + n=`grep 'NEWKEYS sent' ${LOG} | wc -l` + n=`expr $n - 1` + trace "$n rekeying(s)" + if [ $n -lt 1 ]; then + fail "no rekeying occured" + fi +done + +for s in 5 10; do + verbose "client rekeylimit default ${s} no data" + rm -f ${COPY} ${LOG} + ${SSH} -oCompression=no -oRekeyLimit="default $s" -F \ + $OBJ/ssh_proxy somehost "sleep $s;sleep 3" + if [ $? -ne 0 ]; then + fail "ssh failed" + fi + n=`grep 'NEWKEYS sent' ${LOG} | wc -l` + n=`expr $n - 1` + trace "$n rekeying(s)" + if [ $n -lt 1 ]; then + fail "no rekeying occured" + fi +done + +for s in 16 1k 128k 256k; do + verbose "server rekeylimit ${s}" + cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy + echo "rekeylimit ${s}" >>$OBJ/sshd_proxy + rm -f ${COPY} ${LOG} + ${SSH} -oCompression=no -F $OBJ/ssh_proxy somehost "cat ${DATA}" \ + > ${COPY} + if [ $? -ne 0 ]; then + fail "ssh failed" + fi + cmp ${DATA} ${COPY} || fail "corrupted copy" + n=`grep 'NEWKEYS sent' ${LOG} | wc -l` + n=`expr $n - 1` + trace "$n rekeying(s)" + if [ $n -lt 1 ]; then + fail "no rekeying occured" + fi +done + +for s in 5 10; do + verbose "server rekeylimit default ${s} no data" + cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy + echo "rekeylimit default ${s}" >>$OBJ/sshd_proxy + rm -f ${COPY} ${LOG} + ${SSH} -oCompression=no -F $OBJ/ssh_proxy somehost "sleep $s;sleep 3" + if [ $? -ne 0 ]; then + fail "ssh failed" + fi + n=`grep 'NEWKEYS sent' ${LOG} | wc -l` + n=`expr $n - 1` + trace "$n rekeying(s)" + if [ $n -lt 1 ]; then + fail "no rekeying occured" + fi +done + +verbose "rekeylimit parsing" +for size in 16 1k 1K 1m 1M 1g 1G; do + for time in 1 1m 1M 1h 1H 1d 1D 1w 1W; do + case $size in + 16) bytes=16 ;; + 1k|1K) bytes=1024 ;; + 1m|1M) bytes=1048576 ;; + 1g|1G) bytes=1073741824 ;; + esac + case $time in + 1) seconds=1 ;; + 1m|1M) seconds=60 ;; + 1h|1H) seconds=3600 ;; + 1d|1D) seconds=86400 ;; + 1w|1W) seconds=604800 ;; + esac + + b=`$SUDO ${SSHD} -T -o "rekeylimit $size $time" -f $OBJ/sshd_proxy | \ + awk '/rekeylimit/{print $2}'` + s=`$SUDO ${SSHD} -T -o "rekeylimit $size $time" -f $OBJ/sshd_proxy | \ + awk '/rekeylimit/{print $3}'` + + if [ "$bytes" != "$b" ]; then + fatal "rekeylimit size: expected $bytes bytes got $b" + fi + if [ "$seconds" != "$s" ]; then + fatal "rekeylimit time: expected $time seconds got $s" + fi + done +done + +rm -f ${COPY} ${DATA} diff --git a/crypto/external/bsd/openssh/dist/regress/rsa_openssh.prv b/crypto/external/bsd/openssh/dist/regress/rsa_openssh.prv new file mode 100644 index 000000000..267555572 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/rsa_openssh.prv @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWgIBAAKBgQDsilwKcaKN6wSMNd1WgQ9+HRqQEkD0kCTVttrazGu0OhBU3Uko ++dFD1Ip0CxdXmN25JQWxOYF7h/Ocu8P3jzv3RTX87xKR0YzlXTLX+SLtF/ySebS3 +xWPrlfRUDhh03hR5V+8xxvvy9widPYKw/oItwGSueOsEq1LTczCDv2dAjQIDAQAB +An8nH5VzvHkMbSqJ6eOYDsVwomRvYbH5IEaYl1x6VATITNvAu9kUdQ4NsSpuMc+7 +Jj9gKZvmO1y2YCKc0P/iO+i/eV0L+yQh1Rw18jQZll+12T+LZrKRav03YNvMx0gN +wqWY48Kt6hv2/N/ebQzKRe79+D0t2cTh92hT7xENFLIBAkEBGnoGKFjAUkJCwO1V +mzpUqMHpRZVOrqP9hUmPjzNJ5oBPFGe4+h1hoSRFOAzaNuZt8ssbqaLCkzB8bfzj +qhZqAQJBANZekuUpp8iBLeLSagw5FkcPwPzq6zfExbhvsZXb8Bo/4SflNs4JHXwI +7SD9Z8aJLvM4uQ/5M70lblDMQ40i3o0CQQDIJvBYBFL5tlOgakq/O7yi+wt0L5BZ +9H79w5rCSAA0IHRoK/qI1urHiHC3f3vbbLk5UStfrqEaND/mm0shyNIBAkBLsYdC +/ctt5Bc0wUGK4Vl5bBmj9LtrrMJ4FpBpLwj/69BwCuKoK9XKZ0h73p6XHveCEGRg +PIlFX4MtaoLrwgU9AkBV2k4dgIws+X8YX65EsyyFjnlDqX4x0nSOjQB1msIKfHBr +dh5XLDBTTCxnKhMJ0Yx/opgOvf09XHBFwaQntR5i +-----END RSA PRIVATE KEY----- diff --git a/crypto/external/bsd/openssh/dist/regress/rsa_openssh.pub b/crypto/external/bsd/openssh/dist/regress/rsa_openssh.pub new file mode 100644 index 000000000..b504730f3 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/rsa_openssh.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDsilwKcaKN6wSMNd1WgQ9+HRqQEkD0kCTVttrazGu0OhBU3Uko+dFD1Ip0CxdXmN25JQWxOYF7h/Ocu8P3jzv3RTX87xKR0YzlXTLX+SLtF/ySebS3xWPrlfRUDhh03hR5V+8xxvvy9widPYKw/oItwGSueOsEq1LTczCDv2dAjQ== diff --git a/crypto/external/bsd/openssh/dist/regress/rsa_ssh2.prv b/crypto/external/bsd/openssh/dist/regress/rsa_ssh2.prv new file mode 100644 index 000000000..1ece3d7de --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/rsa_ssh2.prv @@ -0,0 +1,16 @@ +---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ---- +Subject: ssh-keygen test +Comment: "1024-bit rsa, Sat Jun 23 2001 12:21:26 -0400" +P2/56wAAAi4AAAA3aWYtbW9kbntzaWdue3JzYS1wa2NzMS1zaGExfSxlbmNyeXB0e3JzYS +1wa2NzMXYyLW9hZXB9fQAAAARub25lAAAB3wAAAdsAAAARAQABAAAD9icflXO8eQxtKonp +45gOxXCiZG9hsfkgRpiXXHpUBMhM28C72RR1Dg2xKm4xz7smP2Apm+Y7XLZgIpzQ/+I76L +95XQv7JCHVHDXyNBmWX7XZP4tmspFq/Tdg28zHSA3CpZjjwq3qG/b8395tDMpF7v34PS3Z +xOH3aFPvEQ0UsgEAAAQA7IpcCnGijesEjDXdVoEPfh0akBJA9JAk1bba2sxrtDoQVN1JKP +nRQ9SKdAsXV5jduSUFsTmBe4fznLvD948790U1/O8SkdGM5V0y1/ki7Rf8knm0t8Vj65X0 +VA4YdN4UeVfvMcb78vcInT2CsP6CLcBkrnjrBKtS03Mwg79nQI0AAAH/VdpOHYCMLPl/GF ++uRLMshY55Q6l+MdJ0jo0AdZrCCnxwa3YeVywwU0wsZyoTCdGMf6KYDr39PVxwRcGkJ7Ue +YgAAAgDWXpLlKafIgS3i0moMORZHD8D86us3xMW4b7GV2/AaP+En5TbOCR18CO0g/WfGiS +7zOLkP+TO9JW5QzEONIt6NAAACAQEaegYoWMBSQkLA7VWbOlSowelFlU6uo/2FSY+PM0nm +gE8UZ7j6HWGhJEU4DNo25m3yyxuposKTMHxt/OOqFmoB +---- END SSH2 ENCRYPTED PRIVATE KEY ---- +--- diff --git a/crypto/external/bsd/openssh/dist/regress/scp-ssh-wrapper.sh b/crypto/external/bsd/openssh/dist/regress/scp-ssh-wrapper.sh new file mode 100644 index 000000000..59f1ff63e --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/scp-ssh-wrapper.sh @@ -0,0 +1,59 @@ +#!/bin/sh +# $OpenBSD: scp-ssh-wrapper.sh,v 1.3 2014/01/26 10:49:17 djm Exp $ +# Placed in the Public Domain. + +printname () { + NAME=$1 + save_IFS=$IFS + IFS=/ + set -- `echo "$NAME"` + IFS="$save_IFS" + while [ $# -ge 1 ] ; do + if [ "x$1" != "x" ]; then + echo "D0755 0 $1" + fi + shift; + done +} + +# Discard all but last argument. We use arg later. +while test "x$1" != "x"; do + arg="$1" + shift +done + +BAD="../../../../../../../../../../../../../${DIR}/dotpathdir" + +case "$SCPTESTMODE" in +badserver_0) + echo "D0755 0 /${DIR}/rootpathdir" + echo "C755 2 rootpathfile" + echo "X" + ;; +badserver_1) + echo "D0755 0 $BAD" + echo "C755 2 file" + echo "X" + ;; +badserver_2) + echo "D0755 0 $BAD" + echo "C755 2 file" + echo "X" + ;; +badserver_3) + printname $BAD + echo "C755 2 file" + echo "X" + ;; +badserver_4) + printname $BAD + echo "D0755 0 .." + echo "C755 2 file" + echo "X" + ;; +*) + set -- $arg + shift + exec $SCP "$@" + ;; +esac diff --git a/crypto/external/bsd/openssh/dist/regress/scp.sh b/crypto/external/bsd/openssh/dist/regress/scp.sh new file mode 100644 index 000000000..57cc77066 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/scp.sh @@ -0,0 +1,126 @@ +# $OpenBSD: scp.sh,v 1.10 2014/01/26 10:49:17 djm Exp $ +# Placed in the Public Domain. + +tid="scp" + +#set -x + +# Figure out if diff understands "-N" +if diff -N ${SRC}/scp.sh ${SRC}/scp.sh 2>/dev/null; then + DIFFOPT="-rN" +else + DIFFOPT="-r" +fi + +COPY2=${OBJ}/copy2 +DIR=${COPY}.dd +DIR2=${COPY}.dd2 + +SRC=`dirname ${SCRIPT}` +cp ${SRC}/scp-ssh-wrapper.sh ${OBJ}/scp-ssh-wrapper.scp +chmod 755 ${OBJ}/scp-ssh-wrapper.scp +scpopts="-q -S ${OBJ}/scp-ssh-wrapper.scp" +export SCP # used in scp-ssh-wrapper.scp + +scpclean() { + rm -rf ${COPY} ${COPY2} ${DIR} ${DIR2} + mkdir ${DIR} ${DIR2} +} + +verbose "$tid: simple copy local file to local file" +scpclean +$SCP $scpopts ${DATA} ${COPY} || fail "copy failed" +cmp ${DATA} ${COPY} || fail "corrupted copy" + +verbose "$tid: simple copy local file to remote file" +scpclean +$SCP $scpopts ${DATA} somehost:${COPY} || fail "copy failed" +cmp ${DATA} ${COPY} || fail "corrupted copy" + +verbose "$tid: simple copy remote file to local file" +scpclean +$SCP $scpopts somehost:${DATA} ${COPY} || fail "copy failed" +cmp ${DATA} ${COPY} || fail "corrupted copy" + +verbose "$tid: simple copy local file to remote dir" +scpclean +cp ${DATA} ${COPY} +$SCP $scpopts ${COPY} somehost:${DIR} || fail "copy failed" +cmp ${COPY} ${DIR}/copy || fail "corrupted copy" + +verbose "$tid: simple copy local file to local dir" +scpclean +cp ${DATA} ${COPY} +$SCP $scpopts ${COPY} ${DIR} || fail "copy failed" +cmp ${COPY} ${DIR}/copy || fail "corrupted copy" + +verbose "$tid: simple copy remote file to local dir" +scpclean +cp ${DATA} ${COPY} +$SCP $scpopts somehost:${COPY} ${DIR} || fail "copy failed" +cmp ${COPY} ${DIR}/copy || fail "corrupted copy" + +verbose "$tid: recursive local dir to remote dir" +scpclean +rm -rf ${DIR2} +cp ${DATA} ${DIR}/copy +$SCP $scpopts -r ${DIR} somehost:${DIR2} || fail "copy failed" +diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy" + +verbose "$tid: recursive local dir to local dir" +scpclean +rm -rf ${DIR2} +cp ${DATA} ${DIR}/copy +$SCP $scpopts -r ${DIR} ${DIR2} || fail "copy failed" +diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy" + +verbose "$tid: recursive remote dir to local dir" +scpclean +rm -rf ${DIR2} +cp ${DATA} ${DIR}/copy +$SCP $scpopts -r somehost:${DIR} ${DIR2} || fail "copy failed" +diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy" + +verbose "$tid: shell metacharacters" +scpclean +(cd ${DIR} && \ +touch '`touch metachartest`' && \ +$SCP $scpopts *metachar* ${DIR2} 2>/dev/null; \ +[ ! -f metachartest ] ) || fail "shell metacharacters" + +if [ ! -z "$SUDO" ]; then + verbose "$tid: skipped file after scp -p with failed chown+utimes" + scpclean + cp -p ${DATA} ${DIR}/copy + cp -p ${DATA} ${DIR}/copy2 + cp ${DATA} ${DIR2}/copy + chmod 660 ${DIR2}/copy + $SUDO chown root ${DIR2}/copy + $SCP -p $scpopts somehost:${DIR}/\* ${DIR2} >/dev/null 2>&1 + $SUDO diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy" + $SUDO rm ${DIR2}/copy +fi + +for i in 0 1 2 3 4; do + verbose "$tid: disallow bad server #$i" + SCPTESTMODE=badserver_$i + export DIR SCPTESTMODE + scpclean + $SCP $scpopts somehost:${DATA} ${DIR} >/dev/null 2>/dev/null + [ -d {$DIR}/rootpathdir ] && fail "allows dir relative to root dir" + [ -d ${DIR}/dotpathdir ] && fail "allows dir creation in non-recursive mode" + + scpclean + $SCP -r $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null + [ -d ${DIR}/dotpathdir ] && fail "allows dir creation outside of subdir" +done + +verbose "$tid: detect non-directory target" +scpclean +echo a > ${COPY} +echo b > ${COPY2} +$SCP $scpopts ${DATA} ${COPY} ${COPY2} +cmp ${COPY} ${COPY2} >/dev/null && fail "corrupt target" + +scpclean +rm -f ${OBJ}/scp-ssh-wrapper.scp diff --git a/crypto/external/bsd/openssh/dist/regress/setuid-allowed.c b/crypto/external/bsd/openssh/dist/regress/setuid-allowed.c new file mode 100644 index 000000000..676d2661c --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/setuid-allowed.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* $OpenBSD$ */ + +#include "includes.h" + +#include +#ifdef HAVE_SYS_STATVFS_H +# include +#endif +#include +#include +#include + +void +usage(void) +{ + fprintf(stderr, "check-setuid [path]\n"); + exit(1); +} + +int +main(int argc, char **argv) +{ + const char *path = "."; + struct statvfs sb; + + if (argc > 2) + usage(); + else if (argc == 2) + path = argv[1]; + + if (statvfs(path, &sb) != 0) { + /* Don't return an error if the host doesn't support statvfs */ + if (errno == ENOSYS) + return 0; + fprintf(stderr, "statvfs for \"%s\" failed: %s\n", + path, strerror(errno)); + } + return (sb.f_flag & ST_NOSUID) ? 1 : 0; +} + + diff --git a/crypto/external/bsd/openssh/dist/regress/sftp-badcmds.sh b/crypto/external/bsd/openssh/dist/regress/sftp-badcmds.sh new file mode 100644 index 000000000..7f85c4f22 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/sftp-badcmds.sh @@ -0,0 +1,65 @@ +# $OpenBSD: sftp-badcmds.sh,v 1.6 2013/05/17 10:26:26 dtucker Exp $ +# Placed in the Public Domain. + +tid="sftp invalid commands" + +DATA2=/bin/sh${EXEEXT} +NONEXIST=/NONEXIST.$$ +GLOBFILES=`(cd /bin;echo l*)` + +rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd + +rm -f ${COPY} +verbose "$tid: get nonexistent" +echo "get $NONEXIST $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get nonexistent failed" +test -f ${COPY} && fail "existing copy after get nonexistent" + +rm -f ${COPY}.dd/* +verbose "$tid: glob get to nonexistent directory" +echo "get /bin/l* $NONEXIST" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get nonexistent failed" +for x in $GLOBFILES; do + test -f ${COPY}.dd/$x && fail "existing copy after get nonexistent" +done + +rm -f ${COPY} +verbose "$tid: put nonexistent" +echo "put $NONEXIST $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "put nonexistent failed" +test -f ${COPY} && fail "existing copy after put nonexistent" + +rm -f ${COPY}.dd/* +verbose "$tid: glob put to nonexistent directory" +echo "put /bin/l* ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "put nonexistent failed" +for x in $GLOBFILES; do + test -f ${COPY}.dd/$x && fail "existing copy after nonexistent" +done + +rm -f ${COPY} +verbose "$tid: rename nonexistent" +echo "rename $NONEXIST ${COPY}.1" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "rename nonexist failed" +test -f ${COPY}.1 && fail "file exists after rename nonexistent" + +rm -rf ${COPY} ${COPY}.dd +cp $DATA $COPY +mkdir ${COPY}.dd +verbose "$tid: rename target exists (directory)" +echo "rename $COPY ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "rename target exists (directory) failed" +test -f ${COPY} || fail "oldname missing after rename target exists (directory)" +test -d ${COPY}.dd || fail "newname missing after rename target exists (directory)" +cmp $DATA ${COPY} >/dev/null 2>&1 || fail "corrupted oldname after rename target exists (directory)" + +rm -f ${COPY}.dd/* +rm -rf ${COPY} +cp ${DATA2} ${COPY} +verbose "$tid: glob put files to local file" +echo "put /bin/l* $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 +cmp ${DATA2} ${COPY} || fail "put successed when it should have failed" + +rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd + + diff --git a/crypto/external/bsd/openssh/dist/regress/sftp-batch.sh b/crypto/external/bsd/openssh/dist/regress/sftp-batch.sh new file mode 100644 index 000000000..41011549b --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/sftp-batch.sh @@ -0,0 +1,55 @@ +# $OpenBSD: sftp-batch.sh,v 1.5 2013/05/17 04:29:14 dtucker Exp $ +# Placed in the Public Domain. + +tid="sftp batchfile" + +BATCH=${OBJ}/sftp.bb + +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 -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "good commands failed" + +verbose "$tid: bad commands" +${SFTP} -b ${BATCH}.fail.1 -D ${SFTPSERVER} >/dev/null 2>&1 \ + && fail "bad commands succeeded" + +verbose "$tid: comments and blanks" +${SFTP} -b ${BATCH}.pass.2 -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "comments & blanks failed" + +verbose "$tid: junk command" +${SFTP} -b ${BATCH}.fail.2 -D ${SFTPSERVER} >/dev/null 2>&1 \ + && fail "junk command succeeded" + +rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${BATCH}.* + + diff --git a/crypto/external/bsd/openssh/dist/regress/sftp-chroot.sh b/crypto/external/bsd/openssh/dist/regress/sftp-chroot.sh new file mode 100644 index 000000000..23f7456e8 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/sftp-chroot.sh @@ -0,0 +1,26 @@ +# $OpenBSD: sftp-chroot.sh,v 1.4 2014/01/20 00:00:30 dtucker Exp $ +# Placed in the Public Domain. + +tid="sftp in chroot" + +CHROOT=/var/run +FILENAME=testdata_${USER} +PRIVDATA=${CHROOT}/${FILENAME} + +if [ -z "$SUDO" ]; then + echo "skipped: need SUDO to create file in /var/run, test won't work without" + exit 0 +fi + +$SUDO sh -c "echo mekmitastdigoat > $PRIVDATA" || \ + fatal "create $PRIVDATA failed" + +start_sshd -oChrootDirectory=$CHROOT -oForceCommand="internal-sftp -d /" + +verbose "test $tid: get" +${SFTP} -S "$SSH" -F $OBJ/ssh_config host:/${FILENAME} $COPY \ + >>$TEST_REGRESS_LOGFILE 2>&1 || \ + fatal "Fetch ${FILENAME} failed" +cmp $PRIVDATA $COPY || fail "$PRIVDATA $COPY differ" + +$SUDO rm $PRIVDATA diff --git a/crypto/external/bsd/openssh/dist/regress/sftp-cmds.sh b/crypto/external/bsd/openssh/dist/regress/sftp-cmds.sh new file mode 100644 index 000000000..aad7fcac2 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/sftp-cmds.sh @@ -0,0 +1,232 @@ +# $OpenBSD: sftp-cmds.sh,v 1.14 2013/06/21 02:26:26 djm Exp $ +# Placed in the Public Domain. + +# XXX - TODO: +# - chmod / chown / chgrp +# - -p flag for get & put + +tid="sftp commands" + +# test that these files are readable! +for i in `(cd /bin;echo l*)` +do + if [ -r $i ]; then + GLOBFILES="$GLOBFILES $i" + fi +done + +# Path with embedded quote +QUOTECOPY=${COPY}".\"blah\"" +QUOTECOPY_ARG=${COPY}'.\"blah\"' +# File with spaces +SPACECOPY="${COPY} this has spaces.txt" +SPACECOPY_ARG="${COPY}\ this\ has\ spaces.txt" +# File with glob metacharacters +GLOBMETACOPY="${COPY} [metachar].txt" + +rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2 +mkdir ${COPY}.dd + +verbose "$tid: lls" +(echo "lcd ${OBJ}" ; echo "lls") | ${SFTP} -D ${SFTPSERVER} 2>&1 | \ + grep copy.dd >/dev/null 2>&1 || fail "lls failed" + +verbose "$tid: lls w/path" +echo "lls ${OBJ}" | ${SFTP} -D ${SFTPSERVER} 2>&1 | \ + grep copy.dd >/dev/null 2>&1 || fail "lls w/path failed" + +verbose "$tid: ls" +echo "ls ${OBJ}" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "ls failed" +# XXX always successful + +verbose "$tid: shell" +echo "!echo hi there" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "shell failed" +# XXX always successful + +verbose "$tid: pwd" +echo "pwd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "pwd failed" +# XXX always successful + +verbose "$tid: lpwd" +echo "lpwd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "lpwd failed" +# XXX always successful + +verbose "$tid: quit" +echo "quit" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "quit failed" +# XXX always successful + +verbose "$tid: help" +echo "help" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "help failed" +# XXX always successful + +rm -f ${COPY} +verbose "$tid: get" +echo "get $DATA $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get failed" +cmp $DATA ${COPY} || fail "corrupted copy after get" + +rm -f ${COPY} +verbose "$tid: get quoted" +echo "get \"$DATA\" $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get failed" +cmp $DATA ${COPY} || fail "corrupted copy after get" + +if [ "$os" != "cygwin" ]; then +rm -f ${QUOTECOPY} +cp $DATA ${QUOTECOPY} +verbose "$tid: get filename with quotes" +echo "get \"$QUOTECOPY_ARG\" ${COPY}" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get failed" +cmp ${COPY} ${QUOTECOPY} || fail "corrupted copy after get with quotes" +rm -f ${QUOTECOPY} ${COPY} +fi + +rm -f "$SPACECOPY" ${COPY} +cp $DATA "$SPACECOPY" +verbose "$tid: get filename with spaces" +echo "get ${SPACECOPY_ARG} ${COPY}" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get failed" +cmp ${COPY} "$SPACECOPY" || fail "corrupted copy after get with spaces" + +rm -f "$GLOBMETACOPY" ${COPY} +cp $DATA "$GLOBMETACOPY" +verbose "$tid: get filename with glob metacharacters" +echo "get \"${GLOBMETACOPY}\" ${COPY}" | \ + ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "get failed" +cmp ${COPY} "$GLOBMETACOPY" || \ + fail "corrupted copy after get with glob metacharacters" + +rm -f ${COPY}.dd/* +verbose "$tid: get to directory" +echo "get $DATA ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get failed" +cmp $DATA ${COPY}.dd/$DATANAME || fail "corrupted copy after get" + +rm -f ${COPY}.dd/* +verbose "$tid: glob get to directory" +echo "get /bin/l* ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get failed" +for x in $GLOBFILES; do + cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after get" +done + +rm -f ${COPY}.dd/* +verbose "$tid: get to local dir" +(echo "lcd ${COPY}.dd"; echo "get $DATA" ) | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get failed" +cmp $DATA ${COPY}.dd/$DATANAME || fail "corrupted copy after get" + +rm -f ${COPY}.dd/* +verbose "$tid: glob get to local dir" +(echo "lcd ${COPY}.dd"; echo "get /bin/l*") | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get failed" +for x in $GLOBFILES; do + cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after get" +done + +rm -f ${COPY} +verbose "$tid: put" +echo "put $DATA $COPY" | \ + ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed" +cmp $DATA ${COPY} || fail "corrupted copy after put" + +if [ "$os" != "cygwin" ]; then +rm -f ${QUOTECOPY} +verbose "$tid: put filename with quotes" +echo "put $DATA \"$QUOTECOPY_ARG\"" | \ + ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed" +cmp $DATA ${QUOTECOPY} || fail "corrupted copy after put with quotes" +fi + +rm -f "$SPACECOPY" +verbose "$tid: put filename with spaces" +echo "put $DATA ${SPACECOPY_ARG}" | \ + ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed" +cmp $DATA "$SPACECOPY" || fail "corrupted copy after put with spaces" + +rm -f ${COPY}.dd/* +verbose "$tid: put to directory" +echo "put $DATA ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "put failed" +cmp $DATA ${COPY}.dd/$DATANAME || fail "corrupted copy after put" + +rm -f ${COPY}.dd/* +verbose "$tid: glob put to directory" +echo "put /bin/l? ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "put failed" +for x in $GLOBFILES; do + cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after put" +done + +rm -f ${COPY}.dd/* +verbose "$tid: put to local dir" +(echo "cd ${COPY}.dd"; echo "put $DATA") | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "put failed" +cmp $DATA ${COPY}.dd/$DATANAME || fail "corrupted copy after put" + +rm -f ${COPY}.dd/* +verbose "$tid: glob put to local dir" +(echo "cd ${COPY}.dd"; echo "put /bin/l?") | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "put failed" +for x in $GLOBFILES; do + cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after put" +done + +verbose "$tid: rename" +echo "rename $COPY ${COPY}.1" | ${SFTP} -D ${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: rename directory" +echo "rename ${COPY}.dd ${COPY}.dd2" | \ + ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || \ + fail "rename directory failed" +test -d ${COPY}.dd && fail "oldname exists after rename directory" +test -d ${COPY}.dd2 || fail "missing newname after rename directory" + +verbose "$tid: ln" +echo "ln ${COPY}.1 ${COPY}.2" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "ln failed" +test -f ${COPY}.2 || fail "missing file after ln" +cmp ${COPY}.1 ${COPY}.2 || fail "created file is not equal after ln" + +verbose "$tid: ln -s" +rm -f ${COPY}.2 +echo "ln -s ${COPY}.1 ${COPY}.2" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "ln -s failed" +test -h ${COPY}.2 || fail "missing file after ln -s" + +verbose "$tid: mkdir" +echo "mkdir ${COPY}.dd" | ${SFTP} -D ${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} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "chdir failed" + +verbose "$tid: rmdir" +echo "rmdir ${COPY}.dd" | ${SFTP} -D ${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} -D ${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} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "lchdir failed" + +rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2 +rm -rf ${QUOTECOPY} "$SPACECOPY" "$GLOBMETACOPY" + + diff --git a/crypto/external/bsd/openssh/dist/regress/sftp-glob.sh b/crypto/external/bsd/openssh/dist/regress/sftp-glob.sh new file mode 100644 index 000000000..8d4df2c98 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/sftp-glob.sh @@ -0,0 +1,75 @@ +# $OpenBSD: sftp-glob.sh,v 1.4 2009/08/13 01:11:55 djm Exp $ +# Placed in the Public Domain. + +tid="sftp glob" + +config_defined FILESYSTEM_NO_BACKSLASH && nobs="not supported on this platform" + +sftp_ls() { + target=$1 + errtag=$2 + expected=$3 + unexpected=$4 + skip=$5 + if test "x$skip" != "x" ; then + verbose "$tid: $errtag (skipped: $skip)" + return + fi + verbose "$tid: $errtag" + printf "ls -l %s" "${target}" | \ + ${SFTP} -b - -D ${SFTPSERVER} 2>/dev/null | \ + grep -v "^sftp>" > ${RESULTS} + if [ $? -ne 0 ]; then + fail "$errtag failed" + fi + if test "x$expected" != "x" ; then + if fgrep "$expected" ${RESULTS} >/dev/null 2>&1 ; then + : + else + fail "$expected missing from $errtag results" + fi + fi + if test "x$unexpected" != "x" && \ + fgrep "$unexpected" ${RESULTS} >/dev/null 2>&1 ; then + fail "$unexpected present in $errtag results" + fi + rm -f ${RESULTS} +} + +BASE=${OBJ}/glob +RESULTS=${OBJ}/results +DIR=${BASE}/dir +DATA=${DIR}/file + +GLOB1="${DIR}/g-wild*" +GLOB2="${DIR}/g-wildx" +QUOTE="${DIR}/g-quote\"" +SLASH="${DIR}/g-sl\\ash" +ESLASH="${DIR}/g-slash\\" +QSLASH="${DIR}/g-qs\\\"" +SPACE="${DIR}/g-q space" + +rm -rf ${BASE} +mkdir -p ${DIR} +touch "${DATA}" "${GLOB1}" "${GLOB2}" "${QUOTE}" "${SPACE}" +test "x$nobs" = "x" && touch "${QSLASH}" "${ESLASH}" "${SLASH}" + +# target message expected unexpected +sftp_ls "${DIR}/fil*" "file glob" "${DATA}" "" +sftp_ls "${BASE}/d*" "dir glob" "`basename ${DATA}`" "" +sftp_ls "${DIR}/g-wild\"*\"" "quoted glob" "g-wild*" "g-wildx" +sftp_ls "${DIR}/g-wild\*" "escaped glob" "g-wild*" "g-wildx" +sftp_ls "${DIR}/g-quote\\\"" "escaped quote" "g-quote\"" "" +sftp_ls "\"${DIR}/g-quote\\\"\"" "quoted quote" "g-quote\"" "" +sftp_ls "'${DIR}/g-quote\"'" "single-quoted quote" "g-quote\"" "" +sftp_ls "${DIR}/g-q\\ space" "escaped space" "g-q space" "" +sftp_ls "'${DIR}/g-q space'" "quoted space" "g-q space" "" +sftp_ls "${DIR}/g-sl\\\\ash" "escaped slash" "g-sl\\ash" "" "$nobs" +sftp_ls "'${DIR}/g-sl\\\\ash'" "quoted slash" "g-sl\\ash" "" "$nobs" +sftp_ls "${DIR}/g-slash\\\\" "escaped slash at EOL" "g-slash\\" "" "$nobs" +sftp_ls "'${DIR}/g-slash\\\\'" "quoted slash at EOL" "g-slash\\" "" "$nobs" +sftp_ls "${DIR}/g-qs\\\\\\\"" "escaped slash+quote" "g-qs\\\"" "" "$nobs" +sftp_ls "'${DIR}/g-qs\\\\\"'" "quoted slash+quote" "g-qs\\\"" "" "$nobs" + +rm -rf ${BASE} + diff --git a/crypto/external/bsd/openssh/dist/regress/sftp-perm.sh b/crypto/external/bsd/openssh/dist/regress/sftp-perm.sh new file mode 100644 index 000000000..304ca0ac5 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/sftp-perm.sh @@ -0,0 +1,269 @@ +# $OpenBSD: sftp-perm.sh,v 1.2 2013/10/17 22:00:18 djm Exp $ +# Placed in the Public Domain. + +tid="sftp permissions" + +SERVER_LOG=${OBJ}/sftp-server.log +CLIENT_LOG=${OBJ}/sftp.log +TEST_SFTP_SERVER=${OBJ}/sftp-server.sh + +prepare_server() { + printf "#!/bin/sh\nexec $SFTPSERVER -el debug3 $* 2>$SERVER_LOG\n" \ + > $TEST_SFTP_SERVER + chmod a+x $TEST_SFTP_SERVER +} + +run_client() { + echo "$@" | ${SFTP} -D ${TEST_SFTP_SERVER} -vvvb - >$CLIENT_LOG 2>&1 +} + +prepare_files() { + _prep="$1" + rm -f ${COPY} ${COPY}.1 + test -d ${COPY}.dd && { rmdir ${COPY}.dd || fatal "rmdir ${COPY}.dd"; } + test -z "$_prep" && return + sh -c "$_prep" || fail "preparation failed: \"$_prep\"" +} + +postcondition() { + _title="$1" + _check="$2" + test -z "$_check" && return + ${TEST_SHELL} -c "$_check" || fail "postcondition check failed: $_title" +} + +ro_test() { + _desc=$1 + _cmd="$2" + _prep="$3" + _expect_success_post="$4" + _expect_fail_post="$5" + verbose "$tid: read-only $_desc" + # Plain (no options, mostly to test that _cmd is good) + prepare_files "$_prep" + prepare_server + run_client "$_cmd" || fail "plain $_desc failed" + postcondition "$_desc no-readonly" "$_expect_success_post" + # Read-only enabled + prepare_files "$_prep" + prepare_server -R + run_client "$_cmd" && fail "read-only $_desc succeeded" + postcondition "$_desc readonly" "$_expect_fail_post" +} + +perm_test() { + _op=$1 + _whitelist_ops=$2 + _cmd="$3" + _prep="$4" + _expect_success_post="$5" + _expect_fail_post="$6" + verbose "$tid: explicit $_op" + # Plain (no options, mostly to test that _cmd is good) + prepare_files "$_prep" + prepare_server + run_client "$_cmd" || fail "plain $_op failed" + postcondition "$_op no white/blacklists" "$_expect_success_post" + # Whitelist + prepare_files "$_prep" + prepare_server -p $_op,$_whitelist_ops + run_client "$_cmd" || fail "whitelisted $_op failed" + postcondition "$_op whitelisted" "$_expect_success_post" + # Blacklist + prepare_files "$_prep" + prepare_server -P $_op + run_client "$_cmd" && fail "blacklisted $_op succeeded" + postcondition "$_op blacklisted" "$_expect_fail_post" + # Whitelist with op missing. + prepare_files "$_prep" + prepare_server -p $_whitelist_ops + run_client "$_cmd" && fail "no whitelist $_op succeeded" + postcondition "$_op not in whitelist" "$_expect_fail_post" +} + +ro_test \ + "upload" \ + "put $DATA $COPY" \ + "" \ + "cmp $DATA $COPY" \ + "test ! -f $COPY" + +ro_test \ + "setstat" \ + "chmod 0700 $COPY" \ + "touch $COPY; chmod 0400 $COPY" \ + "test -x $COPY" \ + "test ! -x $COPY" + +ro_test \ + "rm" \ + "rm $COPY" \ + "touch $COPY" \ + "test ! -f $COPY" \ + "test -f $COPY" + +ro_test \ + "mkdir" \ + "mkdir ${COPY}.dd" \ + "" \ + "test -d ${COPY}.dd" \ + "test ! -d ${COPY}.dd" + +ro_test \ + "rmdir" \ + "rmdir ${COPY}.dd" \ + "mkdir ${COPY}.dd" \ + "test ! -d ${COPY}.dd" \ + "test -d ${COPY}.dd" + +ro_test \ + "posix-rename" \ + "rename $COPY ${COPY}.1" \ + "touch $COPY" \ + "test -f ${COPY}.1 -a ! -f $COPY" \ + "test -f $COPY -a ! -f ${COPY}.1" + +ro_test \ + "oldrename" \ + "rename -l $COPY ${COPY}.1" \ + "touch $COPY" \ + "test -f ${COPY}.1 -a ! -f $COPY" \ + "test -f $COPY -a ! -f ${COPY}.1" + +ro_test \ + "symlink" \ + "ln -s $COPY ${COPY}.1" \ + "touch $COPY" \ + "test -h ${COPY}.1" \ + "test ! -h ${COPY}.1" + +ro_test \ + "hardlink" \ + "ln $COPY ${COPY}.1" \ + "touch $COPY" \ + "test -f ${COPY}.1" \ + "test ! -f ${COPY}.1" + +# Test explicit permissions + +perm_test \ + "open" \ + "realpath,stat,lstat,read,close" \ + "get $DATA $COPY" \ + "" \ + "cmp $DATA $COPY" \ + "! cmp $DATA $COPY 2>/dev/null" + +perm_test \ + "read" \ + "realpath,stat,lstat,open,close" \ + "get $DATA $COPY" \ + "" \ + "cmp $DATA $COPY" \ + "! cmp $DATA $COPY 2>/dev/null" + +perm_test \ + "write" \ + "realpath,stat,lstat,open,close" \ + "put $DATA $COPY" \ + "" \ + "cmp $DATA $COPY" \ + "! cmp $DATA $COPY 2>/dev/null" + +perm_test \ + "lstat" \ + "realpath,stat,open,read,close" \ + "get $DATA $COPY" \ + "" \ + "cmp $DATA $COPY" \ + "! cmp $DATA $COPY 2>/dev/null" + +perm_test \ + "opendir" \ + "realpath,readdir,stat,lstat" \ + "ls -ln $OBJ" + +perm_test \ + "readdir" \ + "realpath,opendir,stat,lstat" \ + "ls -ln $OBJ" + +perm_test \ + "setstat" \ + "realpath,stat,lstat" \ + "chmod 0700 $COPY" \ + "touch $COPY; chmod 0400 $COPY" \ + "test -x $COPY" \ + "test ! -x $COPY" + +perm_test \ + "remove" \ + "realpath,stat,lstat" \ + "rm $COPY" \ + "touch $COPY" \ + "test ! -f $COPY" \ + "test -f $COPY" + +perm_test \ + "mkdir" \ + "realpath,stat,lstat" \ + "mkdir ${COPY}.dd" \ + "" \ + "test -d ${COPY}.dd" \ + "test ! -d ${COPY}.dd" + +perm_test \ + "rmdir" \ + "realpath,stat,lstat" \ + "rmdir ${COPY}.dd" \ + "mkdir ${COPY}.dd" \ + "test ! -d ${COPY}.dd" \ + "test -d ${COPY}.dd" + +perm_test \ + "posix-rename" \ + "realpath,stat,lstat" \ + "rename $COPY ${COPY}.1" \ + "touch $COPY" \ + "test -f ${COPY}.1 -a ! -f $COPY" \ + "test -f $COPY -a ! -f ${COPY}.1" + +perm_test \ + "rename" \ + "realpath,stat,lstat" \ + "rename -l $COPY ${COPY}.1" \ + "touch $COPY" \ + "test -f ${COPY}.1 -a ! -f $COPY" \ + "test -f $COPY -a ! -f ${COPY}.1" + +perm_test \ + "symlink" \ + "realpath,stat,lstat" \ + "ln -s $COPY ${COPY}.1" \ + "touch $COPY" \ + "test -h ${COPY}.1" \ + "test ! -h ${COPY}.1" + +perm_test \ + "hardlink" \ + "realpath,stat,lstat" \ + "ln $COPY ${COPY}.1" \ + "touch $COPY" \ + "test -f ${COPY}.1" \ + "test ! -f ${COPY}.1" + +perm_test \ + "statvfs" \ + "realpath,stat,lstat" \ + "df /" + +# XXX need good tests for: +# fstat +# fsetstat +# realpath +# stat +# readlink +# fstatvfs + +rm -rf ${COPY} ${COPY}.1 ${COPY}.dd + diff --git a/crypto/external/bsd/openssh/dist/regress/sftp.sh b/crypto/external/bsd/openssh/dist/regress/sftp.sh new file mode 100644 index 000000000..b8e9f7527 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/sftp.sh @@ -0,0 +1,32 @@ +# $OpenBSD: sftp.sh,v 1.5 2013/05/17 10:28:11 dtucker Exp $ +# Placed in the Public Domain. + +tid="basic sftp put/get" + +SFTPCMDFILE=${OBJ}/batch +cat >$SFTPCMDFILE < /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then + fail "sftp failed with $r" + else + cmp $DATA ${COPY}.1 || fail "corrupted copy after get" + cmp $DATA ${COPY}.2 || fail "corrupted copy after put" + fi + done +done +rm -f ${COPY}.1 ${COPY}.2 +rm -f $SFTPCMDFILE diff --git a/crypto/external/bsd/openssh/dist/regress/ssh-com-client.sh b/crypto/external/bsd/openssh/dist/regress/ssh-com-client.sh new file mode 100644 index 000000000..e4f80cf0a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/ssh-com-client.sh @@ -0,0 +1,130 @@ +# $OpenBSD: ssh-com-client.sh,v 1.7 2013/05/17 04:29:14 dtucker Exp $ +# Placed in the Public Domain. + +tid="connect with ssh.com client" + +#TEST_COMBASE=/path/to/ssh/com/binaries +if [ "X${TEST_COMBASE}" = "X" ]; then + fatal '$TEST_COMBASE is not set' +fi + +VERSIONS=" + 2.1.0 + 2.2.0 + 2.3.0 + 2.3.1 + 2.4.0 + 3.0.0 + 3.1.0 + 3.2.0 + 3.2.2 + 3.2.3 + 3.2.5 + 3.2.9 + 3.2.9.1 + 3.3.0" + +# 2.0.10 2.0.12 2.0.13 don't like the test setup + +# setup authorized keys +SRC=`dirname ${SCRIPT}` +cp ${SRC}/dsa_ssh2.prv ${OBJ}/id.com +chmod 600 ${OBJ}/id.com +${SSHKEYGEN} -i -f ${OBJ}/id.com > $OBJ/id.openssh +chmod 600 ${OBJ}/id.openssh +${SSHKEYGEN} -y -f ${OBJ}/id.openssh > $OBJ/authorized_keys_$USER +${SSHKEYGEN} -e -f ${OBJ}/id.openssh > $OBJ/id.com.pub +echo IdKey ${OBJ}/id.com > ${OBJ}/id.list + +# we need a DSA host key +t=dsa +rm -f ${OBJ}/$t ${OBJ}/$t.pub +${SSHKEYGEN} -q -N '' -t $t -f ${OBJ}/$t +$SUDO cp $OBJ/$t $OBJ/host.$t +echo HostKey $OBJ/host.$t >> $OBJ/sshd_config + +# add hostkeys to known hosts +mkdir -p ${OBJ}/${USER}/hostkeys +HK=${OBJ}/${USER}/hostkeys/key_${PORT}_127.0.0.1 +${SSHKEYGEN} -e -f ${OBJ}/rsa.pub > ${HK}.ssh-rsa.pub +${SSHKEYGEN} -e -f ${OBJ}/dsa.pub > ${HK}.ssh-dss.pub + +cat > ${OBJ}/ssh2_config << EOF +*: + QuietMode yes + StrictHostKeyChecking yes + Port ${PORT} + User ${USER} + Host 127.0.0.1 + IdentityFile ${OBJ}/id.list + RandomSeedFile ${OBJ}/random_seed + UserConfigDirectory ${OBJ}/%U + AuthenticationSuccessMsg no + BatchMode yes + ForwardX11 no +EOF + +# we need a real server (no ProxyConnect option) +start_sshd + +# go for it +for v in ${VERSIONS}; do + ssh2=${TEST_COMBASE}/${v}/ssh2 + if [ ! -x ${ssh2} ]; then + continue + fi + verbose "ssh2 ${v}" + key=ssh-dss + skipcat=0 + case $v in + 2.1.*|2.3.0) + skipcat=1 + ;; + 3.0.*) + key=ssh-rsa + ;; + esac + cp ${HK}.$key.pub ${HK}.pub + + # check exit status + ${ssh2} -q -F ${OBJ}/ssh2_config somehost exit 42 + r=$? + if [ $r -ne 42 ]; then + fail "ssh2 ${v} exit code test failed (got $r, expected 42)" + fi + + # data transfer + rm -f ${COPY} + ${ssh2} -F ${OBJ}/ssh2_config somehost cat ${DATA} > ${COPY} + if [ $? -ne 0 ]; then + fail "ssh2 ${v} cat test (receive) failed" + fi + cmp ${DATA} ${COPY} || fail "ssh2 ${v} cat test (receive) data mismatch" + + # data transfer, again + if [ $skipcat -eq 0 ]; then + rm -f ${COPY} + cat ${DATA} | \ + ${ssh2} -F ${OBJ}/ssh2_config host "cat > ${COPY}" + if [ $? -ne 0 ]; then + fail "ssh2 ${v} cat test (send) failed" + fi + cmp ${DATA} ${COPY} || \ + fail "ssh2 ${v} cat test (send) data mismatch" + fi + + # no stderr after eof + rm -f ${COPY} + ${ssh2} -F ${OBJ}/ssh2_config somehost \ + exec sh -c \'"exec > /dev/null; sleep 1; echo bla 1>&2; exit 0"\' \ + 2> /dev/null + if [ $? -ne 0 ]; then + fail "ssh2 ${v} stderr test failed" + fi +done + +rm -rf ${OBJ}/${USER} +for i in ssh2_config random_seed dsa.pub dsa host.dsa \ + id.list id.com id.com.pub id.openssh; do + rm -f ${OBJ}/$i +done diff --git a/crypto/external/bsd/openssh/dist/regress/ssh-com-keygen.sh b/crypto/external/bsd/openssh/dist/regress/ssh-com-keygen.sh new file mode 100644 index 000000000..29b02d946 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/ssh-com-keygen.sh @@ -0,0 +1,74 @@ +# $OpenBSD: ssh-com-keygen.sh,v 1.4 2004/02/24 17:06:52 markus Exp $ +# Placed in the Public Domain. + +tid="ssh.com key import" + +#TEST_COMBASE=/path/to/ssh/com/binaries +if [ "X${TEST_COMBASE}" = "X" ]; then + fatal '$TEST_COMBASE is not set' +fi + +VERSIONS=" + 2.0.10 + 2.0.12 + 2.0.13 + 2.1.0 + 2.2.0 + 2.3.0 + 2.3.1 + 2.4.0 + 3.0.0 + 3.1.0 + 3.2.0 + 3.2.2 + 3.2.3 + 3.2.5 + 3.2.9 + 3.2.9.1 + 3.3.0" + +COMPRV=${OBJ}/comkey +COMPUB=${COMPRV}.pub +OPENSSHPRV=${OBJ}/opensshkey +OPENSSHPUB=${OPENSSHPRV}.pub + +# go for it +for v in ${VERSIONS}; do + keygen=${TEST_COMBASE}/${v}/ssh-keygen2 + if [ ! -x ${keygen} ]; then + continue + fi + types="dss" + case $v in + 2.3.1|3.*) + types="$types rsa" + ;; + esac + for t in $types; do + verbose "ssh-keygen $v/$t" + rm -f $COMPRV $COMPUB $OPENSSHPRV $OPENSSHPUB + ${keygen} -q -P -t $t ${COMPRV} > /dev/null 2>&1 + if [ $? -ne 0 ]; then + fail "${keygen} -t $t failed" + continue + fi + ${SSHKEYGEN} -if ${COMPUB} > ${OPENSSHPUB} + if [ $? -ne 0 ]; then + fail "import public key ($v/$t) failed" + continue + fi + ${SSHKEYGEN} -if ${COMPRV} > ${OPENSSHPRV} + if [ $? -ne 0 ]; then + fail "import private key ($v/$t) failed" + continue + fi + chmod 600 ${OPENSSHPRV} + ${SSHKEYGEN} -yf ${OPENSSHPRV} |\ + diff - ${OPENSSHPUB} + if [ $? -ne 0 ]; then + fail "public keys ($v/$t) differ" + fi + done +done + +rm -f $COMPRV $COMPUB $OPENSSHPRV $OPENSSHPUB diff --git a/crypto/external/bsd/openssh/dist/regress/ssh-com-sftp.sh b/crypto/external/bsd/openssh/dist/regress/ssh-com-sftp.sh new file mode 100644 index 000000000..fabfa4983 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/ssh-com-sftp.sh @@ -0,0 +1,65 @@ +# $OpenBSD: ssh-com-sftp.sh,v 1.7 2013/05/17 04:29:14 dtucker Exp $ +# Placed in the Public Domain. + +tid="basic sftp put/get with ssh.com server" + +SFTPCMDFILE=${OBJ}/batch + +cat >$SFTPCMDFILE < /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then + fail "sftp failed with $r" + else + cmp $DATA ${COPY}.1 || fail "corrupted copy after get" + cmp $DATA ${COPY}.2 || fail "corrupted copy after put" + fi + done + done +done +rm -f ${COPY}.1 ${COPY}.2 +rm -f $SFTPCMDFILE diff --git a/crypto/external/bsd/openssh/dist/regress/ssh-com.sh b/crypto/external/bsd/openssh/dist/regress/ssh-com.sh new file mode 100644 index 000000000..4371d5279 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/ssh-com.sh @@ -0,0 +1,119 @@ +# $OpenBSD: ssh-com.sh,v 1.9 2015/05/08 07:29:00 djm Exp $ +# Placed in the Public Domain. + +tid="connect to ssh.com server" + +#TEST_COMBASE=/path/to/ssh/com/binaries +if [ "X${TEST_COMBASE}" = "X" ]; then + fatal '$TEST_COMBASE is not set' +fi + +VERSIONS=" + 2.0.12 + 2.0.13 + 2.1.0 + 2.2.0 + 2.3.0 + 2.4.0 + 3.0.0 + 3.1.0 + 3.2.0 + 3.2.2 + 3.2.3 + 3.2.5 + 3.2.9 + 3.2.9.1 + 3.3.0" +# 2.0.10 does not support UserConfigDirectory +# 2.3.1 requires a config in $HOME/.ssh2 + +SRC=`dirname ${SCRIPT}` + +# ssh.com +cat << EOF > $OBJ/sshd2_config +#*: + # Port and ListenAddress are not used. + QuietMode yes + Port 4343 + ListenAddress 127.0.0.1 + UserConfigDirectory ${OBJ}/%U + Ciphers AnyCipher + PubKeyAuthentication yes + #AllowedAuthentications publickey + AuthorizationFile authorization + HostKeyFile ${SRC}/dsa_ssh2.prv + PublicHostKeyFile ${SRC}/dsa_ssh2.pub + RandomSeedFile ${OBJ}/random_seed + MaxConnections 0 + PermitRootLogin yes + VerboseMode no + CheckMail no + Ssh1Compatibility no +EOF + +# create client config +sed "s/HostKeyAlias.*/HostKeyAlias ssh2-localhost-with-alias/" \ + < $OBJ/ssh_config > $OBJ/ssh_config_com + +# we need a DSA key for +rm -f ${OBJ}/dsa ${OBJ}/dsa.pub +${SSHKEYGEN} -q -N '' -t dsa -f ${OBJ}/dsa + +# setup userdir, try rsa first +mkdir -p ${OBJ}/${USER} +cp /dev/null ${OBJ}/${USER}/authorization +for t in rsa dsa; do + ${SSHKEYGEN} -e -f ${OBJ}/$t.pub > ${OBJ}/${USER}/$t.com + echo Key $t.com >> ${OBJ}/${USER}/authorization + echo IdentityFile ${OBJ}/$t >> ${OBJ}/ssh_config_com +done + +# convert and append DSA hostkey +( + printf 'ssh2-localhost-with-alias,127.0.0.1,::1 ' + ${SSHKEYGEN} -if ${SRC}/dsa_ssh2.pub +) >> $OBJ/known_hosts + +# go for it +for v in ${VERSIONS}; do + sshd2=${TEST_COMBASE}/${v}/sshd2 + if [ ! -x ${sshd2} ]; then + continue + fi + trace "sshd2 ${v}" + PROXY="proxycommand ${sshd2} -qif ${OBJ}/sshd2_config 2> /dev/null" + ${SSH} -qF ${OBJ}/ssh_config_com -o "${PROXY}" dummy exit 0 + if [ $? -ne 0 ]; then + fail "ssh connect to sshd2 ${v} failed" + fi + + ciphers="3des-cbc blowfish-cbc arcfour" + macs="hmac-md5" + case $v in + 2.4.*) + ciphers="$ciphers cast128-cbc" + macs="$macs hmac-sha1 hmac-sha1-96 hmac-md5-96" + ;; + 3.*) + ciphers="$ciphers aes128-cbc cast128-cbc" + macs="$macs hmac-sha1 hmac-sha1-96 hmac-md5-96" + ;; + esac + #ciphers="3des-cbc" + for m in $macs; do + for c in $ciphers; do + trace "sshd2 ${v} cipher $c mac $m" + verbose "test ${tid}: sshd2 ${v} cipher $c mac $m" + ${SSH} -c $c -m $m -qF ${OBJ}/ssh_config_com -o "${PROXY}" dummy exit 0 + if [ $? -ne 0 ]; then + fail "ssh connect to sshd2 ${v} with $c/$m failed" + fi + done + done +done + +rm -rf ${OBJ}/${USER} +for i in sshd_config_proxy ssh_config_proxy random_seed \ + sshd2_config dsa.pub dsa ssh_config_com; do + rm -f ${OBJ}/$i +done diff --git a/crypto/external/bsd/openssh/dist/regress/ssh2putty.sh b/crypto/external/bsd/openssh/dist/regress/ssh2putty.sh new file mode 100755 index 000000000..bcf83afe9 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/ssh2putty.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# $OpenBSD: ssh2putty.sh,v 1.3 2015/05/08 07:26:13 djm Exp $ + +if test "x$1" = "x" -o "x$2" = "x" -o "x$3" = "x" ; then + echo "Usage: ssh2putty hostname port ssh-private-key" + exit 1 +fi + +HOST=$1 +PORT=$2 +KEYFILE=$3 + +# XXX - support DSA keys too +if grep "BEGIN RSA PRIVATE KEY" $KEYFILE >/dev/null 2>&1 ; then + : +else + echo "Unsupported private key format" + exit 1 +fi + +public_exponent=` + openssl rsa -noout -text -in $KEYFILE | grep ^publicExponent | + sed 's/.*(//;s/).*//' +` +test $? -ne 0 && exit 1 + +modulus=` + openssl rsa -noout -modulus -in $KEYFILE | grep ^Modulus= | + sed 's/^Modulus=/0x/' | tr A-Z a-z +` +test $? -ne 0 && exit 1 + +echo "rsa2@$PORT:$HOST $public_exponent,$modulus" + diff --git a/crypto/external/bsd/openssh/dist/regress/sshd-log-wrapper.sh b/crypto/external/bsd/openssh/dist/regress/sshd-log-wrapper.sh new file mode 100644 index 000000000..c00934c78 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/sshd-log-wrapper.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# $OpenBSD: sshd-log-wrapper.sh,v 1.3 2013/04/07 02:16:03 dtucker Exp $ +# Placed in the Public Domain. +# +# simple wrapper for sshd proxy mode to catch stderr output +# sh sshd-log-wrapper.sh /path/to/logfile /path/to/sshd [args...] + +log=$1 +shift + +exec "$@" -E$log diff --git a/crypto/external/bsd/openssh/dist/regress/stderr-after-eof.sh b/crypto/external/bsd/openssh/dist/regress/stderr-after-eof.sh new file mode 100644 index 000000000..218ac6b68 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/stderr-after-eof.sh @@ -0,0 +1,24 @@ +# $OpenBSD: stderr-after-eof.sh,v 1.2 2013/05/17 04:29:14 dtucker Exp $ +# Placed in the Public Domain. + +tid="stderr data after eof" + +# setup data +rm -f ${DATA} ${COPY} +cp /dev/null ${DATA} +for i in 1 2 3 4 5 6; do + (date;echo $i) | md5 >> ${DATA} +done + +${SSH} -2 -F $OBJ/ssh_proxy otherhost \ + exec sh -c \'"exec > /dev/null; sleep 2; cat ${DATA} 1>&2 $s"\' \ + 2> ${COPY} +r=$? +if [ $r -ne 0 ]; then + fail "ssh failed with exit code $r" +fi +egrep 'Disconnecting: Received extended_data after EOF' ${COPY} && + fail "ext data received after eof" +cmp ${DATA} ${COPY} || fail "stderr corrupt" + +rm -f ${DATA} ${COPY} diff --git a/crypto/external/bsd/openssh/dist/regress/stderr-data.sh b/crypto/external/bsd/openssh/dist/regress/stderr-data.sh new file mode 100644 index 000000000..8c8149a73 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/stderr-data.sh @@ -0,0 +1,29 @@ +# $OpenBSD: stderr-data.sh,v 1.4 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="stderr data transfer" + +for n in '' -n; do +for p in ${SSH_PROTOCOLS}; do + verbose "test $tid: proto $p ($n)" + ${SSH} $n -$p -F $OBJ/ssh_proxy otherhost \ + exec sh -c \'"exec > /dev/null; sleep 3; cat ${DATA} 1>&2 $s"\' \ + 2> ${COPY} + r=$? + if [ $r -ne 0 ]; then + fail "ssh failed with exit code $r" + fi + cmp ${DATA} ${COPY} || fail "stderr corrupt" + rm -f ${COPY} + + ${SSH} $n -$p -F $OBJ/ssh_proxy otherhost \ + exec sh -c \'"echo a; exec > /dev/null; sleep 3; cat ${DATA} 1>&2 $s"\' \ + > /dev/null 2> ${COPY} + r=$? + if [ $r -ne 0 ]; then + fail "ssh failed with exit code $r" + fi + cmp ${DATA} ${COPY} || fail "stderr corrupt" + rm -f ${COPY} +done +done diff --git a/crypto/external/bsd/openssh/dist/regress/t11.ok b/crypto/external/bsd/openssh/dist/regress/t11.ok new file mode 100644 index 000000000..1925bb470 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/t11.ok @@ -0,0 +1 @@ +SHA256:4w1rnrek3klTJOTVhwuCIFd5k+pq9Bfo5KTxxb8BqbY diff --git a/crypto/external/bsd/openssh/dist/regress/t4.ok b/crypto/external/bsd/openssh/dist/regress/t4.ok new file mode 100644 index 000000000..4631ea8c7 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/t4.ok @@ -0,0 +1 @@ +MD5:3b:dd:44:e9:49:18:84:95:f1:e7:33:6b:9d:93:b1:36 diff --git a/crypto/external/bsd/openssh/dist/regress/t5.ok b/crypto/external/bsd/openssh/dist/regress/t5.ok new file mode 100644 index 000000000..bd622f300 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/t5.ok @@ -0,0 +1 @@ +xokes-lylis-byleh-zebib-kalus-bihas-tevah-haroz-suhar-foved-noxex diff --git a/crypto/external/bsd/openssh/dist/regress/test-exec.sh b/crypto/external/bsd/openssh/dist/regress/test-exec.sh new file mode 100644 index 000000000..114e129f2 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/test-exec.sh @@ -0,0 +1,564 @@ +# $OpenBSD: test-exec.sh,v 1.51 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +#SUDO=sudo + +# Unbreak GNU head(1) +_POSIX2_VERSION=199209 +export _POSIX2_VERSION + +case `uname -s 2>/dev/null` in +OSF1*) + BIN_SH=xpg4 + export BIN_SH + ;; +CYGWIN_NT-5.0) + os=cygwin + TEST_SSH_IPV6=no + ;; +CYGWIN*) + os=cygwin + ;; +esac + +if [ ! -z "$TEST_SSH_PORT" ]; then + PORT="$TEST_SSH_PORT" +else + PORT=4242 +fi + +if [ -x /usr/ucb/whoami ]; then + USER=`/usr/ucb/whoami` +elif whoami >/dev/null 2>&1; then + USER=`whoami` +elif logname >/dev/null 2>&1; then + USER=`logname` +else + USER=`id -un` +fi + +OBJ=$1 +if [ "x$OBJ" = "x" ]; then + echo '$OBJ not defined' + exit 2 +fi +if [ ! -d $OBJ ]; then + echo "not a directory: $OBJ" + exit 2 +fi +SCRIPT=$2 +if [ "x$SCRIPT" = "x" ]; then + echo '$SCRIPT not defined' + exit 2 +fi +if [ ! -f $SCRIPT ]; then + echo "not a file: $SCRIPT" + exit 2 +fi +if $TEST_SHELL -n $SCRIPT; then + true +else + echo "syntax error in $SCRIPT" + exit 2 +fi +unset SSH_AUTH_SOCK + +SRC=`dirname ${SCRIPT}` + +# defaults +SSH=ssh +SSHD=sshd +SSHAGENT=ssh-agent +SSHADD=ssh-add +SSHKEYGEN=ssh-keygen +SSHKEYSCAN=ssh-keyscan +SFTP=sftp +SFTPSERVER=/usr/libexec/openssh/sftp-server +SCP=scp + +# Interop testing +PLINK=plink +PUTTYGEN=puttygen +CONCH=conch + +if [ "x$TEST_SSH_SSH" != "x" ]; then + SSH="${TEST_SSH_SSH}" +fi +if [ "x$TEST_SSH_SSHD" != "x" ]; then + SSHD="${TEST_SSH_SSHD}" +fi +if [ "x$TEST_SSH_SSHAGENT" != "x" ]; then + SSHAGENT="${TEST_SSH_SSHAGENT}" +fi +if [ "x$TEST_SSH_SSHADD" != "x" ]; then + SSHADD="${TEST_SSH_SSHADD}" +fi +if [ "x$TEST_SSH_SSHKEYGEN" != "x" ]; then + SSHKEYGEN="${TEST_SSH_SSHKEYGEN}" +fi +if [ "x$TEST_SSH_SSHKEYSCAN" != "x" ]; then + SSHKEYSCAN="${TEST_SSH_SSHKEYSCAN}" +fi +if [ "x$TEST_SSH_SFTP" != "x" ]; then + SFTP="${TEST_SSH_SFTP}" +fi +if [ "x$TEST_SSH_SFTPSERVER" != "x" ]; then + SFTPSERVER="${TEST_SSH_SFTPSERVER}" +fi +if [ "x$TEST_SSH_SCP" != "x" ]; then + SCP="${TEST_SSH_SCP}" +fi +if [ "x$TEST_SSH_PLINK" != "x" ]; then + # Find real binary, if it exists + case "${TEST_SSH_PLINK}" in + /*) PLINK="${TEST_SSH_PLINK}" ;; + *) PLINK=`which ${TEST_SSH_PLINK} 2>/dev/null` ;; + esac +fi +if [ "x$TEST_SSH_PUTTYGEN" != "x" ]; then + # Find real binary, if it exists + case "${TEST_SSH_PUTTYGEN}" in + /*) PUTTYGEN="${TEST_SSH_PUTTYGEN}" ;; + *) PUTTYGEN=`which ${TEST_SSH_PUTTYGEN} 2>/dev/null` ;; + esac +fi +if [ "x$TEST_SSH_CONCH" != "x" ]; then + # Find real binary, if it exists + case "${TEST_SSH_CONCH}" in + /*) CONCH="${TEST_SSH_CONCH}" ;; + *) CONCH=`which ${TEST_SSH_CONCH} 2>/dev/null` ;; + esac +fi + +SSH_PROTOCOLS=`$SSH -Q protocol-version` +if [ "x$TEST_SSH_PROTOCOLS" != "x" ]; then + SSH_PROTOCOLS="${TEST_SSH_PROTOCOLS}" +fi + +# Path to sshd must be absolute for rexec +case "$SSHD" in +/*) ;; +*) SSHD=`which $SSHD` ;; +esac + +case "$SSHAGENT" in +/*) ;; +*) SSHAGENT=`which $SSHAGENT` ;; +esac + +# Record the actual binaries used. +SSH_BIN=${SSH} +SSHD_BIN=${SSHD} +SSHAGENT_BIN=${SSHAGENT} +SSHADD_BIN=${SSHADD} +SSHKEYGEN_BIN=${SSHKEYGEN} +SSHKEYSCAN_BIN=${SSHKEYSCAN} +SFTP_BIN=${SFTP} +SFTPSERVER_BIN=${SFTPSERVER} +SCP_BIN=${SCP} + +if [ "x$USE_VALGRIND" != "x" ]; then + mkdir -p $OBJ/valgrind-out + VG_TEST=`basename $SCRIPT .sh` + + # Some tests are difficult to fix. + case "$VG_TEST" in + connect-privsep|reexec) + VG_SKIP=1 ;; + esac + + if [ x"$VG_SKIP" = "x" ]; then + VG_IGNORE="/bin/*,/sbin/*,/usr/*,/var/*" + VG_LOG="$OBJ/valgrind-out/${VG_TEST}." + VG_OPTS="--track-origins=yes --leak-check=full" + VG_OPTS="$VG_OPTS --trace-children=yes" + VG_OPTS="$VG_OPTS --trace-children-skip=${VG_IGNORE}" + VG_PATH="valgrind" + if [ "x$VALGRIND_PATH" != "x" ]; then + VG_PATH="$VALGRIND_PATH" + fi + VG="$VG_PATH $VG_OPTS" + SSH="$VG --log-file=${VG_LOG}ssh.%p $SSH" + SSHD="$VG --log-file=${VG_LOG}sshd.%p $SSHD" + SSHAGENT="$VG --log-file=${VG_LOG}ssh-agent.%p $SSHAGENT" + SSHADD="$VG --log-file=${VG_LOG}ssh-add.%p $SSHADD" + SSHKEYGEN="$VG --log-file=${VG_LOG}ssh-keygen.%p $SSHKEYGEN" + SSHKEYSCAN="$VG --log-file=${VG_LOG}ssh-keyscan.%p $SSHKEYSCAN" + SFTP="$VG --log-file=${VG_LOG}sftp.%p ${SFTP}" + SCP="$VG --log-file=${VG_LOG}scp.%p $SCP" + cat > $OBJ/valgrind-sftp-server.sh << EOF +#!/bin/sh +exec $VG --log-file=${VG_LOG}sftp-server.%p $SFTPSERVER "\$@" +EOF + chmod a+rx $OBJ/valgrind-sftp-server.sh + SFTPSERVER="$OBJ/valgrind-sftp-server.sh" + fi +fi + +# Logfiles. +# SSH_LOGFILE should be the debug output of ssh(1) only +# SSHD_LOGFILE should be the debug output of sshd(8) only +# REGRESS_LOGFILE is the output of the test itself stdout and stderr +if [ "x$TEST_SSH_LOGFILE" = "x" ]; then + TEST_SSH_LOGFILE=$OBJ/ssh.log +fi +if [ "x$TEST_SSHD_LOGFILE" = "x" ]; then + TEST_SSHD_LOGFILE=$OBJ/sshd.log +fi +if [ "x$TEST_REGRESS_LOGFILE" = "x" ]; then + TEST_REGRESS_LOGFILE=$OBJ/regress.log +fi + +# truncate logfiles +>$TEST_SSH_LOGFILE +>$TEST_SSHD_LOGFILE +>$TEST_REGRESS_LOGFILE + +# Create wrapper ssh with logging. We can't just specify "SSH=ssh -E..." +# because sftp and scp don't handle spaces in arguments. +SSHLOGWRAP=$OBJ/ssh-log-wrapper.sh +echo "#!/bin/sh" > $SSHLOGWRAP +echo "exec ${SSH} -E${TEST_SSH_LOGFILE} "'"$@"' >>$SSHLOGWRAP + +chmod a+rx $OBJ/ssh-log-wrapper.sh +SSH="$SSHLOGWRAP" + +# Some test data. We make a copy because some tests will overwrite it. +# The tests may assume that $DATA exists and is writable and $COPY does +# not exist. Tests requiring larger data files can call increase_datafile_size +# [kbytes] to ensure the file is at least that large. +DATANAME=data +DATA=$OBJ/${DATANAME} +cat ${SSHAGENT_BIN} >${DATA} +chmod u+w ${DATA} +COPY=$OBJ/copy +rm -f ${COPY} + +increase_datafile_size() +{ + while [ `du -k ${DATA} | cut -f1` -lt $1 ]; do + cat ${SSHAGENT_BIN} >>${DATA} + done +} + +# these should be used in tests +export SSH SSHD SSHAGENT SSHADD SSHKEYGEN SSHKEYSCAN SFTP SFTPSERVER SCP +#echo $SSH $SSHD $SSHAGENT $SSHADD $SSHKEYGEN $SSHKEYSCAN $SFTP $SFTPSERVER $SCP + +# Portable specific functions +have_prog() +{ + saved_IFS="$IFS" + IFS=":" + for i in $PATH + do + if [ -x $i/$1 ]; then + IFS="$saved_IFS" + return 0 + fi + done + IFS="$saved_IFS" + return 1 +} + +jot() { + awk "BEGIN { for (i = $2; i < $2 + $1; i++) { printf \"%d\n\", i } exit }" +} + +# Check whether preprocessor symbols are defined in config.h. +config_defined () +{ + str=$1 + while test "x$2" != "x" ; do + str="$str|$2" + shift + done + egrep "^#define.*($str)" ${BUILDDIR}/config.h >/dev/null 2>&1 +} + +md5 () { + if have_prog md5sum; then + md5sum + elif have_prog openssl; then + openssl md5 + elif have_prog cksum; then + cksum + elif have_prog sum; then + sum + else + wc -c + fi +} +# End of portable specific functions + +# helper +cleanup () +{ + if [ "x$SSH_PID" != "x" ]; then + if [ $SSH_PID -lt 2 ]; then + echo bad pid for ssh: $SSH_PID + else + kill $SSH_PID + fi + fi + if [ -f $PIDFILE ]; then + pid=`$SUDO cat $PIDFILE` + if [ "X$pid" = "X" ]; then + echo no sshd running + else + if [ $pid -lt 2 ]; then + echo bad pid for sshd: $pid + else + $SUDO kill $pid + trace "wait for sshd to exit" + i=0; + while [ -f $PIDFILE -a $i -lt 5 ]; do + i=`expr $i + 1` + sleep $i + done + test -f $PIDFILE && \ + fatal "sshd didn't exit port $PORT pid $pid" + fi + fi + fi +} + +start_debug_log () +{ + echo "trace: $@" >$TEST_REGRESS_LOGFILE + echo "trace: $@" >$TEST_SSH_LOGFILE + echo "trace: $@" >$TEST_SSHD_LOGFILE +} + +save_debug_log () +{ + echo $@ >>$TEST_REGRESS_LOGFILE + echo $@ >>$TEST_SSH_LOGFILE + echo $@ >>$TEST_SSHD_LOGFILE + (cat $TEST_REGRESS_LOGFILE; echo) >>$OBJ/failed-regress.log + (cat $TEST_SSH_LOGFILE; echo) >>$OBJ/failed-ssh.log + (cat $TEST_SSHD_LOGFILE; echo) >>$OBJ/failed-sshd.log +} + +trace () +{ + start_debug_log $@ + if [ "X$TEST_SSH_TRACE" = "Xyes" ]; then + echo "$@" + fi +} + +verbose () +{ + start_debug_log $@ + if [ "X$TEST_SSH_QUIET" != "Xyes" ]; then + echo "$@" + fi +} + +warn () +{ + echo "WARNING: $@" >>$TEST_SSH_LOGFILE + echo "WARNING: $@" +} + +fail () +{ + save_debug_log "FAIL: $@" + RESULT=1 + echo "$@" + +} + +fatal () +{ + save_debug_log "FATAL: $@" + printf "FATAL: " + fail "$@" + cleanup + exit $RESULT +} + +ssh_version () +{ + echo ${SSH_PROTOCOLS} | grep "$1" >/dev/null +} + +RESULT=0 +PIDFILE=$OBJ/pidfile + +trap fatal 3 2 + +if ssh_version 1; then + PROTO="2,1" +else + PROTO="2" +fi + +# create server config +cat << EOF > $OBJ/sshd_config + StrictModes no + Port $PORT + Protocol $PROTO + AddressFamily inet + ListenAddress 127.0.0.1 + #ListenAddress ::1 + PidFile $PIDFILE + AuthorizedKeysFile $OBJ/authorized_keys_%u + LogLevel DEBUG3 + AcceptEnv _XXX_TEST_* + AcceptEnv _XXX_TEST + Subsystem sftp $SFTPSERVER +EOF + +if [ ! -z "$TEST_SSH_SSHD_CONFOPTS" ]; then + trace "adding sshd_config option $TEST_SSH_SSHD_CONFOPTS" + echo "$TEST_SSH_SSHD_CONFOPTS" >> $OBJ/sshd_config +fi + +# server config for proxy connects +cp $OBJ/sshd_config $OBJ/sshd_proxy + +# allow group-writable directories in proxy-mode +echo 'StrictModes no' >> $OBJ/sshd_proxy + +# create client config +cat << EOF > $OBJ/ssh_config +Host * + Protocol $PROTO + Hostname 127.0.0.1 + HostKeyAlias localhost-with-alias + Port $PORT + User $USER + GlobalKnownHostsFile $OBJ/known_hosts + UserKnownHostsFile $OBJ/known_hosts + RSAAuthentication yes + PubkeyAuthentication yes + ChallengeResponseAuthentication no + HostbasedAuthentication no + PasswordAuthentication no + RhostsRSAAuthentication no + BatchMode yes + StrictHostKeyChecking yes + LogLevel DEBUG3 +EOF + +if [ ! -z "$TEST_SSH_SSH_CONFOPTS" ]; then + trace "adding ssh_config option $TEST_SSH_SSH_CONFOPTS" + echo "$TEST_SSH_SSH_CONFOPTS" >> $OBJ/ssh_config +fi + +rm -f $OBJ/known_hosts $OBJ/authorized_keys_$USER + +if ssh_version 1; then + SSH_KEYTYPES="rsa rsa1" +else + SSH_KEYTYPES="rsa ed25519" +fi +trace "generate keys" +for t in ${SSH_KEYTYPES}; do + # generate user key + if [ ! -f $OBJ/$t ] || [ ${SSHKEYGEN_BIN} -nt $OBJ/$t ]; then + rm -f $OBJ/$t + ${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t ||\ + fail "ssh-keygen for $t failed" + fi + + # known hosts file for client + ( + printf 'localhost-with-alias,127.0.0.1,::1 ' + cat $OBJ/$t.pub + ) >> $OBJ/known_hosts + + # setup authorized keys + cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER + echo IdentityFile $OBJ/$t >> $OBJ/ssh_config + + # use key as host key, too + $SUDO cp $OBJ/$t $OBJ/host.$t + echo HostKey $OBJ/host.$t >> $OBJ/sshd_config + + # don't use SUDO for proxy connect + echo HostKey $OBJ/$t >> $OBJ/sshd_proxy +done +chmod 644 $OBJ/authorized_keys_$USER + +# Activate Twisted Conch tests if the binary is present +REGRESS_INTEROP_CONCH=no +if test -x "$CONCH" ; then + REGRESS_INTEROP_CONCH=yes +fi + +# If PuTTY is present and we are running a PuTTY test, prepare keys and +# configuration +REGRESS_INTEROP_PUTTY=no +if test -x "$PUTTYGEN" -a -x "$PLINK" ; then + REGRESS_INTEROP_PUTTY=yes +fi +case "$SCRIPT" in +*putty*) ;; +*) REGRESS_INTEROP_PUTTY=no ;; +esac + +if test "$REGRESS_INTEROP_PUTTY" = "yes" ; then + mkdir -p ${OBJ}/.putty + + # Add a PuTTY key to authorized_keys + rm -f ${OBJ}/putty.rsa2 + puttygen -t rsa -o ${OBJ}/putty.rsa2 < /dev/null > /dev/null + puttygen -O public-openssh ${OBJ}/putty.rsa2 \ + >> $OBJ/authorized_keys_$USER + + # Convert rsa2 host key to PuTTY format + ${SRC}/ssh2putty.sh 127.0.0.1 $PORT $OBJ/rsa > \ + ${OBJ}/.putty/sshhostkeys + ${SRC}/ssh2putty.sh 127.0.0.1 22 $OBJ/rsa >> \ + ${OBJ}/.putty/sshhostkeys + + # Setup proxied session + mkdir -p ${OBJ}/.putty/sessions + rm -f ${OBJ}/.putty/sessions/localhost_proxy + echo "Hostname=127.0.0.1" >> ${OBJ}/.putty/sessions/localhost_proxy + echo "PortNumber=$PORT" >> ${OBJ}/.putty/sessions/localhost_proxy + echo "ProxyMethod=5" >> ${OBJ}/.putty/sessions/localhost_proxy + echo "ProxyTelnetCommand=sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy" >> ${OBJ}/.putty/sessions/localhost_proxy + + REGRESS_INTEROP_PUTTY=yes +fi + +# create a proxy version of the client config +( + cat $OBJ/ssh_config + echo proxycommand ${SUDO} sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy +) > $OBJ/ssh_proxy + +# check proxy config +${SSHD} -t -f $OBJ/sshd_proxy || fatal "sshd_proxy broken" + +start_sshd () +{ + # start sshd + $SUDO ${SSHD} -f $OBJ/sshd_config "$@" -t || fatal "sshd_config broken" + $SUDO ${SSHD} -f $OBJ/sshd_config "$@" -E$TEST_SSHD_LOGFILE + + trace "wait for sshd" + i=0; + while [ ! -f $PIDFILE -a $i -lt 10 ]; do + i=`expr $i + 1` + sleep $i + done + + test -f $PIDFILE || fatal "no sshd running on port $PORT" +} + +# source test body +. $SCRIPT + +# kill sshd +cleanup +if [ $RESULT -eq 0 ]; then + verbose ok $tid +else + echo failed $tid +fi +exit $RESULT diff --git a/crypto/external/bsd/openssh/dist/regress/transfer.sh b/crypto/external/bsd/openssh/dist/regress/transfer.sh new file mode 100644 index 000000000..36c14634a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/transfer.sh @@ -0,0 +1,26 @@ +# $OpenBSD: transfer.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="transfer data" + +for p in ${SSH_PROTOCOLS}; do + verbose "$tid: proto $p" + rm -f ${COPY} + ${SSH} -n -q -$p -F $OBJ/ssh_proxy somehost cat ${DATA} > ${COPY} + if [ $? -ne 0 ]; then + fail "ssh cat $DATA failed" + fi + cmp ${DATA} ${COPY} || fail "corrupted copy" + + for s in 10 100 1k 32k 64k 128k 256k; do + trace "proto $p dd-size ${s}" + rm -f ${COPY} + dd if=$DATA obs=${s} 2> /dev/null | \ + ${SSH} -q -$p -F $OBJ/ssh_proxy somehost "cat > ${COPY}" + if [ $? -ne 0 ]; then + fail "ssh cat $DATA failed" + fi + cmp $DATA ${COPY} || fail "corrupted copy" + done +done +rm -f ${COPY} diff --git a/crypto/external/bsd/openssh/dist/regress/try-ciphers.sh b/crypto/external/bsd/openssh/dist/regress/try-ciphers.sh new file mode 100644 index 000000000..889a735d2 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/try-ciphers.sh @@ -0,0 +1,42 @@ +# $OpenBSD: try-ciphers.sh,v 1.25 2015/03/24 20:22:17 markus Exp $ +# Placed in the Public Domain. + +tid="try ciphers" + +cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak + +for c in `${SSH} -Q cipher`; do + n=0 + for m in `${SSH} -Q mac`; do + trace "proto 2 cipher $c mac $m" + verbose "test $tid: proto 2 cipher $c mac $m" + cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy + echo "Ciphers=$c" >> $OBJ/sshd_proxy + echo "MACs=$m" >> $OBJ/sshd_proxy + ${SSH} -F $OBJ/ssh_proxy -2 -m $m -c $c somehost true + if [ $? -ne 0 ]; then + fail "ssh -2 failed with mac $m cipher $c" + fi + # No point trying all MACs for AEAD ciphers since they + # are ignored. + if ${SSH} -Q cipher-auth | grep "^${c}\$" >/dev/null 2>&1 ; then + break + fi + n=`expr $n + 1` + done +done + +if ssh_version 1; then + ciphers="3des blowfish" +else + ciphers="" +fi +for c in $ciphers; do + trace "proto 1 cipher $c" + verbose "test $tid: proto 1 cipher $c" + ${SSH} -F $OBJ/ssh_proxy -1 -c $c somehost true + if [ $? -ne 0 ]; then + fail "ssh -1 failed with cipher $c" + fi +done + diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/Makefile b/crypto/external/bsd/openssh/dist/regress/unittests/Makefile new file mode 100644 index 000000000..d3d90823f --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/Makefile @@ -0,0 +1,5 @@ +# $OpenBSD: Makefile,v 1.5 2015/02/16 22:21:03 djm Exp $ +REGRESS_FAIL_EARLY= yes +SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys + +.include diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/Makefile.inc b/crypto/external/bsd/openssh/dist/regress/unittests/Makefile.inc new file mode 100644 index 000000000..7385e2ba3 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/Makefile.inc @@ -0,0 +1,59 @@ +# $OpenBSD: Makefile.inc,v 1.6 2015/07/01 23:11:18 djm Exp $ + +.include +.include + +# enable warnings +WARNINGS=Yes + +DEBUG=-g +CFLAGS+= -fstack-protector-all +CDIAGFLAGS= -Wall +CDIAGFLAGS+= -Wextra +CDIAGFLAGS+= -Werror +CDIAGFLAGS+= -Wchar-subscripts +CDIAGFLAGS+= -Wcomment +CDIAGFLAGS+= -Wformat +CDIAGFLAGS+= -Wformat-security +CDIAGFLAGS+= -Wimplicit +CDIAGFLAGS+= -Winline +CDIAGFLAGS+= -Wmissing-declarations +CDIAGFLAGS+= -Wmissing-prototypes +CDIAGFLAGS+= -Wparentheses +CDIAGFLAGS+= -Wpointer-arith +CDIAGFLAGS+= -Wreturn-type +CDIAGFLAGS+= -Wshadow +CDIAGFLAGS+= -Wsign-compare +CDIAGFLAGS+= -Wstrict-aliasing +CDIAGFLAGS+= -Wstrict-prototypes +CDIAGFLAGS+= -Wswitch +CDIAGFLAGS+= -Wtrigraphs +CDIAGFLAGS+= -Wuninitialized +CDIAGFLAGS+= -Wunused +.if ${COMPILER_VERSION} == "gcc4" +CDIAGFLAGS+= -Wpointer-sign +CDIAGFLAGS+= -Wold-style-definition +.endif + +SSHREL=../../../../../usr.bin/ssh + +CFLAGS+=-I${.CURDIR}/../test_helper -I${.CURDIR}/${SSHREL} + +.if exists(${.CURDIR}/../test_helper/${__objdir}) +LDADD+=-L${.CURDIR}/../test_helper/${__objdir} -ltest_helper +DPADD+=${.CURDIR}/../test_helper/${__objdir}/libtest_helper.a +.else +LDADD+=-L${.CURDIR}/../test_helper -ltest_helper +DPADD+=${.CURDIR}/../test_helper/libtest_helper.a +.endif + +.if exists(${.CURDIR}/${SSHREL}/lib/${__objdir}) +LDADD+=-L${.CURDIR}/${SSHREL}/lib/${__objdir} -lssh +DPADD+=${.CURDIR}/${SSHREL}/lib/${__objdir}/libssh.a +.else +LDADD+=-L${.CURDIR}/${SSHREL}/lib -lssh +DPADD+=${.CURDIR}/${SSHREL}/lib/libssh.a +.endif + +LDADD+= -lcrypto +DPADD+= ${LIBCRYPTO} diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/bitmap/Makefile b/crypto/external/bsd/openssh/dist/regress/unittests/bitmap/Makefile new file mode 100644 index 000000000..b704d22d6 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/bitmap/Makefile @@ -0,0 +1,12 @@ +# $OpenBSD: Makefile,v 1.1 2015/01/15 07:36:28 djm Exp $ + +TEST_ENV= "MALLOC_OPTIONS=AFGJPRX" + +PROG=test_bitmap +SRCS=tests.c +REGRESS_TARGETS=run-regress-${PROG} + +run-regress-${PROG}: ${PROG} + env ${TEST_ENV} ./${PROG} + +.include diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/bitmap/tests.c b/crypto/external/bsd/openssh/dist/regress/unittests/bitmap/tests.c new file mode 100644 index 000000000..23025f90a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/bitmap/tests.c @@ -0,0 +1,135 @@ +/* $OpenBSD: tests.c,v 1.1 2015/01/15 07:36:28 djm Exp $ */ +/* + * Regress test for bitmap.h bitmap API + * + * Placed in the public domain + */ + +#include "includes.h" + +#include +#include +#include +#ifdef HAVE_STDINT_H +#include +#endif +#include +#include + +#include + +#include "../test_helper/test_helper.h" + +#include "bitmap.h" + +#define NTESTS 131 + +void +tests(void) +{ + struct bitmap *b; + BIGNUM *bn; + size_t len; + int i, j, k, n; + u_char bbuf[1024], bnbuf[1024]; + int r; + + TEST_START("bitmap_new"); + b = bitmap_new(); + ASSERT_PTR_NE(b, NULL); + bn = BN_new(); + ASSERT_PTR_NE(bn, NULL); + TEST_DONE(); + + TEST_START("bitmap_set_bit / bitmap_test_bit"); + for (i = -1; i < NTESTS; i++) { + for (j = -1; j < NTESTS; j++) { + for (k = -1; k < NTESTS; k++) { + bitmap_zero(b); + BN_clear(bn); + + test_subtest_info("set %d/%d/%d", i, j, k); + /* Set bits */ + if (i >= 0) { + ASSERT_INT_EQ(bitmap_set_bit(b, i), 0); + ASSERT_INT_EQ(BN_set_bit(bn, i), 1); + } + if (j >= 0) { + ASSERT_INT_EQ(bitmap_set_bit(b, j), 0); + ASSERT_INT_EQ(BN_set_bit(bn, j), 1); + } + if (k >= 0) { + ASSERT_INT_EQ(bitmap_set_bit(b, k), 0); + ASSERT_INT_EQ(BN_set_bit(bn, k), 1); + } + + /* Check perfect match between bitmap and bn */ + test_subtest_info("match %d/%d/%d", i, j, k); + for (n = 0; n < NTESTS; n++) { + ASSERT_INT_EQ(BN_is_bit_set(bn, n), + bitmap_test_bit(b, n)); + } + + /* Test length calculations */ + test_subtest_info("length %d/%d/%d", i, j, k); + ASSERT_INT_EQ(BN_num_bits(bn), + (int)bitmap_nbits(b)); + ASSERT_INT_EQ(BN_num_bytes(bn), + (int)bitmap_nbytes(b)); + + /* Test serialisation */ + test_subtest_info("serialise %d/%d/%d", + i, j, k); + len = bitmap_nbytes(b); + memset(bbuf, 0xfc, sizeof(bbuf)); + ASSERT_INT_EQ(bitmap_to_string(b, bbuf, + sizeof(bbuf)), 0); + for (n = len; n < (int)sizeof(bbuf); n++) + ASSERT_U8_EQ(bbuf[n], 0xfc); + r = BN_bn2bin(bn, bnbuf); + ASSERT_INT_GE(r, 0); + ASSERT_INT_EQ(r, (int)len); + ASSERT_MEM_EQ(bbuf, bnbuf, len); + + /* Test deserialisation */ + test_subtest_info("deserialise %d/%d/%d", + i, j, k); + bitmap_zero(b); + ASSERT_INT_EQ(bitmap_from_string(b, bnbuf, + len), 0); + for (n = 0; n < NTESTS; n++) { + ASSERT_INT_EQ(BN_is_bit_set(bn, n), + bitmap_test_bit(b, n)); + } + + /* Test clearing bits */ + test_subtest_info("clear %d/%d/%d", + i, j, k); + for (n = 0; n < NTESTS; n++) { + ASSERT_INT_EQ(bitmap_set_bit(b, n), 0); + ASSERT_INT_EQ(BN_set_bit(bn, n), 1); + } + if (i >= 0) { + bitmap_clear_bit(b, i); + BN_clear_bit(bn, i); + } + if (j >= 0) { + bitmap_clear_bit(b, j); + BN_clear_bit(bn, j); + } + if (k >= 0) { + bitmap_clear_bit(b, k); + BN_clear_bit(bn, k); + } + for (n = 0; n < NTESTS; n++) { + ASSERT_INT_EQ(BN_is_bit_set(bn, n), + bitmap_test_bit(b, n)); + } + } + } + } + bitmap_free(b); + BN_free(bn); + TEST_DONE(); +} + diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/Makefile b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/Makefile new file mode 100644 index 000000000..f52a85fb1 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/Makefile @@ -0,0 +1,12 @@ +# $OpenBSD: Makefile,v 1.1 2015/02/16 22:18:34 djm Exp $ + +TEST_ENV= "MALLOC_OPTIONS=AFGJPRX" + +PROG=test_hostkeys +SRCS=tests.c test_iterate.c +REGRESS_TARGETS=run-regress-${PROG} + +run-regress-${PROG}: ${PROG} + env ${TEST_ENV} ./${PROG} -d ${.CURDIR}/testdata + +.include diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/mktestdata.sh b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/mktestdata.sh new file mode 100644 index 000000000..36890ba11 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/mktestdata.sh @@ -0,0 +1,94 @@ +#!/bin/sh +# $OpenBSD: mktestdata.sh,v 1.1 2015/02/16 22:18:34 djm Exp $ + +set -ex + +cd testdata + +rm -f rsa1* rsa* dsa* ecdsa* ed25519* +rm -f known_hosts* + +gen_all() { + _n=$1 + _ecdsa_bits=256 + test "x$_n" = "x1" && _ecdsa_bits=384 + test "x$_n" = "x2" && _ecdsa_bits=521 + ssh-keygen -qt rsa1 -b 1024 -C "RSA1 #$_n" -N "" -f rsa1_$_n + ssh-keygen -qt rsa -b 1024 -C "RSA #$_n" -N "" -f rsa_$_n + ssh-keygen -qt dsa -b 1024 -C "DSA #$_n" -N "" -f dsa_$_n + ssh-keygen -qt ecdsa -b $_ecdsa_bits -C "ECDSA #$_n" -N "" -f ecdsa_$_n + ssh-keygen -qt ed25519 -C "ED25519 #$_n" -N "" -f ed25519_$_n + # Don't need private keys + rm -f rsa1_$_n rsa_$_n dsa_$_n ecdsa_$_n ed25519_$_n +} + +hentries() { + _preamble=$1 + _kspec=$2 + for k in `ls -1 $_kspec | sort` ; do + printf "$_preamble " + cat $k + done + echo +} + +gen_all 1 +gen_all 2 +gen_all 3 +gen_all 4 +gen_all 5 +gen_all 6 + +# A section of known_hosts with hashed hostnames. +( + hentries "sisyphus.example.com" "*_5.pub" + hentries "prometheus.example.com,192.0.2.1,2001:db8::1" "*_6.pub" +) > known_hosts_hash_frag +ssh-keygen -Hf known_hosts_hash_frag +rm -f known_hosts_hash_frag.old + +# Populated known_hosts, including comments, hashed names and invalid lines +( + echo "# Plain host keys, plain host names" + hentries "sisyphus.example.com" "*_1.pub" + + echo "# Plain host keys, hostnames + addresses" + hentries "prometheus.example.com,192.0.2.1,2001:db8::1" "*_2.pub" + + echo "# Some hosts with wildcard names / IPs" + hentries "*.example.com,192.0.2.*,2001:*" "*_3.pub" + + echo "# Hashed hostname and address entries" + cat known_hosts_hash_frag + rm -f known_hosts_hash_frag + echo + + echo "# Revoked and CA keys" + printf "@revoked sisyphus.example.com " ; cat rsa1_4.pub + printf "@revoked sisyphus.example.com " ; cat ed25519_4.pub + printf "@cert-authority prometheus.example.com " ; cat ecdsa_4.pub + printf "@cert-authority *.example.com " ; cat dsa_4.pub + + printf "\n" + echo "# Some invalid lines" + # Invalid marker + printf "@what sisyphus.example.com " ; cat rsa1_1.pub + # Key missing + echo "sisyphus.example.com " + # Key blob missing + echo "prometheus.example.com ssh-ed25519 " + # Key blob truncated + echo "sisyphus.example.com ssh-dsa AAAATgAAAAdz" + # RSA1 key truncated after key bits + echo "prometheus.example.com 1024 " + # RSA1 key truncated after exponent + echo "sisyphus.example.com 1024 65535 " + # RSA1 key incorrect key bits + printf "prometheus.example.com 1025 " ; cut -d' ' -f2- < rsa1_1.pub + # Invalid type + echo "sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg==" + # Type mismatch with blob + echo "prometheus.example.com ssh-rsa AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg==" +) > known_hosts + +echo OK diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/test_iterate.c b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/test_iterate.c new file mode 100644 index 000000000..2eaaf063a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/test_iterate.c @@ -0,0 +1,1171 @@ +/* $OpenBSD: test_iterate.c,v 1.4 2015/03/31 22:59:01 djm Exp $ */ +/* + * Regress test for hostfile.h hostkeys_foreach() + * + * Placed in the public domain + */ + +#include "includes.h" + +#include +#include +#include +#ifdef HAVE_STDINT_H +#include +#endif +#include +#include + +#include "../test_helper/test_helper.h" + +#include "sshkey.h" +#include "authfile.h" +#include "hostfile.h" + +struct expected { + const char *key_file; /* Path for key, NULL for none */ + int no_parse_status; /* Expected status w/o key parsing */ + int no_parse_keytype; /* Expected keytype w/o key parsing */ + int match_host_p; /* Match 'prometheus.example.com' */ + int match_host_s; /* Match 'sisyphus.example.com' */ + int match_ipv4; /* Match '192.0.2.1' */ + int match_ipv6; /* Match '2001:db8::1' */ + int match_flags; /* Expected flags from match */ + struct hostkey_foreach_line l; /* Expected line contents */ +}; + +struct cbctx { + const struct expected *expected; + size_t nexpected; + size_t i; + int flags; + int match_host_p; + int match_host_s; + int match_ipv4; + int match_ipv6; +}; + +/* + * hostkeys_foreach() iterator callback that verifies the line passed + * against an array of expected entries. + */ +static int +check(struct hostkey_foreach_line *l, void *_ctx) +{ + struct cbctx *ctx = (struct cbctx *)_ctx; + const struct expected *expected; + int parse_key = (ctx->flags & HKF_WANT_PARSE_KEY) != 0; + const int matching = (ctx->flags & HKF_WANT_MATCH) != 0; + u_int expected_status, expected_match; + int expected_keytype; + + test_subtest_info("entry %zu/%zu, file line %ld", + ctx->i + 1, ctx->nexpected, l->linenum); + + for (;;) { + ASSERT_SIZE_T_LT(ctx->i, ctx->nexpected); + expected = ctx->expected + ctx->i++; + /* If we are matching host/IP then skip entries that don't */ + if (!matching) + break; + if (ctx->match_host_p && expected->match_host_p) + break; + if (ctx->match_host_s && expected->match_host_s) + break; + if (ctx->match_ipv4 && expected->match_ipv4) + break; + if (ctx->match_ipv6 && expected->match_ipv6) + break; + } + expected_status = (parse_key || expected->no_parse_status < 0) ? + expected->l.status : (u_int)expected->no_parse_status; + expected_match = expected->l.match; +#define UPDATE_MATCH_STATUS(x) do { \ + if (ctx->x && expected->x) { \ + expected_match |= expected->x; \ + if (expected_status == HKF_STATUS_OK) \ + expected_status = HKF_STATUS_MATCHED; \ + } \ + } while (0) + expected_keytype = (parse_key || expected->no_parse_keytype < 0) ? + expected->l.keytype : expected->no_parse_keytype; + +#ifndef WITH_SSH1 + if (parse_key && (expected->l.keytype == KEY_RSA1 || + expected->no_parse_keytype == KEY_RSA1)) { + expected_status = HKF_STATUS_INVALID; + expected_keytype = KEY_UNSPEC; + parse_key = 0; + } +#endif +#ifndef OPENSSL_HAS_ECC + if (expected->l.keytype == KEY_ECDSA || + expected->no_parse_keytype == KEY_ECDSA) { + expected_status = HKF_STATUS_INVALID; + expected_keytype = KEY_UNSPEC; + parse_key = 0; + } +#endif + + UPDATE_MATCH_STATUS(match_host_p); + UPDATE_MATCH_STATUS(match_host_s); + UPDATE_MATCH_STATUS(match_ipv4); + UPDATE_MATCH_STATUS(match_ipv6); + + ASSERT_PTR_NE(l->path, NULL); /* Don't care about path */ + ASSERT_LONG_LONG_EQ(l->linenum, expected->l.linenum); + ASSERT_U_INT_EQ(l->status, expected_status); + ASSERT_U_INT_EQ(l->match, expected_match); + /* Not all test entries contain fulltext */ + if (expected->l.line != NULL) + ASSERT_STRING_EQ(l->line, expected->l.line); + ASSERT_INT_EQ(l->marker, expected->l.marker); + /* XXX we skip hashed hostnames for now; implement checking */ + if (expected->l.hosts != NULL) + ASSERT_STRING_EQ(l->hosts, expected->l.hosts); + /* Not all test entries contain raw keys */ + if (expected->l.rawkey != NULL) + ASSERT_STRING_EQ(l->rawkey, expected->l.rawkey); + /* XXX synthesise raw key for cases lacking and compare */ + ASSERT_INT_EQ(l->keytype, expected_keytype); + if (parse_key) { + if (expected->l.key == NULL) + ASSERT_PTR_EQ(l->key, NULL); + if (expected->l.key != NULL) { + ASSERT_PTR_NE(l->key, NULL); + ASSERT_INT_EQ(sshkey_equal(l->key, expected->l.key), 1); + } + } + if (parse_key && !(l->comment == NULL && expected->l.comment == NULL)) + ASSERT_STRING_EQ(l->comment, expected->l.comment); + return 0; +} + +/* Loads public keys for a set of expected results */ +static void +prepare_expected(struct expected *expected, size_t n) +{ + size_t i; + + for (i = 0; i < n; i++) { + if (expected[i].key_file == NULL) + continue; +#ifndef WITH_SSH1 + if (expected[i].l.keytype == KEY_RSA1) + continue; +#endif +#ifndef OPENSSL_HAS_ECC + if (expected[i].l.keytype == KEY_ECDSA) + continue; +#endif + ASSERT_INT_EQ(sshkey_load_public( + test_data_file(expected[i].key_file), &expected[i].l.key, + NULL), 0); + } +} + +struct expected expected_full[] = { + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, /* path, don't care */ + 1, /* line number */ + HKF_STATUS_COMMENT, /* status */ + 0, /* match flags */ + "# Plain host keys, plain host names", /* full line, optional */ + MRK_NONE, /* marker (CA / revoked) */ + NULL, /* hosts text */ + NULL, /* raw key, optional */ + KEY_UNSPEC, /* key type */ + NULL, /* deserialised key */ + NULL, /* comment */ + } }, + { "dsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 2, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "sisyphus.example.com", + NULL, + KEY_DSA, + NULL, /* filled at runtime */ + "DSA #1", + } }, + { "ecdsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 3, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "sisyphus.example.com", + NULL, + KEY_ECDSA, + NULL, /* filled at runtime */ + "ECDSA #1", + } }, + { "ed25519_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 4, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "sisyphus.example.com", + NULL, + KEY_ED25519, + NULL, /* filled at runtime */ + "ED25519 #1", + } }, + { "rsa1_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 5, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "sisyphus.example.com", + NULL, + KEY_RSA1, + NULL, /* filled at runtime */ + "RSA1 #1", + } }, + { "rsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 6, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "sisyphus.example.com", + NULL, + KEY_RSA, + NULL, /* filled at runtime */ + "RSA #1", + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 7, + HKF_STATUS_COMMENT, + 0, + "", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 8, + HKF_STATUS_COMMENT, + 0, + "# Plain host keys, hostnames + addresses", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { "dsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { + NULL, + 9, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "prometheus.example.com,192.0.2.1,2001:db8::1", + NULL, + KEY_DSA, + NULL, /* filled at runtime */ + "DSA #2", + } }, + { "ecdsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { + NULL, + 10, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "prometheus.example.com,192.0.2.1,2001:db8::1", + NULL, + KEY_ECDSA, + NULL, /* filled at runtime */ + "ECDSA #2", + } }, + { "ed25519_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { + NULL, + 11, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "prometheus.example.com,192.0.2.1,2001:db8::1", + NULL, + KEY_ED25519, + NULL, /* filled at runtime */ + "ED25519 #2", + } }, + { "rsa1_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { + NULL, + 12, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "prometheus.example.com,192.0.2.1,2001:db8::1", + NULL, + KEY_RSA1, + NULL, /* filled at runtime */ + "RSA1 #2", + } }, + { "rsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { + NULL, + 13, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "prometheus.example.com,192.0.2.1,2001:db8::1", + NULL, + KEY_RSA, + NULL, /* filled at runtime */ + "RSA #2", + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 14, + HKF_STATUS_COMMENT, + 0, + "", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 15, + HKF_STATUS_COMMENT, + 0, + "# Some hosts with wildcard names / IPs", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { "dsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { + NULL, + 16, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "*.example.com,192.0.2.*,2001:*", + NULL, + KEY_DSA, + NULL, /* filled at runtime */ + "DSA #3", + } }, + { "ecdsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { + NULL, + 17, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "*.example.com,192.0.2.*,2001:*", + NULL, + KEY_ECDSA, + NULL, /* filled at runtime */ + "ECDSA #3", + } }, + { "ed25519_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { + NULL, + 18, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "*.example.com,192.0.2.*,2001:*", + NULL, + KEY_ED25519, + NULL, /* filled at runtime */ + "ED25519 #3", + } }, + { "rsa1_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { + NULL, + 19, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "*.example.com,192.0.2.*,2001:*", + NULL, + KEY_RSA1, + NULL, /* filled at runtime */ + "RSA1 #3", + } }, + { "rsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { + NULL, + 20, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "*.example.com,192.0.2.*,2001:*", + NULL, + KEY_RSA, + NULL, /* filled at runtime */ + "RSA #3", + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 21, + HKF_STATUS_COMMENT, + 0, + "", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 22, + HKF_STATUS_COMMENT, + 0, + "# Hashed hostname and address entries", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { "dsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { + NULL, + 23, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_DSA, + NULL, /* filled at runtime */ + "DSA #5", + } }, + { "ecdsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { + NULL, + 24, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_ECDSA, + NULL, /* filled at runtime */ + "ECDSA #5", + } }, + { "ed25519_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { + NULL, + 25, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_ED25519, + NULL, /* filled at runtime */ + "ED25519 #5", + } }, + { "rsa1_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { + NULL, + 26, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_RSA1, + NULL, /* filled at runtime */ + "RSA1 #5", + } }, + { "rsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { + NULL, + 27, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_RSA, + NULL, /* filled at runtime */ + "RSA #5", + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 28, + HKF_STATUS_COMMENT, + 0, + "", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + /* + * The next series have each key listed multiple times, as the + * hostname and addresses in the pre-hashed known_hosts are split + * to separate lines. + */ + { "dsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { + NULL, + 29, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_DSA, + NULL, /* filled at runtime */ + "DSA #6", + } }, + { "dsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { + NULL, + 30, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_DSA, + NULL, /* filled at runtime */ + "DSA #6", + } }, + { "dsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { + NULL, + 31, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_DSA, + NULL, /* filled at runtime */ + "DSA #6", + } }, + { "ecdsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { + NULL, + 32, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_ECDSA, + NULL, /* filled at runtime */ + "ECDSA #6", + } }, + { "ecdsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { + NULL, + 33, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_ECDSA, + NULL, /* filled at runtime */ + "ECDSA #6", + } }, + { "ecdsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { + NULL, + 34, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_ECDSA, + NULL, /* filled at runtime */ + "ECDSA #6", + } }, + { "ed25519_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { + NULL, + 35, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_ED25519, + NULL, /* filled at runtime */ + "ED25519 #6", + } }, + { "ed25519_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { + NULL, + 36, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_ED25519, + NULL, /* filled at runtime */ + "ED25519 #6", + } }, + { "ed25519_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { + NULL, + 37, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_ED25519, + NULL, /* filled at runtime */ + "ED25519 #6", + } }, + { "rsa1_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { + NULL, + 38, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_RSA1, + NULL, /* filled at runtime */ + "RSA1 #6", + } }, + { "rsa1_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { + NULL, + 39, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_RSA1, + NULL, /* filled at runtime */ + "RSA1 #6", + } }, + { "rsa1_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { + NULL, + 40, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_RSA1, + NULL, /* filled at runtime */ + "RSA1 #6", + } }, + { "rsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { + NULL, + 41, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_RSA, + NULL, /* filled at runtime */ + "RSA #6", + } }, + { "rsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { + NULL, + 42, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_RSA, + NULL, /* filled at runtime */ + "RSA #6", + } }, + { "rsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { + NULL, + 43, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_RSA, + NULL, /* filled at runtime */ + "RSA #6", + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 44, + HKF_STATUS_COMMENT, + 0, + "", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 45, + HKF_STATUS_COMMENT, + 0, + "", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 46, + HKF_STATUS_COMMENT, + 0, + "# Revoked and CA keys", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { "rsa1_4.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 47, + HKF_STATUS_OK, + 0, + NULL, + MRK_REVOKE, + "sisyphus.example.com", + NULL, + KEY_RSA1, + NULL, /* filled at runtime */ + "RSA1 #4", + } }, + { "ed25519_4.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 48, + HKF_STATUS_OK, + 0, + NULL, + MRK_REVOKE, + "sisyphus.example.com", + NULL, + KEY_ED25519, + NULL, /* filled at runtime */ + "ED25519 #4", + } }, + { "ecdsa_4.pub" , -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { + NULL, + 49, + HKF_STATUS_OK, + 0, + NULL, + MRK_CA, + "prometheus.example.com", + NULL, + KEY_ECDSA, + NULL, /* filled at runtime */ + "ECDSA #4", + } }, + { "dsa_4.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 50, + HKF_STATUS_OK, + 0, + NULL, + MRK_CA, + "*.example.com", + NULL, + KEY_DSA, + NULL, /* filled at runtime */ + "DSA #4", + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 51, + HKF_STATUS_COMMENT, + 0, + "", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 52, + HKF_STATUS_COMMENT, + 0, + "# Some invalid lines", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 53, + HKF_STATUS_INVALID, + 0, + NULL, + MRK_ERROR, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 54, + HKF_STATUS_INVALID, + 0, + NULL, + MRK_NONE, + "sisyphus.example.com", + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { + NULL, + 55, + HKF_STATUS_INVALID, + 0, + NULL, + MRK_NONE, + "prometheus.example.com", + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 56, + HKF_STATUS_INVALID, /* Would be ok if key not parsed */ + 0, + NULL, + MRK_NONE, + "sisyphus.example.com", + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { + NULL, + 57, + HKF_STATUS_INVALID, /* Would be ok if key not parsed */ + 0, + NULL, + MRK_NONE, + "prometheus.example.com", + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, HKF_STATUS_OK, KEY_RSA1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 58, + HKF_STATUS_INVALID, /* Would be ok if key not parsed */ + 0, + NULL, + MRK_NONE, + "sisyphus.example.com", + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, HKF_STATUS_OK, KEY_RSA1, HKF_MATCH_HOST, 0, 0, 0, -1, { + NULL, + 59, + HKF_STATUS_INVALID, /* Would be ok if key not parsed */ + 0, + NULL, + MRK_NONE, + "prometheus.example.com", + NULL, + KEY_UNSPEC, + NULL, /* filled at runtime */ + NULL, + } }, + { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 60, + HKF_STATUS_INVALID, + 0, + NULL, + MRK_NONE, + "sisyphus.example.com", + NULL, + KEY_UNSPEC, + NULL, /* filled at runtime */ + NULL, + } }, + { NULL, HKF_STATUS_OK, KEY_RSA, HKF_MATCH_HOST, 0, 0, 0, -1, { + NULL, + 61, + HKF_STATUS_INVALID, /* Would be ok if key not parsed */ + 0, + NULL, + MRK_NONE, + "prometheus.example.com", + NULL, + KEY_UNSPEC, + NULL, /* filled at runtime */ + NULL, + } }, +}; + +void test_iterate(void); + +void +test_iterate(void) +{ + struct cbctx ctx; + + TEST_START("hostkeys_iterate all with key parse"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = HKF_WANT_PARSE_KEY; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, NULL, NULL, ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate all without key parse"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = 0; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, NULL, NULL, ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate specify host 1"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = 0; + ctx.match_host_p = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "prometheus.example.com", NULL, ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate specify host 2"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = 0; + ctx.match_host_s = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "sisyphus.example.com", NULL, ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate match host 1"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = HKF_WANT_MATCH; + ctx.match_host_p = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "prometheus.example.com", NULL, ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate match host 2"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = HKF_WANT_MATCH; + ctx.match_host_s = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "sisyphus.example.com", NULL, ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate specify host missing"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = 0; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "actaeon.example.org", NULL, ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate match host missing"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = HKF_WANT_MATCH; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "actaeon.example.org", NULL, ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate specify IPv4"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = 0; + ctx.match_ipv4 = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate specify IPv6"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = 0; + ctx.match_ipv6 = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "tiresias.example.org", "2001:db8::1", ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate match IPv4"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = HKF_WANT_MATCH; + ctx.match_ipv4 = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate match IPv6"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = HKF_WANT_MATCH; + ctx.match_ipv6 = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "tiresias.example.org", "2001:db8::1", ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate specify addr missing"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = 0; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "tiresias.example.org", "192.168.0.1", ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate match addr missing"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = HKF_WANT_MATCH; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "tiresias.example.org", "::1", ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate specify host 2 and IPv4"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = 0; + ctx.match_host_s = 1; + ctx.match_ipv4 = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "sisyphus.example.com", "192.0.2.1", ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate match host 1 and IPv6"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = HKF_WANT_MATCH; + ctx.match_host_p = 1; + ctx.match_ipv6 = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "prometheus.example.com", "2001:db8::1", ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate specify host 2 and IPv4 w/ key parse"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = HKF_WANT_PARSE_KEY; + ctx.match_host_s = 1; + ctx.match_ipv4 = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "sisyphus.example.com", "192.0.2.1", ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate match host 1 and IPv6 w/ key parse"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = HKF_WANT_MATCH|HKF_WANT_PARSE_KEY; + ctx.match_host_p = 1; + ctx.match_ipv6 = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "prometheus.example.com", "2001:db8::1", ctx.flags), 0); + TEST_DONE(); +} + diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_1.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_1.pub new file mode 100644 index 000000000..56e1e3714 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_1.pub @@ -0,0 +1 @@ +ssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_2.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_2.pub new file mode 100644 index 000000000..394e0bf00 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_2.pub @@ -0,0 +1 @@ +ssh-dss AAAAB3NzaC1kc3MAAACBAI38Hy/61/O5Bp6yUG8J5XQCeNjRS0xvjlCdzKLyXCueMa+L+X2L/u9PWUsy5SVbTjGgpB8sF6UkCNsV+va7S8zCCHas2MZ7GPlxP6GZBkRPTIFR0N/Pu7wfBzDQz0t0iL4VmxBfTBQv/SxkGWZg+yHihIQP9fwdSAwD/7aVh6ItAAAAFQDSyihIUlINlswM0PJ8wXSti3yIMwAAAIB+oqzaB6ozqs8YxpN5oQOBa/9HEBQEsp8RSIlQmVubXRNgktp42n+Ii1waU9UUk8DX5ahhIeR6B7ojWkqmDAji4SKpoHf4kmr6HvYo85ZSTSx0W4YK/gJHSpDJwhlT52tAfb1JCbWSObjl09B4STv7KedCHcR5oXQvvrV+XoKOSAAAAIAue/EXrs2INw1RfaKNHC0oqOMxmRitv0BFMuNVPo1VDj39CE5kA7AHjwvS1TNeaHtK5Hhgeb6vsmLmNPTOc8xCob0ilyQbt9O0GbONeF2Ge7D2UJyULA/hxql+tCYFIC6yUrmo35fF9XiNisXLoaflk9fjp7ROWWVwnki/jstaQw== DSA #2 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_3.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_3.pub new file mode 100644 index 000000000..e506ea422 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_3.pub @@ -0,0 +1 @@ +ssh-dss AAAAB3NzaC1kc3MAAACBAI6lz2Ip9bzE7TGuDD4SjO9S4Ac90gq0h6ai1O06eI8t/Ot2uJ5Jk2QyVr2jvIZHDl/5bwBx7+5oyjlwRoUrAPPD814wf5tU2tSnmdu1Wbf0cBswif5q0r4tevzmopp/AtgH11QHo3u0/pfyJd10qBDLV2FaYSKMmZvyPfZJ0s9pAAAAFQD5Eqjl6Rx2qVePodD9OwAPT0bU6wAAAIAfnDm6csZF0sFaJR3NIJvaYgSGr8s7cqlsk2gLltB/1wOOO2yX+NeEC+B0H93hlMfaUsPa08bwgmYxnavSMqEBpmtPceefJiEd68zwYqXd38f88wyWZ9Z5iwaI/6OVZPHzCbDxOa4ewVTevRNYUKP1xUTZNT8/gSMfZLYPk4T2AQAAAIAUKroozRMyV+3V/rxt0gFnNxRXBKk+9cl3vgsQ7ktkI9cYg7V1T2K0XF21AVMK9gODszy6PBJjV6ruXBV6TRiqIbQauivp3bHHKYsG6wiJNqwdbVwIjfvv8nn1qFoZQLXG3sdONr9NwN8KzrX89OV0BlR2dVM5qqp+YxOXymP9yg== DSA #3 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_4.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_4.pub new file mode 100644 index 000000000..8552c3819 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_4.pub @@ -0,0 +1 @@ +ssh-dss AAAAB3NzaC1kc3MAAACBAKvjnFHm0VvMr5h2Zu3nURsxQKGoxm+DCzYDxRYcilK07Cm5c4XTrFbA2X86+9sGs++W7QRMcTJUYIg0a+UtIMtAjwORd6ZPXM2K5dBW+gh1oHyvKi767tWX7I2c+1ZPJDY95mUUfZQUEfdy9eGDSBmw/pSsveQ1ur6XNUh/MtP/AAAAFQDHnXk/9jBJAdce1pHtLWnbdPSGdQAAAIEAm2OLy8tZBfiEO3c3X1yyB/GTcDwrQCqRMDkhnsmrliec3dWkOfNTzu+MrdvF8ymTWLEqPpbMheYtvNyZ3TF0HO5W7aVBpdGZbOdOAIfB+6skqGbI8A5Up1d7dak/bSsqL2r5NjwbDOdq+1hBzzvbl/qjh+sQarV2zHrpKoQaV28AAACANtkBVedBbqIAdphCrN/LbUi9WlyuF9UZz+tlpVLYrj8GJVwnplV2tvOmUw6yP5/pzCimTsao8dpL5PWxm7fKxLWVxA+lEsA4WeC885CiZn8xhdaJOCN+NyJ2bqkz+4VPI7oDGBm0aFwUqJn+M1PiSgvI50XdF2dBsFRTRNY0wzA= DSA #4 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_5.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_5.pub new file mode 100644 index 000000000..149e1efd1 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_5.pub @@ -0,0 +1 @@ +ssh-dss AAAAB3NzaC1kc3MAAACBALrFy7w5ihlaOG+qR+6fj+vm5EQaO3qwxgACLcgH+VfShuOG4mkx8qFJmf+OZ3fh5iKngjNZfKtfcqI7zHWdk6378TQfQC52/kbZukjNXOLCpyNkogahcjA00onIoTK1RUDuMW28edAHwPFbpttXDTaqis+8JPMY8hZwsZGENCzTAAAAFQD6+It5vozwGgaN9ROYPMlByhi6jwAAAIBz2mcAC694vNzz9b6614gkX9d9E99PzJYfU1MPkXDziKg7MrjBw7Opd5y1jL09S3iL6lSTlHkKwVKvQ3pOwWRwXXRrKVus4I0STveoApm526jmp6mY0YEtqR98vMJ0v97h1ydt8FikKlihefCsnXVicb8887PXs2Y8C6GuFT3tfQAAAIBbmHtV5tPcrMRDkULhaQ/Whap2VKvT2DUhIHA7lx6oy/KpkltOpxDZOIGUHKqffGbiR7Jh01/y090AY5L2eCf0S2Ytx93+eADwVVpJbFJo6zSwfeey2Gm6L2oA+rCz9zTdmtZoekpD3/RAOQjnJIAPwbs7mXwabZTw4xRtiYIRrw== DSA #5 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_6.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_6.pub new file mode 100644 index 000000000..edbb97643 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/dsa_6.pub @@ -0,0 +1 @@ +ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_1.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_1.pub new file mode 100644 index 000000000..16a535bcc --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_1.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF6yQEtD9yBw9gmDRf477WBBzvWhAa0ioBI3nbA4emKykj0RbuQd5C4XdQAEOZGzE7v//FcCjwB2wi+JH5eKkxCtN6CjohDASZ1huoIV2UVyYIicZJEEOg1IWjjphvaxtw== ECDSA #1 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_2.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_2.pub new file mode 100644 index 000000000..d2bad11e2 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_2.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB8qVcXwgBM92NCmReQlPrZAoui4Bz/mW0VUBFOpHXXW1n+15b/Y7Pc6UBd/ITTZmaBciXY+PWaSBGdwc5GdqGdLgFyJ/QAGrFMPNpVutm/82gNQzlxpNwjbMcKyiZEXzSgnjS6DzMQ0WuSMdzIBXq8OW/Kafxg4ZkU6YqALUXxlQMZuQ== ECDSA #2 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_3.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_3.pub new file mode 100644 index 000000000..e3ea9254e --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_3.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIb3BhJZk+vUQPg5TQc1koIzuGqloCq7wjr9LjlhG24IBeiFHLsdWw74HDlH4DrOmlxToVYk2lTdnjARleRByjk= ECDSA #3 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_4.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_4.pub new file mode 100644 index 000000000..2d616f5c6 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_4.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHZd0OXHIWwK3xnjAdMZ1tojxWycdu38pORO/UX5cqsKMgGCKQVBWWO3TFk1ePkGIE9VMWT1hCGqWRRwYlH+dSE= ECDSA #4 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_5.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_5.pub new file mode 100644 index 000000000..a3df9b3f4 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_5.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIudcagzq4QPtP1jkpje34+0POLB0jwT64hqrbCqhTH2T800KDZ0h2vwlJYa3OP3Oqru9AB5pnuHsKw7mAhUGY= ECDSA #5 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_6.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_6.pub new file mode 100644 index 000000000..139f5a7bf --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ecdsa_6.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_1.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_1.pub new file mode 100644 index 000000000..0b12efedb --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_1.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9ks7jkua5YWIwByRnnnc6UPJQWI75O0e/UJdPYU1JI ED25519 #1 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_2.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_2.pub new file mode 100644 index 000000000..78e262bcc --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_2.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBp6PVW0z2o9C4Ukv/JOgmK7QMFe1pD1s3ADFF7IQob ED25519 #2 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_3.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_3.pub new file mode 100644 index 000000000..64e5f12a6 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_3.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBlYfExtYZAPqYvYdrlpGlSWhh/XNHcH3v3c2JzsVNbB ED25519 #3 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_4.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_4.pub new file mode 100644 index 000000000..47b6724ec --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_4.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFP8L9REfN/iYy1KIRtFqSCn3V2+vOCpoZYENFGLdOF ED25519 #4 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_5.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_5.pub new file mode 100644 index 000000000..72ccae6fe --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_5.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINf63qSV8rD57N+digID8t28WVhd3Yf2K2UhaoG8TsWQ ED25519 #5 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_6.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_6.pub new file mode 100644 index 000000000..0f719731d --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/ed25519_6.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/known_hosts b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/known_hosts new file mode 100644 index 000000000..3740f674b --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/known_hosts @@ -0,0 +1,61 @@ +# Plain host keys, plain host names +sisyphus.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1 +sisyphus.example.com ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF6yQEtD9yBw9gmDRf477WBBzvWhAa0ioBI3nbA4emKykj0RbuQd5C4XdQAEOZGzE7v//FcCjwB2wi+JH5eKkxCtN6CjohDASZ1huoIV2UVyYIicZJEEOg1IWjjphvaxtw== ECDSA #1 +sisyphus.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9ks7jkua5YWIwByRnnnc6UPJQWI75O0e/UJdPYU1JI ED25519 #1 +sisyphus.example.com 1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1 +sisyphus.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDg4hB4vAZHJ0PVRiJajOv/GlytFWNpv5/9xgB9+5BIbvp8LOrFZ5D9K0Gsmwpd4G4rfaAz8j896DhMArg0vtkilIPPGt/6VzWMERgvaIQPJ/IE99X3+fjcAG56oAWwy29JX10lQMzBPU6XJIaN/zqpkb6qUBiAHBdLpxrFBBU0/w== RSA #1 + +# Plain host keys, hostnames + addresses +prometheus.example.com,192.0.2.1,2001:db8::1 ssh-dss AAAAB3NzaC1kc3MAAACBAI38Hy/61/O5Bp6yUG8J5XQCeNjRS0xvjlCdzKLyXCueMa+L+X2L/u9PWUsy5SVbTjGgpB8sF6UkCNsV+va7S8zCCHas2MZ7GPlxP6GZBkRPTIFR0N/Pu7wfBzDQz0t0iL4VmxBfTBQv/SxkGWZg+yHihIQP9fwdSAwD/7aVh6ItAAAAFQDSyihIUlINlswM0PJ8wXSti3yIMwAAAIB+oqzaB6ozqs8YxpN5oQOBa/9HEBQEsp8RSIlQmVubXRNgktp42n+Ii1waU9UUk8DX5ahhIeR6B7ojWkqmDAji4SKpoHf4kmr6HvYo85ZSTSx0W4YK/gJHSpDJwhlT52tAfb1JCbWSObjl09B4STv7KedCHcR5oXQvvrV+XoKOSAAAAIAue/EXrs2INw1RfaKNHC0oqOMxmRitv0BFMuNVPo1VDj39CE5kA7AHjwvS1TNeaHtK5Hhgeb6vsmLmNPTOc8xCob0ilyQbt9O0GbONeF2Ge7D2UJyULA/hxql+tCYFIC6yUrmo35fF9XiNisXLoaflk9fjp7ROWWVwnki/jstaQw== DSA #2 +prometheus.example.com,192.0.2.1,2001:db8::1 ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB8qVcXwgBM92NCmReQlPrZAoui4Bz/mW0VUBFOpHXXW1n+15b/Y7Pc6UBd/ITTZmaBciXY+PWaSBGdwc5GdqGdLgFyJ/QAGrFMPNpVutm/82gNQzlxpNwjbMcKyiZEXzSgnjS6DzMQ0WuSMdzIBXq8OW/Kafxg4ZkU6YqALUXxlQMZuQ== ECDSA #2 +prometheus.example.com,192.0.2.1,2001:db8::1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBp6PVW0z2o9C4Ukv/JOgmK7QMFe1pD1s3ADFF7IQob ED25519 #2 +prometheus.example.com,192.0.2.1,2001:db8::1 1024 65537 135970715082947442639683969597180728933388298633245835186618852623800675939308729462220235058285909679252157995530180587329132927339620517781785310829060832352381015614725360278571924286986474946772141568893116432268565829418506866604294073334978275702221949783314402806080929601995102334442541344606109853641 RSA1 #2 +prometheus.example.com,192.0.2.1,2001:db8::1 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDmbUhNabB5AmBDX6GNHZ3lbn7pRxqfpW+f53QqNGlK0sLV+0gkMIrOfUp1kdE2ZLE6tfzdicatj/RlH6/wuo4yyYb+Pyx3G0vxdmAIiA4aANq38XweDucBC0TZkRWVHK+Gs5V/uV0z7N0axJvkkJujMLvST3CRiiWwlficBc6yVQ== RSA #2 + +# Some hosts with wildcard names / IPs +*.example.com,192.0.2.*,2001:* ssh-dss AAAAB3NzaC1kc3MAAACBAI6lz2Ip9bzE7TGuDD4SjO9S4Ac90gq0h6ai1O06eI8t/Ot2uJ5Jk2QyVr2jvIZHDl/5bwBx7+5oyjlwRoUrAPPD814wf5tU2tSnmdu1Wbf0cBswif5q0r4tevzmopp/AtgH11QHo3u0/pfyJd10qBDLV2FaYSKMmZvyPfZJ0s9pAAAAFQD5Eqjl6Rx2qVePodD9OwAPT0bU6wAAAIAfnDm6csZF0sFaJR3NIJvaYgSGr8s7cqlsk2gLltB/1wOOO2yX+NeEC+B0H93hlMfaUsPa08bwgmYxnavSMqEBpmtPceefJiEd68zwYqXd38f88wyWZ9Z5iwaI/6OVZPHzCbDxOa4ewVTevRNYUKP1xUTZNT8/gSMfZLYPk4T2AQAAAIAUKroozRMyV+3V/rxt0gFnNxRXBKk+9cl3vgsQ7ktkI9cYg7V1T2K0XF21AVMK9gODszy6PBJjV6ruXBV6TRiqIbQauivp3bHHKYsG6wiJNqwdbVwIjfvv8nn1qFoZQLXG3sdONr9NwN8KzrX89OV0BlR2dVM5qqp+YxOXymP9yg== DSA #3 +*.example.com,192.0.2.*,2001:* ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIb3BhJZk+vUQPg5TQc1koIzuGqloCq7wjr9LjlhG24IBeiFHLsdWw74HDlH4DrOmlxToVYk2lTdnjARleRByjk= ECDSA #3 +*.example.com,192.0.2.*,2001:* ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBlYfExtYZAPqYvYdrlpGlSWhh/XNHcH3v3c2JzsVNbB ED25519 #3 +*.example.com,192.0.2.*,2001:* 1024 65537 125895605498029643697051635076028105429632810811904702876152645261610759866299221305725069141163240694267669117205342283569102183636228981857946763978553664895308762890072813014496700601576921921752482059207749978374872713540759920335553799711267170948655579130584031555334229966603000896364091459595522912269 RSA1 #3 +*.example.com,192.0.2.*,2001:* ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDX8F93W3SH4ZSus4XUQ2cw9dqcuyUETTlKEeGv3zlknV3YCoe2Mp04naDhiuwj8sOsytrZSESzLY1ZEyzrjxE6ZFVv8NKgck/AbRjcwlRFOcx9oKUxOrXRa0IoXlTq0kyjKCJfaHBKnGitZThknCPTbVmpATkm5xx6J0WEDozfoQ== RSA #3 + +# Hashed hostname and address entries +|1|6FWxoqTCAfm8sZ7T/q73OmxCFGM=|S4eQmusok4cbyDzzGEFGIAthDbw= ssh-dss AAAAB3NzaC1kc3MAAACBALrFy7w5ihlaOG+qR+6fj+vm5EQaO3qwxgACLcgH+VfShuOG4mkx8qFJmf+OZ3fh5iKngjNZfKtfcqI7zHWdk6378TQfQC52/kbZukjNXOLCpyNkogahcjA00onIoTK1RUDuMW28edAHwPFbpttXDTaqis+8JPMY8hZwsZGENCzTAAAAFQD6+It5vozwGgaN9ROYPMlByhi6jwAAAIBz2mcAC694vNzz9b6614gkX9d9E99PzJYfU1MPkXDziKg7MrjBw7Opd5y1jL09S3iL6lSTlHkKwVKvQ3pOwWRwXXRrKVus4I0STveoApm526jmp6mY0YEtqR98vMJ0v97h1ydt8FikKlihefCsnXVicb8887PXs2Y8C6GuFT3tfQAAAIBbmHtV5tPcrMRDkULhaQ/Whap2VKvT2DUhIHA7lx6oy/KpkltOpxDZOIGUHKqffGbiR7Jh01/y090AY5L2eCf0S2Ytx93+eADwVVpJbFJo6zSwfeey2Gm6L2oA+rCz9zTdmtZoekpD3/RAOQjnJIAPwbs7mXwabZTw4xRtiYIRrw== DSA #5 +|1|hTrfD0CuuB9ZbOa1CHFYvIk/gKE=|tPmW50t7flncm1UyM+DR97ubDNU= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIudcagzq4QPtP1jkpje34+0POLB0jwT64hqrbCqhTH2T800KDZ0h2vwlJYa3OP3Oqru9AB5pnuHsKw7mAhUGY= ECDSA #5 +|1|fOGqe75X5ZpTz4c7DitP4E8/y30=|Lmcch2fh54bUYoV//S2VqDFVeiY= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINf63qSV8rD57N+digID8t28WVhd3Yf2K2UhaoG8TsWQ ED25519 #5 +|1|0RVzLjY3lwE3MRweguaAXaCCWk8=|DbcIgJQcRZJMYI6NYDOM6oJycPk= 1024 65537 127931411493401587586867047972295564331543694182352197506125410692673654572057908999642645524647232712160516076508316152810117209181150078352725299319149726341058893406440426414316276977768958023952319602422835879783057966985348561111880658922724668687074412548487722084792283453716871417610020757212399252171 RSA1 #5 +|1|4q79XnHpKBNQhyMLAqbPPDN+JKo=|k1Wvjjb52zDdrXWM801+wX5oH8U= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC/C15Q4sfnk7BZff1er8bscay+5s51oD4eWArlHWMK/ZfYeeTAccTy+7B7Jv+MS4nKCpflrvJI2RQz4kS8vF0ATdBbi4jeWefStlHNg0HLhnCY7NAfDIlRdaN9lm3Pqm2vmr+CkqwcJaSpycDg8nPN9yNAuD6pv7NDuUnECezojQ== RSA #5 + +|1|0M6PIx6THA3ipIOvTl3fcgn2z+A=|bwEJAOwJz+Sm7orFdgj170mD/zY= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 +|1|a6WGHcL+9gX3e96tMlgDSDJwtSg=|5Dqlb/yqNEf7jgfllrp/ygLmRV8= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 +|1|OeCpi7Pn5Q6c8la4fPf9G8YctT8=|sC6D7lDXTafIpokZJ1+1xWg2R6Q= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 +|1|BHESVyiJ7G2NN0lxrw7vT109jmk=|TKof+015J77bXqibsh0N1Lp0MKk= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 +|1|wY53mZNASDJ5/P3JYCJ4FUNa6WQ=|v8p0MfV5lqlZB2J0yLxl/gsWVQo= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 +|1|horeoyFPwfKhyFN+zJZ5LCfOo/I=|2ofvp0tNwCbKsV8FuiFA4gQG2Z8= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 +|1|Aw4fXumZfx6jEIJuDGIyeEMd81A=|5FdLtdm2JeKNsS8IQeQlGYIadOE= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6 +|1|+dGUNpv6GblrDd5fgHLlOWpSbEo=|He/pQ1yJjtiCyTNWpGwjBD4sZFI= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6 +|1|E/PACGl8m1T7QnPedOoooozstP0=|w6DQAFT8yZgj0Hlkz5R1TppYHCA= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6 +|1|SaoyMStgxpYfwedSXBAghi8Zo0s=|Gz78k69GaE6iViV3OOvbStKqyTA= 1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6 +|1|8qfGeiT5WTCzWYbXPQ+lsLg7km4=|1sIBwiSUr8IGkvrUGm3/9QYurmA= 1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6 +|1|87M1OtyHg1BZiDY3rT6lYsZFnAU=|eddAQVcMNbn2OB87XWXFQnYo6R4= 1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6 +|1|60w3wFfC0XWI+rRmRlxIRhh8lwE=|yMhsGrzBJKiesAdSQ/PVgkCrDKk= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6 +|1|5gdEMmLUJC7grqWhRJPy2OTaSyE=|/XTfmLMa/B8npcVCGFRdaHl+d/0= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6 +|1|6FGCWUr42GHdMB/eifnHNCuwgdk=|ONJvYZ/ANmi59R5HrOhLPmvYENM= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6 + + +# Revoked and CA keys +@revoked sisyphus.example.com 1024 65537 174143366122697048196335388217056770310345753698079464367148030836533360510864881734142526411160017107552815906024399248049666856133771656680462456979369587903909343046704480897527203474513676654933090991684252819423129896444427656841613263783484827101210734799449281639493127615902427443211183258155381810593 RSA1 #4 +@revoked sisyphus.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFP8L9REfN/iYy1KIRtFqSCn3V2+vOCpoZYENFGLdOF ED25519 #4 +@cert-authority prometheus.example.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHZd0OXHIWwK3xnjAdMZ1tojxWycdu38pORO/UX5cqsKMgGCKQVBWWO3TFk1ePkGIE9VMWT1hCGqWRRwYlH+dSE= ECDSA #4 +@cert-authority *.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAKvjnFHm0VvMr5h2Zu3nURsxQKGoxm+DCzYDxRYcilK07Cm5c4XTrFbA2X86+9sGs++W7QRMcTJUYIg0a+UtIMtAjwORd6ZPXM2K5dBW+gh1oHyvKi767tWX7I2c+1ZPJDY95mUUfZQUEfdy9eGDSBmw/pSsveQ1ur6XNUh/MtP/AAAAFQDHnXk/9jBJAdce1pHtLWnbdPSGdQAAAIEAm2OLy8tZBfiEO3c3X1yyB/GTcDwrQCqRMDkhnsmrliec3dWkOfNTzu+MrdvF8ymTWLEqPpbMheYtvNyZ3TF0HO5W7aVBpdGZbOdOAIfB+6skqGbI8A5Up1d7dak/bSsqL2r5NjwbDOdq+1hBzzvbl/qjh+sQarV2zHrpKoQaV28AAACANtkBVedBbqIAdphCrN/LbUi9WlyuF9UZz+tlpVLYrj8GJVwnplV2tvOmUw6yP5/pzCimTsao8dpL5PWxm7fKxLWVxA+lEsA4WeC885CiZn8xhdaJOCN+NyJ2bqkz+4VPI7oDGBm0aFwUqJn+M1PiSgvI50XdF2dBsFRTRNY0wzA= DSA #4 + +# Some invalid lines +@what sisyphus.example.com 1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1 +sisyphus.example.com +prometheus.example.com ssh-ed25519 +sisyphus.example.com ssh-dsa AAAATgAAAAdz +prometheus.example.com 1024 +sisyphus.example.com 1024 65535 +prometheus.example.com 1025 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1 +sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg== +prometheus.example.com ssh-rsa AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg== diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_1.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_1.pub new file mode 100644 index 000000000..772ce9c05 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_1.pub @@ -0,0 +1 @@ +1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_2.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_2.pub new file mode 100644 index 000000000..78794b941 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_2.pub @@ -0,0 +1 @@ +1024 65537 135970715082947442639683969597180728933388298633245835186618852623800675939308729462220235058285909679252157995530180587329132927339620517781785310829060832352381015614725360278571924286986474946772141568893116432268565829418506866604294073334978275702221949783314402806080929601995102334442541344606109853641 RSA1 #2 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_3.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_3.pub new file mode 100644 index 000000000..0c035fe0a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_3.pub @@ -0,0 +1 @@ +1024 65537 125895605498029643697051635076028105429632810811904702876152645261610759866299221305725069141163240694267669117205342283569102183636228981857946763978553664895308762890072813014496700601576921921752482059207749978374872713540759920335553799711267170948655579130584031555334229966603000896364091459595522912269 RSA1 #3 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_4.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_4.pub new file mode 100644 index 000000000..00064423e --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_4.pub @@ -0,0 +1 @@ +1024 65537 174143366122697048196335388217056770310345753698079464367148030836533360510864881734142526411160017107552815906024399248049666856133771656680462456979369587903909343046704480897527203474513676654933090991684252819423129896444427656841613263783484827101210734799449281639493127615902427443211183258155381810593 RSA1 #4 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_5.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_5.pub new file mode 100644 index 000000000..bb53c2642 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_5.pub @@ -0,0 +1 @@ +1024 65537 127931411493401587586867047972295564331543694182352197506125410692673654572057908999642645524647232712160516076508316152810117209181150078352725299319149726341058893406440426414316276977768958023952319602422835879783057966985348561111880658922724668687074412548487722084792283453716871417610020757212399252171 RSA1 #5 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_6.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_6.pub new file mode 100644 index 000000000..85d6576b5 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa1_6.pub @@ -0,0 +1 @@ +1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_1.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_1.pub new file mode 100644 index 000000000..2b87885a1 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_1.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDg4hB4vAZHJ0PVRiJajOv/GlytFWNpv5/9xgB9+5BIbvp8LOrFZ5D9K0Gsmwpd4G4rfaAz8j896DhMArg0vtkilIPPGt/6VzWMERgvaIQPJ/IE99X3+fjcAG56oAWwy29JX10lQMzBPU6XJIaN/zqpkb6qUBiAHBdLpxrFBBU0/w== RSA #1 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_2.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_2.pub new file mode 100644 index 000000000..33f1fd93b --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_2.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDmbUhNabB5AmBDX6GNHZ3lbn7pRxqfpW+f53QqNGlK0sLV+0gkMIrOfUp1kdE2ZLE6tfzdicatj/RlH6/wuo4yyYb+Pyx3G0vxdmAIiA4aANq38XweDucBC0TZkRWVHK+Gs5V/uV0z7N0axJvkkJujMLvST3CRiiWwlficBc6yVQ== RSA #2 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_3.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_3.pub new file mode 100644 index 000000000..c2f6b208c --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_3.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDX8F93W3SH4ZSus4XUQ2cw9dqcuyUETTlKEeGv3zlknV3YCoe2Mp04naDhiuwj8sOsytrZSESzLY1ZEyzrjxE6ZFVv8NKgck/AbRjcwlRFOcx9oKUxOrXRa0IoXlTq0kyjKCJfaHBKnGitZThknCPTbVmpATkm5xx6J0WEDozfoQ== RSA #3 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_4.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_4.pub new file mode 100644 index 000000000..35545a713 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_4.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDI8AdjBAozcdRnIikVlt69iyDHKyrtxmpdkbRy9bWaL86OH+PTmLUk5e+T/ufiakpeE2pm0hkE3e4Sh/FsY+rsQdRoraWVNFfchcMeVlKvuy5RZN0ElvmaQebOJUeNeBn2LLw8aL8bJ4CP/bQRKrmrSSqjz3+4H9YNVyyk1OGBPQ== RSA #4 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_5.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_5.pub new file mode 100644 index 000000000..befbaa7d9 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_5.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC/C15Q4sfnk7BZff1er8bscay+5s51oD4eWArlHWMK/ZfYeeTAccTy+7B7Jv+MS4nKCpflrvJI2RQz4kS8vF0ATdBbi4jeWefStlHNg0HLhnCY7NAfDIlRdaN9lm3Pqm2vmr+CkqwcJaSpycDg8nPN9yNAuD6pv7NDuUnECezojQ== RSA #5 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_6.pub b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_6.pub new file mode 100644 index 000000000..393e11672 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/testdata/rsa_6.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/tests.c b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/tests.c new file mode 100644 index 000000000..92c7646ad --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/hostkeys/tests.c @@ -0,0 +1,16 @@ +/* $OpenBSD: tests.c,v 1.1 2015/02/16 22:18:34 djm Exp $ */ +/* + * Regress test for known_hosts-related API. + * + * Placed in the public domain + */ + +void tests(void); +void test_iterate(void); /* test_iterate.c */ + +void +tests(void) +{ + test_iterate(); +} + diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/kex/Makefile b/crypto/external/bsd/openssh/dist/regress/unittests/kex/Makefile new file mode 100644 index 000000000..6532cb00a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/kex/Makefile @@ -0,0 +1,14 @@ +# $OpenBSD: Makefile,v 1.2 2015/01/24 10:39:21 miod Exp $ + +TEST_ENV= "MALLOC_OPTIONS=AFGJPRX" + +PROG=test_kex +SRCS=tests.c test_kex.c +REGRESS_TARGETS=run-regress-${PROG} + +run-regress-${PROG}: ${PROG} + env ${TEST_ENV} ./${PROG} + +.include + +LDADD+=-lz diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/kex/test_kex.c b/crypto/external/bsd/openssh/dist/regress/unittests/kex/test_kex.c new file mode 100644 index 000000000..6e5999bb9 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/kex/test_kex.c @@ -0,0 +1,202 @@ +/* $OpenBSD: test_kex.c,v 1.2 2015/07/10 06:23:25 markus Exp $ */ +/* + * Regress test KEX + * + * Placed in the public domain + */ + +#include "includes.h" + +#include +#include +#include +#ifdef HAVE_STDINT_H +#include +#endif +#include +#include + +#include "../test_helper/test_helper.h" + +#include "ssherr.h" +#include "ssh_api.h" +#include "sshbuf.h" +#include "packet.h" +#include "myproposal.h" + +struct ssh *active_state = NULL; /* XXX - needed for linking */ + +void kex_tests(void); +static int do_debug = 0; + +static int +do_send_and_receive(struct ssh *from, struct ssh *to) +{ + u_char type; + size_t len; + const u_char *buf; + int r; + + for (;;) { + if ((r = ssh_packet_next(from, &type)) != 0) { + fprintf(stderr, "ssh_packet_next: %s\n", ssh_err(r)); + return r; + } + if (type != 0) + return 0; + buf = ssh_output_ptr(from, &len); + if (do_debug) + printf("%zu", len); + if (len == 0) + return 0; + if ((r = ssh_output_consume(from, len)) != 0 || + (r = ssh_input_append(to, buf, len)) != 0) + return r; + } +} + +static void +run_kex(struct ssh *client, struct ssh *server) +{ + int r = 0; + + while (!server->kex->done || !client->kex->done) { + if (do_debug) + printf(" S:"); + if ((r = do_send_and_receive(server, client))) + break; + if (do_debug) + printf(" C:"); + if ((r = do_send_and_receive(client, server))) + break; + } + if (do_debug) + printf("done: %s\n", ssh_err(r)); + ASSERT_INT_EQ(r, 0); + ASSERT_INT_EQ(server->kex->done, 1); + ASSERT_INT_EQ(client->kex->done, 1); +} + +static void +do_kex_with_key(char *kex, int keytype, int bits) +{ + struct ssh *client = NULL, *server = NULL, *server2 = NULL; + struct sshkey *private, *public; + struct sshbuf *state; + struct kex_params kex_params; + char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; + char *keyname = NULL; + + TEST_START("sshkey_generate"); + ASSERT_INT_EQ(sshkey_generate(keytype, bits, &private), 0); + TEST_DONE(); + + TEST_START("sshkey_from_private"); + ASSERT_INT_EQ(sshkey_from_private(private, &public), 0); + TEST_DONE(); + + TEST_START("ssh_init"); + memcpy(kex_params.proposal, myproposal, sizeof(myproposal)); + if (kex != NULL) + kex_params.proposal[PROPOSAL_KEX_ALGS] = kex; + keyname = strdup(sshkey_ssh_name(private)); + ASSERT_PTR_NE(keyname, NULL); + kex_params.proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = keyname; + ASSERT_INT_EQ(ssh_init(&client, 0, &kex_params), 0); + ASSERT_INT_EQ(ssh_init(&server, 1, &kex_params), 0); + ASSERT_PTR_NE(client, NULL); + ASSERT_PTR_NE(server, NULL); + TEST_DONE(); + + TEST_START("ssh_add_hostkey"); + ASSERT_INT_EQ(ssh_add_hostkey(server, private), 0); + ASSERT_INT_EQ(ssh_add_hostkey(client, public), 0); + TEST_DONE(); + + TEST_START("kex"); + run_kex(client, server); + TEST_DONE(); + + TEST_START("rekeying client"); + ASSERT_INT_EQ(kex_send_kexinit(client), 0); + run_kex(client, server); + TEST_DONE(); + + TEST_START("rekeying server"); + ASSERT_INT_EQ(kex_send_kexinit(server), 0); + run_kex(client, server); + TEST_DONE(); + + TEST_START("ssh_packet_get_state"); + state = sshbuf_new(); + ASSERT_PTR_NE(state, NULL); + ASSERT_INT_EQ(ssh_packet_get_state(server, state), 0); + ASSERT_INT_GE(sshbuf_len(state), 1); + TEST_DONE(); + + TEST_START("ssh_packet_set_state"); + server2 = NULL; + ASSERT_INT_EQ(ssh_init(&server2, 1, NULL), 0); + ASSERT_PTR_NE(server2, NULL); + ASSERT_INT_EQ(ssh_add_hostkey(server2, private), 0); + kex_free(server2->kex); /* XXX or should ssh_packet_set_state()? */ + ASSERT_INT_EQ(ssh_packet_set_state(server2, state), 0); + ASSERT_INT_EQ(sshbuf_len(state), 0); + sshbuf_free(state); + ASSERT_PTR_NE(server2->kex, NULL); + /* XXX we need to set the callbacks */ + server2->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; + server2->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; + server2->kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; + server2->kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; +#ifdef OPENSSL_HAS_ECC + server2->kex->kex[KEX_ECDH_SHA2] = kexecdh_server; +#endif + server2->kex->kex[KEX_C25519_SHA256] = kexc25519_server; + server2->kex->load_host_public_key = server->kex->load_host_public_key; + server2->kex->load_host_private_key = server->kex->load_host_private_key; + server2->kex->sign = server->kex->sign; + TEST_DONE(); + + TEST_START("rekeying server2"); + ASSERT_INT_EQ(kex_send_kexinit(server2), 0); + run_kex(client, server2); + ASSERT_INT_EQ(kex_send_kexinit(client), 0); + run_kex(client, server2); + TEST_DONE(); + + TEST_START("cleanup"); + sshkey_free(private); + sshkey_free(public); + ssh_free(client); + ssh_free(server); + ssh_free(server2); + free(keyname); + TEST_DONE(); +} + +static void +do_kex(char *kex) +{ + do_kex_with_key(kex, KEY_RSA, 2048); + do_kex_with_key(kex, KEY_DSA, 1024); +#ifdef OPENSSL_HAS_ECC + do_kex_with_key(kex, KEY_ECDSA, 256); +#endif + do_kex_with_key(kex, KEY_ED25519, 256); +} + +void +kex_tests(void) +{ + do_kex("curve25519-sha256@libssh.org"); +#ifdef OPENSSL_HAS_ECC + do_kex("ecdh-sha2-nistp256"); + do_kex("ecdh-sha2-nistp384"); + do_kex("ecdh-sha2-nistp521"); +#endif + do_kex("diffie-hellman-group-exchange-sha256"); + do_kex("diffie-hellman-group-exchange-sha1"); + do_kex("diffie-hellman-group14-sha1"); + do_kex("diffie-hellman-group1-sha1"); +} diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/kex/tests.c b/crypto/external/bsd/openssh/dist/regress/unittests/kex/tests.c new file mode 100644 index 000000000..e7036ec17 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/kex/tests.c @@ -0,0 +1,14 @@ +/* $OpenBSD: tests.c,v 1.1 2015/01/15 23:41:29 markus Exp $ */ +/* + * Placed in the public domain + */ + +#include "../test_helper/test_helper.h" + +void kex_tests(void); + +void +tests(void) +{ + kex_tests(); +} diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/Makefile b/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/Makefile new file mode 100644 index 000000000..85f99ac38 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/Makefile @@ -0,0 +1,14 @@ +# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $ + +PROG=test_sshbuf +SRCS=tests.c +SRCS+=test_sshbuf.c +SRCS+=test_sshbuf_getput_basic.c +SRCS+=test_sshbuf_getput_crypto.c +SRCS+=test_sshbuf_misc.c +SRCS+=test_sshbuf_fuzz.c +SRCS+=test_sshbuf_getput_fuzz.c +SRCS+=test_sshbuf_fixed.c + +.include + diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf.c b/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf.c new file mode 100644 index 000000000..ee77d6934 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf.c @@ -0,0 +1,240 @@ +/* $OpenBSD: test_sshbuf.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */ +/* + * Regress test for sshbuf.h buffer API + * + * Placed in the public domain + */ + +#define SSHBUF_INTERNAL 1 /* access internals for testing */ +#include "includes.h" + +#include +#include +#include +#ifdef HAVE_STDINT_H +# include +#endif +#include +#include + +#include "../test_helper/test_helper.h" + +#include "ssherr.h" +#include "sshbuf.h" + +void sshbuf_tests(void); + +void +sshbuf_tests(void) +{ + struct sshbuf *p1; + const u_char *cdp; + u_char *dp; + size_t sz; + int r; + + TEST_START("allocate sshbuf"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + TEST_DONE(); + + TEST_START("max size on fresh buffer"); + ASSERT_SIZE_T_GT(sshbuf_max_size(p1), 0); + TEST_DONE(); + + TEST_START("available on fresh buffer"); + ASSERT_SIZE_T_GT(sshbuf_avail(p1), 0); + TEST_DONE(); + + TEST_START("len = 0 on empty buffer"); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + TEST_DONE(); + + TEST_START("set valid max size"); + ASSERT_INT_EQ(sshbuf_set_max_size(p1, 65536), 0); + ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 65536); + TEST_DONE(); + + TEST_START("available on limited buffer"); + ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 65536); + TEST_DONE(); + + TEST_START("free"); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("consume on empty buffer"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0); + ASSERT_INT_EQ(sshbuf_consume(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("consume_end on empty buffer"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_consume_end(p1, 0), 0); + ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("reserve space"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + r = sshbuf_reserve(p1, 1, &dp); + ASSERT_INT_EQ(r, 0); + ASSERT_PTR_NE(dp, NULL); + *dp = 0x11; + r = sshbuf_reserve(p1, 3, &dp); + ASSERT_INT_EQ(r, 0); + ASSERT_PTR_NE(dp, NULL); + *dp++ = 0x22; + *dp++ = 0x33; + *dp++ = 0x44; + TEST_DONE(); + + TEST_START("sshbuf_len on filled buffer"); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); + TEST_DONE(); + + TEST_START("sshbuf_ptr on filled buffer"); + cdp = sshbuf_ptr(p1); + ASSERT_PTR_NE(cdp, NULL); + ASSERT_U8_EQ(cdp[0], 0x11); + ASSERT_U8_EQ(cdp[1], 0x22); + ASSERT_U8_EQ(cdp[2], 0x33); + ASSERT_U8_EQ(cdp[3], 0x44); + TEST_DONE(); + + TEST_START("consume on filled buffer"); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); + ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); + r = sshbuf_consume(p1, 64); + ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); + ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 3); + cdp = sshbuf_ptr(p1); + ASSERT_PTR_NE(p1, NULL); + ASSERT_U8_EQ(cdp[0], 0x22); + ASSERT_INT_EQ(sshbuf_consume(p1, 2), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); + cdp = sshbuf_ptr(p1); + ASSERT_PTR_NE(p1, NULL); + ASSERT_U8_EQ(cdp[0], 0x44); + r = sshbuf_consume(p1, 2); + ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); + ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + r = sshbuf_consume(p1, 1); + ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("consume_end on filled buffer"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + r = sshbuf_reserve(p1, 4, &dp); + ASSERT_INT_EQ(r, 0); + ASSERT_PTR_NE(dp, NULL); + *dp++ = 0x11; + *dp++ = 0x22; + *dp++ = 0x33; + *dp++ = 0x44; + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); + r = sshbuf_consume_end(p1, 5); + ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); + ASSERT_INT_EQ(sshbuf_consume_end(p1, 3), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); + cdp = sshbuf_ptr(p1); + ASSERT_PTR_NE(cdp, NULL); + ASSERT_U8_EQ(*cdp, 0x11); + r = sshbuf_consume_end(p1, 2); + ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); + ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("fill limited buffer"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0); + ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223); + ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223); + r = sshbuf_reserve(p1, 1223, &dp); + ASSERT_INT_EQ(r, 0); + ASSERT_PTR_NE(dp, NULL); + memset(dp, 0xd7, 1223); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223); + ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 0); + r = sshbuf_reserve(p1, 1, &dp); + ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); + ASSERT_PTR_EQ(dp, NULL); + TEST_DONE(); + + TEST_START("consume and force compaction"); + ASSERT_INT_EQ(sshbuf_consume(p1, 223), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000); + ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223); + r = sshbuf_reserve(p1, 224, &dp); + ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); + ASSERT_PTR_EQ(dp, NULL); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000); + ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223); + r = sshbuf_reserve(p1, 223, &dp); + ASSERT_INT_EQ(r, 0); + ASSERT_PTR_NE(dp, NULL); + memset(dp, 0x7d, 223); + cdp = sshbuf_ptr(p1); + ASSERT_PTR_NE(cdp, NULL); + ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000); + ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223); + TEST_DONE(); + + TEST_START("resize full buffer"); + r = sshbuf_set_max_size(p1, 1000); + ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); + sz = roundup(1223 + SSHBUF_SIZE_INC * 3, SSHBUF_SIZE_INC); + ASSERT_INT_EQ(sshbuf_set_max_size(p1, sz), 0); + ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz); + ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - 1223); + ASSERT_INT_EQ(sshbuf_len(p1), 1223); + TEST_DONE(); + + /* NB. uses sshbuf internals */ + TEST_START("alloc chunking"); + r = sshbuf_reserve(p1, 1, &dp); + ASSERT_INT_EQ(r, 0); + ASSERT_PTR_NE(dp, NULL); + *dp = 0xff; + cdp = sshbuf_ptr(p1); + ASSERT_PTR_NE(cdp, NULL); + ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000); + ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223); + ASSERT_MEM_FILLED_EQ(cdp + 1223, 0xff, 1); + ASSERT_SIZE_T_EQ(sshbuf_alloc(p1) % SSHBUF_SIZE_INC, 0); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("reset buffer"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0); + ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223); + r = sshbuf_reserve(p1, 1223, &dp); + ASSERT_INT_EQ(r, 0); + ASSERT_PTR_NE(dp, NULL); + memset(dp, 0xd7, 1223); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223); + sshbuf_reset(p1); + ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223); + sshbuf_free(p1); + TEST_DONE(); +} diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_fixed.c b/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_fixed.c new file mode 100644 index 000000000..df4925f7c --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_fixed.c @@ -0,0 +1,126 @@ +/* $OpenBSD: test_sshbuf_fixed.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */ +/* + * Regress test for sshbuf.h buffer API + * + * Placed in the public domain + */ + +#define SSHBUF_INTERNAL 1 /* access internals for testing */ +#include "includes.h" + +#include +#include +#include +#ifdef HAVE_STDINT_H +# include +#endif +#include +#include + +#include "../test_helper/test_helper.h" + +#include "sshbuf.h" +#include "ssherr.h" + +void sshbuf_fixed(void); + +const u_char test_buf[] = "\x01\x12\x34\x56\x78\x00\x00\x00\x05hello"; + +void +sshbuf_fixed(void) +{ + struct sshbuf *p1, *p2, *p3; + u_char c; + char *s; + u_int i; + size_t l; + + TEST_START("sshbuf_from"); + p1 = sshbuf_from(test_buf, sizeof(test_buf)); + ASSERT_PTR_NE(p1, NULL); + ASSERT_PTR_EQ(sshbuf_mutable_ptr(p1), NULL); + ASSERT_INT_EQ(sshbuf_check_reserve(p1, 1), SSH_ERR_BUFFER_READ_ONLY); + ASSERT_INT_EQ(sshbuf_reserve(p1, 1, NULL), SSH_ERR_BUFFER_READ_ONLY); + ASSERT_INT_EQ(sshbuf_set_max_size(p1, 200), SSH_ERR_BUFFER_READ_ONLY); + ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), SSH_ERR_BUFFER_READ_ONLY); + ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 0); + ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_from data"); + p1 = sshbuf_from(test_buf, sizeof(test_buf) - 1); + ASSERT_PTR_NE(p1, NULL); + ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf); + ASSERT_INT_EQ(sshbuf_get_u8(p1, &c), 0); + ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf + 1); + ASSERT_U8_EQ(c, 1); + ASSERT_INT_EQ(sshbuf_get_u32(p1, &i), 0); + ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf + 5); + ASSERT_U32_EQ(i, 0x12345678); + ASSERT_INT_EQ(sshbuf_get_cstring(p1, &s, &l), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + ASSERT_STRING_EQ(s, "hello"); + ASSERT_SIZE_T_EQ(l, 5); + sshbuf_free(p1); + free(s); + TEST_DONE(); + + TEST_START("sshbuf_fromb "); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_U_INT_EQ(sshbuf_refcount(p1), 1); + ASSERT_PTR_EQ(sshbuf_parent(p1), NULL); + ASSERT_INT_EQ(sshbuf_put(p1, test_buf, sizeof(test_buf) - 1), 0); + p2 = sshbuf_fromb(p1); + ASSERT_PTR_NE(p2, NULL); + ASSERT_U_INT_EQ(sshbuf_refcount(p1), 2); + ASSERT_PTR_EQ(sshbuf_parent(p1), NULL); + ASSERT_PTR_EQ(sshbuf_parent(p2), p1); + ASSERT_PTR_EQ(sshbuf_ptr(p2), sshbuf_ptr(p1)); + ASSERT_PTR_NE(sshbuf_ptr(p1), NULL); + ASSERT_PTR_NE(sshbuf_ptr(p2), NULL); + ASSERT_PTR_EQ(sshbuf_mutable_ptr(p1), NULL); + ASSERT_PTR_EQ(sshbuf_mutable_ptr(p2), NULL); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sshbuf_len(p2)); + ASSERT_INT_EQ(sshbuf_get_u8(p2, &c), 0); + ASSERT_PTR_EQ(sshbuf_ptr(p2), sshbuf_ptr(p1) + 1); + ASSERT_U8_EQ(c, 1); + ASSERT_INT_EQ(sshbuf_get_u32(p2, &i), 0); + ASSERT_PTR_EQ(sshbuf_ptr(p2), sshbuf_ptr(p1) + 5); + ASSERT_U32_EQ(i, 0x12345678); + ASSERT_INT_EQ(sshbuf_get_cstring(p2, &s, &l), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p2), 0); + ASSERT_STRING_EQ(s, "hello"); + ASSERT_SIZE_T_EQ(l, 5); + sshbuf_free(p1); + ASSERT_U_INT_EQ(sshbuf_refcount(p1), 1); + sshbuf_free(p2); + free(s); + TEST_DONE(); + + TEST_START("sshbuf_froms"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x01), 0); + ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0); + ASSERT_INT_EQ(sshbuf_put_cstring(p1, "hello"), 0); + p2 = sshbuf_new(); + ASSERT_PTR_NE(p2, NULL); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(test_buf) - 1); + ASSERT_INT_EQ(sshbuf_put_stringb(p2, p1), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p2), sizeof(test_buf) + 4 - 1); + ASSERT_INT_EQ(sshbuf_froms(p2, &p3), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p2), 0); + ASSERT_PTR_NE(p3, NULL); + ASSERT_PTR_NE(sshbuf_ptr(p3), NULL); + ASSERT_SIZE_T_EQ(sshbuf_len(p3), sizeof(test_buf) - 1); + ASSERT_MEM_EQ(sshbuf_ptr(p3), test_buf, sizeof(test_buf) - 1); + sshbuf_free(p3); + ASSERT_INT_EQ(sshbuf_put_stringb(p2, p1), 0); + ASSERT_INT_EQ(sshbuf_consume_end(p2, 1), 0); + ASSERT_INT_EQ(sshbuf_froms(p2, &p3), SSH_ERR_MESSAGE_INCOMPLETE); + ASSERT_PTR_EQ(p3, NULL); + sshbuf_free(p2); + sshbuf_free(p1); +} diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_fuzz.c b/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_fuzz.c new file mode 100644 index 000000000..c52376b53 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_fuzz.c @@ -0,0 +1,127 @@ +/* $OpenBSD: test_sshbuf_fuzz.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */ +/* + * Regress test for sshbuf.h buffer API + * + * Placed in the public domain + */ + +#include "includes.h" + +#include +#include +#include +#ifdef HAVE_STDINT_H +# include +#endif +#include +#include + +#include "../test_helper/test_helper.h" + +#include "ssherr.h" +#include "sshbuf.h" + +#define NUM_FUZZ_TESTS (1 << 18) + +void sshbuf_fuzz_tests(void); + +void +sshbuf_fuzz_tests(void) +{ + struct sshbuf *p1; + u_char *dp; + size_t sz, sz2, i; + u_int32_t r; + int ret; + + /* NB. uses sshbuf internals */ + TEST_START("fuzz alloc/dealloc"); + p1 = sshbuf_new(); + ASSERT_INT_EQ(sshbuf_set_max_size(p1, 16 * 1024), 0); + ASSERT_PTR_NE(p1, NULL); + ASSERT_PTR_NE(sshbuf_ptr(p1), NULL); + ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1)); + for (i = 0; i < NUM_FUZZ_TESTS; i++) { + r = arc4random_uniform(10); + if (r == 0) { + /* 10% chance: small reserve */ + r = arc4random_uniform(10); + fuzz_reserve: + sz = sshbuf_avail(p1); + sz2 = sshbuf_len(p1); + ret = sshbuf_reserve(p1, r, &dp); + if (ret < 0) { + ASSERT_PTR_EQ(dp, NULL); + ASSERT_SIZE_T_LT(sz, r); + ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2); + } else { + ASSERT_PTR_NE(dp, NULL); + ASSERT_SIZE_T_GE(sz, r); + ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - r); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2 + r); + memset(dp, arc4random_uniform(255) + 1, r); + } + } else if (r < 3) { + /* 20% chance: big reserve */ + r = arc4random_uniform(8 * 1024); + goto fuzz_reserve; + } else if (r == 3) { + /* 10% chance: small consume */ + r = arc4random_uniform(10); + fuzz_consume: + sz = sshbuf_avail(p1); + sz2 = sshbuf_len(p1); + /* 50% change consume from end, otherwise start */ + ret = ((arc4random() & 1) ? + sshbuf_consume : sshbuf_consume_end)(p1, r); + if (ret < 0) { + ASSERT_SIZE_T_LT(sz2, r); + ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2); + } else { + ASSERT_SIZE_T_GE(sz2, r); + ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz + r); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2 - r); + } + } else if (r < 8) { + /* 40% chance: big consume */ + r = arc4random_uniform(2 * 1024); + goto fuzz_consume; + } else if (r == 8) { + /* 10% chance: reset max size */ + r = arc4random_uniform(16 * 1024); + sz = sshbuf_max_size(p1); + if (sshbuf_set_max_size(p1, r) < 0) + ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz); + else + ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), r); + } else { + if (arc4random_uniform(8192) == 0) { + /* tiny chance: new buffer */ + ASSERT_PTR_NE(sshbuf_ptr(p1), NULL); + ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1)); + sshbuf_free(p1); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_set_max_size(p1, + 16 * 1024), 0); + } else { + /* Almost 10%: giant reserve */ + /* use arc4random_buf for r > 2^32 on 64 bit */ + arc4random_buf(&r, sizeof(r)); + while (r < SSHBUF_SIZE_MAX / 2) { + r <<= 1; + r |= arc4random() & 1; + } + goto fuzz_reserve; + } + } + ASSERT_PTR_NE(sshbuf_ptr(p1), NULL); + ASSERT_SIZE_T_LE(sshbuf_max_size(p1), 16 * 1024); + } + ASSERT_PTR_NE(sshbuf_ptr(p1), NULL); + ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1)); + sshbuf_free(p1); + TEST_DONE(); +} diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_getput_basic.c b/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_getput_basic.c new file mode 100644 index 000000000..966e8432b --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_getput_basic.c @@ -0,0 +1,484 @@ +/* $OpenBSD: test_sshbuf_getput_basic.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */ +/* + * Regress test for sshbuf.h buffer API + * + * Placed in the public domain + */ + +#include "includes.h" + +#include +#include +#include +#ifdef HAVE_STDINT_H +# include +#endif +#include +#include + +#include "../test_helper/test_helper.h" +#include "ssherr.h" +#include "sshbuf.h" + +void sshbuf_getput_basic_tests(void); + +void +sshbuf_getput_basic_tests(void) +{ + struct sshbuf *p1, *p2; + const u_char *cd; + u_char *d, d2[32], x[] = { + 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x00, 0x99 + }; + u_int64_t v64; + u_int32_t v32; + u_int16_t v16; + u_char v8; + size_t s; + char *s2; + int r; + u_char bn1[] = { 0x00, 0x00, 0x00 }; + u_char bn2[] = { 0x00, 0x00, 0x01, 0x02 }; + u_char bn3[] = { 0x00, 0x80, 0x09 }; + u_char bn_exp1[] = { 0x00, 0x00, 0x00, 0x00 }; + u_char bn_exp2[] = { 0x00, 0x00, 0x00, 0x02, 0x01, 0x02 }; + u_char bn_exp3[] = { 0x00, 0x00, 0x00, 0x03, 0x00, 0x80, 0x09 }; + + TEST_START("PEEK_U64"); + ASSERT_U64_EQ(PEEK_U64(x), 0x1122334455667788ULL); + TEST_DONE(); + + TEST_START("PEEK_U32"); + ASSERT_U32_EQ(PEEK_U32(x), 0x11223344); + TEST_DONE(); + + TEST_START("PEEK_U16"); + ASSERT_U16_EQ(PEEK_U16(x), 0x1122); + TEST_DONE(); + + TEST_START("POKE_U64"); + bzero(d2, sizeof(d2)); + POKE_U64(d2, 0x1122334455667788ULL); + ASSERT_MEM_EQ(d2, x, 8); + TEST_DONE(); + + TEST_START("POKE_U32"); + bzero(d2, sizeof(d2)); + POKE_U32(d2, 0x11223344); + ASSERT_MEM_EQ(d2, x, 4); + TEST_DONE(); + + TEST_START("POKE_U16"); + bzero(d2, sizeof(d2)); + POKE_U16(d2, 0x1122); + ASSERT_MEM_EQ(d2, x, 2); + TEST_DONE(); + + TEST_START("sshbuf_put"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put(p1, x, 5), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 5); + cd = sshbuf_ptr(p1); + ASSERT_PTR_NE(cd, NULL); + ASSERT_U8_EQ(cd[0], 0x11); + ASSERT_U8_EQ(cd[1], 0x22); + ASSERT_U8_EQ(cd[2], 0x33); + ASSERT_U8_EQ(cd[3], 0x44); + ASSERT_U8_EQ(cd[4], 0x55); + TEST_DONE(); + + TEST_START("sshbuf_get"); + ASSERT_INT_EQ(sshbuf_get(p1, d2, 4), 0); + ASSERT_MEM_EQ(d2, x, 4); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); + ASSERT_U8_EQ(*(sshbuf_ptr(p1)), 0x55); + TEST_DONE(); + + TEST_START("sshbuf_get truncated"); + r = sshbuf_get(p1, d2, 4); + ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); + ASSERT_U8_EQ(*(sshbuf_ptr(p1)), 0x55); + TEST_DONE(); + + TEST_START("sshbuf_put truncated"); + ASSERT_INT_EQ(sshbuf_set_max_size(p1, 4), 0); + r = sshbuf_put(p1, x, 5); + ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_u64"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put(p1, x, 10), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 10); + ASSERT_INT_EQ(sshbuf_get_u64(p1, &v64), 0); + ASSERT_U64_EQ(v64, 0x1122334455667788ULL); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); + TEST_DONE(); + + TEST_START("sshbuf_get_u64 truncated"); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); + r = sshbuf_get_u64(p1, &v64); + ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_u32"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put(p1, x, 10), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 10); + ASSERT_INT_EQ(sshbuf_get_u32(p1, &v32), 0); + ASSERT_U32_EQ(v32, 0x11223344); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 6); + ASSERT_INT_EQ(sshbuf_get_u32(p1, &v32), 0); + ASSERT_U32_EQ(v32, 0x55667788); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); + TEST_DONE(); + + TEST_START("sshbuf_get_u32 truncated"); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); + r = sshbuf_get_u32(p1, &v32); + ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_u16"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put(p1, x, 9), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 9); + ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0); + ASSERT_U16_EQ(v16, 0x1122); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 7); + ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0); + ASSERT_U16_EQ(v16, 0x3344); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 5); + ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0); + ASSERT_U16_EQ(v16, 0x5566); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 3); + ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0); + ASSERT_U16_EQ(v16, 0x7788); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); + TEST_DONE(); + + TEST_START("sshbuf_get_u16 truncated"); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); + r = sshbuf_get_u16(p1, &v16); + ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_u8"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put(p1, x, 2), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); + ASSERT_INT_EQ(sshbuf_get_u8(p1, &v8), 0); + ASSERT_U8_EQ(v8, 0x11); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); + ASSERT_INT_EQ(sshbuf_get_u8(p1, &v8), 0); + ASSERT_U8_EQ(v8, 0x22); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + TEST_DONE(); + + TEST_START("sshbuf_get_u8 truncated"); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + r = sshbuf_get_u8(p1, &v8); + ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_u64"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u64(p1, 0x1122334455667788ULL), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 8); + ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 8); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_u64 exact"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_set_max_size(p1, 8), 0); + ASSERT_INT_EQ(sshbuf_put_u64(p1, 0x1122334455667788ULL), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 8); + ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 8); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_u64 limited"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_set_max_size(p1, 7), 0); + r = sshbuf_put_u64(p1, 0x1122334455667788ULL); + ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_u32"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x11223344), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); + ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 4); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_u32 exact"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_set_max_size(p1, 4), 0); + ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x11223344), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); + ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 4); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_u32 limited"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_set_max_size(p1, 3), 0); + r = sshbuf_put_u32(p1, 0x11223344); + ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_u16"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u16(p1, 0x1122), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); + ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 2); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_u16"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_set_max_size(p1, 2), 0); + ASSERT_INT_EQ(sshbuf_put_u16(p1, 0x1122), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); + ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 2); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_u16 limited"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1), 0); + r = sshbuf_put_u16(p1, 0x1122); + ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_string"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0); + ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0); + ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4 + 4); + ASSERT_INT_EQ(sshbuf_get_string(p1, &d, &s), 0); + ASSERT_SIZE_T_EQ(s, sizeof(x)); + ASSERT_MEM_EQ(d, x, sizeof(x)); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); + free(d); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_string exact"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(x) + 4), 0); + ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0); + ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4); + ASSERT_INT_EQ(sshbuf_get_string(p1, &d, &s), 0); + ASSERT_SIZE_T_EQ(s, sizeof(x)); + ASSERT_MEM_EQ(d, x, sizeof(x)); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + free(d); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_string truncated"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0); + ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4); + ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 3); + r = sshbuf_get_string(p1, &d, &s); + ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 3); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_string giant"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u32(p1, 0xffffffff), 0); + ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4); + r = sshbuf_get_string(p1, &d, &s); + ASSERT_INT_EQ(r, SSH_ERR_STRING_TOO_LARGE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_cstring giant"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u32(p1, 0xffffffff), 0); + ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4); + r = sshbuf_get_cstring(p1, &s2, &s); + ASSERT_INT_EQ(r, SSH_ERR_STRING_TOO_LARGE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_cstring embedded \\0"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0); + ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4); + r = sshbuf_get_cstring(p1, &s2, NULL); + ASSERT_INT_EQ(r, SSH_ERR_INVALID_FORMAT); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_cstring trailing \\0"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x) - 1), 0); + ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x) - 1), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4 - 1); + ASSERT_INT_EQ(sshbuf_get_cstring(p1, &s2, &s), 0); + ASSERT_SIZE_T_EQ(s, sizeof(x) - 1); + ASSERT_MEM_EQ(s2, x, s); + free(s2); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_string"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_string(p1, x, sizeof(x)), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4); + ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), sizeof(x)); + ASSERT_MEM_EQ(sshbuf_ptr(p1) + 4, x, sizeof(x)); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_string limited"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(x) + 4 - 1), 0); + r = sshbuf_put_string(p1, x, sizeof(x)); + ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_string giant"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + r = sshbuf_put_string(p1, (void *)0x01, 0xfffffffc); + ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_putf"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + r = sshbuf_putf(p1, "%s %d %x", "hello", 23, 0x5f); + ASSERT_INT_EQ(r, 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 11); + ASSERT_MEM_EQ(sshbuf_ptr(p1), "hello 23 5f", 11); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_putb"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + p2 = sshbuf_new(); + ASSERT_PTR_NE(p2, NULL); + ASSERT_INT_EQ(sshbuf_put(p1, "blahblahblah", 12), 0); + ASSERT_INT_EQ(sshbuf_putb(p2, p1), 0); + sshbuf_free(p1); + ASSERT_SIZE_T_EQ(sshbuf_len(p2), 12); + ASSERT_MEM_EQ(sshbuf_ptr(p2), "blahblahblah", 12); + sshbuf_free(p2); + TEST_DONE(); + + TEST_START("sshbuf_put_bignum2_bytes empty buf"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, NULL, 0), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp1)); + ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp1, sizeof(bn_exp1)); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_bignum2_bytes all zeroes"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn1, sizeof(bn1)), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp1)); + ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp1, sizeof(bn_exp1)); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_bignum2_bytes simple"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn2+2, sizeof(bn2)-2), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp2)); + ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp2, sizeof(bn_exp2)); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_bignum2_bytes leading zero"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn2, sizeof(bn2)), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp2)); + ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp2, sizeof(bn_exp2)); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_bignum2_bytes neg"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn3+1, sizeof(bn3)-1), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp3)); + ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp3, sizeof(bn_exp3)); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_bignum2_bytes neg and leading zero"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn3, sizeof(bn3)), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp3)); + ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp3, sizeof(bn_exp3)); + sshbuf_free(p1); + TEST_DONE(); +} diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c b/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c new file mode 100644 index 000000000..a68e1329e --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c @@ -0,0 +1,409 @@ +/* $OpenBSD: test_sshbuf_getput_crypto.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */ +/* + * Regress test for sshbuf.h buffer API + * + * Placed in the public domain + */ + +#include "includes.h" + +#include +#include +#include +#ifdef HAVE_STDINT_H +# include +#endif +#include +#include + +#include +#include +#ifdef OPENSSL_HAS_NISTP256 +# include +#endif + +#include "../test_helper/test_helper.h" +#include "ssherr.h" +#include "sshbuf.h" + +void sshbuf_getput_crypto_tests(void); + +void +sshbuf_getput_crypto_tests(void) +{ + struct sshbuf *p1; + BIGNUM *bn, *bn2; + /* This one has num_bits != num_bytes * 8 to test bignum1 encoding */ + const char *hexbn1 = "0102030405060708090a0b0c0d0e0f10"; + /* This one has MSB set to test bignum2 encoding negative-avoidance */ + const char *hexbn2 = "f0e0d0c0b0a0908070605040302010007fff11"; + u_char expbn1[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + }; + u_char expbn2[] = { + 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80, + 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00, + 0x7f, 0xff, 0x11 + }; +#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) + const u_char *d; + size_t s; + BIGNUM *bn_x, *bn_y; + int ec256_nid = NID_X9_62_prime256v1; + char *ec256_x = "0C828004839D0106AA59575216191357" + "34B451459DADB586677EF9DF55784999"; + char *ec256_y = "4D196B50F0B4E94B3C73E3A9D4CD9DF2" + "C8F9A35E42BDD047550F69D80EC23CD4"; + u_char expec256[] = { + 0x04, + 0x0c, 0x82, 0x80, 0x04, 0x83, 0x9d, 0x01, 0x06, + 0xaa, 0x59, 0x57, 0x52, 0x16, 0x19, 0x13, 0x57, + 0x34, 0xb4, 0x51, 0x45, 0x9d, 0xad, 0xb5, 0x86, + 0x67, 0x7e, 0xf9, 0xdf, 0x55, 0x78, 0x49, 0x99, + 0x4d, 0x19, 0x6b, 0x50, 0xf0, 0xb4, 0xe9, 0x4b, + 0x3c, 0x73, 0xe3, 0xa9, 0xd4, 0xcd, 0x9d, 0xf2, + 0xc8, 0xf9, 0xa3, 0x5e, 0x42, 0xbd, 0xd0, 0x47, + 0x55, 0x0f, 0x69, 0xd8, 0x0e, 0xc2, 0x3c, 0xd4 + }; + EC_KEY *eck; + EC_POINT *ecp; +#endif + int r; + +#define MKBN(b, bnn) \ + do { \ + bnn = NULL; \ + ASSERT_INT_GT(BN_hex2bn(&bnn, b), 0); \ + } while (0) + + TEST_START("sshbuf_put_bignum1"); + MKBN(hexbn1, bn); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_bignum1(p1, bn), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 2); + ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), (u_int16_t)BN_num_bits(bn)); + ASSERT_MEM_EQ(sshbuf_ptr(p1) + 2, expbn1, sizeof(expbn1)); + BN_free(bn); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_bignum1 limited"); + MKBN(hexbn1, bn); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 1), 0); + r = sshbuf_put_bignum1(p1, bn); + ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + BN_free(bn); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_bignum1 bn2"); + MKBN(hexbn2, bn); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_bignum1(p1, bn), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 2); + ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), (u_int16_t)BN_num_bits(bn)); + ASSERT_MEM_EQ(sshbuf_ptr(p1) + 2, expbn2, sizeof(expbn2)); + BN_free(bn); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_bignum1 bn2 limited"); + MKBN(hexbn2, bn); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 1), 0); + r = sshbuf_put_bignum1(p1, bn); + ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + BN_free(bn); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_bignum2"); + MKBN(hexbn1, bn); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 4); + ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn)); + ASSERT_MEM_EQ(sshbuf_ptr(p1) + 4, expbn1, sizeof(expbn1)); + BN_free(bn); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_bignum2 limited"); + MKBN(hexbn1, bn); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 3), 0); + r = sshbuf_put_bignum2(p1, bn); + ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + BN_free(bn); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_bignum2 bn2"); + MKBN(hexbn2, bn); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 4 + 1); /* MSB */ + ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn) + 1); + ASSERT_U8_EQ(*(sshbuf_ptr(p1) + 4), 0x00); + ASSERT_MEM_EQ(sshbuf_ptr(p1) + 5, expbn2, sizeof(expbn2)); + BN_free(bn); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_put_bignum2 bn2 limited"); + MKBN(hexbn2, bn); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn2) + 3), 0); + r = sshbuf_put_bignum2(p1, bn); + ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + BN_free(bn); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_bignum1"); + MKBN(hexbn1, bn); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0); + ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1)), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1)); + ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0); + bn2 = BN_new(); + ASSERT_INT_EQ(sshbuf_get_bignum1(p1, bn2), 0); + ASSERT_BIGNUM_EQ(bn, bn2); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); + BN_free(bn); + BN_free(bn2); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_bignum1 truncated"); + MKBN(hexbn1, bn); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0); + ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1) - 1), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1) - 1); + bn2 = BN_new(); + r = sshbuf_get_bignum1(p1, bn2); + ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1) - 1); + BN_free(bn); + BN_free(bn2); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_bignum1 giant"); + MKBN(hexbn1, bn); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xffff), 0); + ASSERT_INT_EQ(sshbuf_reserve(p1, (0xffff + 7) / 8, NULL), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + ((0xffff + 7) / 8)); + bn2 = BN_new(); + r = sshbuf_get_bignum1(p1, bn2); + ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_TOO_LARGE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + ((0xffff + 7) / 8)); + BN_free(bn); + BN_free(bn2); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_bignum1 bn2"); + MKBN(hexbn2, bn); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0); + ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2)); + ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0); + bn2 = BN_new(); + ASSERT_INT_EQ(sshbuf_get_bignum1(p1, bn2), 0); + ASSERT_BIGNUM_EQ(bn, bn2); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); + BN_free(bn); + BN_free(bn2); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_bignum1 bn2 truncated"); + MKBN(hexbn2, bn); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0); + ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2) - 1), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2) - 1); + bn2 = BN_new(); + r = sshbuf_get_bignum1(p1, bn2); + ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2) - 1); + BN_free(bn); + BN_free(bn2); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_bignum2"); + MKBN(hexbn1, bn); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0); + ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1)), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4 + sizeof(expbn1)); + ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0); + bn2 = BN_new(); + ASSERT_INT_EQ(sshbuf_get_bignum2(p1, bn2), 0); + ASSERT_BIGNUM_EQ(bn, bn2); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); + BN_free(bn); + BN_free(bn2); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_bignum2 truncated"); + MKBN(hexbn1, bn); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0); + ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1) - 1), 0); + bn2 = BN_new(); + r = sshbuf_get_bignum2(p1, bn2); + ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 3); + BN_free(bn); + BN_free(bn2); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_bignum2 giant"); + MKBN(hexbn1, bn); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u32(p1, 65536), 0); + ASSERT_INT_EQ(sshbuf_reserve(p1, 65536, NULL), 0); + bn2 = BN_new(); + r = sshbuf_get_bignum2(p1, bn2); + ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_TOO_LARGE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 65536 + 4); + BN_free(bn); + BN_free(bn2); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_bignum2 bn2"); + MKBN(hexbn2, bn); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn) + 1), 0); /* MSB */ + ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0); + ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4 + 1 + sizeof(expbn2)); + ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0); + bn2 = BN_new(); + ASSERT_INT_EQ(sshbuf_get_bignum2(p1, bn2), 0); + ASSERT_BIGNUM_EQ(bn, bn2); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); + BN_free(bn); + BN_free(bn2); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_bignum2 bn2 truncated"); + MKBN(hexbn2, bn); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn) + 1), 0); + ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0); + ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2) - 1), 0); + bn2 = BN_new(); + r = sshbuf_get_bignum2(p1, bn2); + ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 1 + 4 - 1); + BN_free(bn); + BN_free(bn2); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_bignum2 bn2 negative"); + MKBN(hexbn2, bn); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0); + ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0); + bn2 = BN_new(); + r = sshbuf_get_bignum2(p1, bn2); + ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_IS_NEGATIVE); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 4); + BN_free(bn); + BN_free(bn2); + sshbuf_free(p1); + TEST_DONE(); + +#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) + TEST_START("sshbuf_put_ec"); + eck = EC_KEY_new_by_curve_name(ec256_nid); + ASSERT_PTR_NE(eck, NULL); + ecp = EC_POINT_new(EC_KEY_get0_group(eck)); + ASSERT_PTR_NE(ecp, NULL); + MKBN(ec256_x, bn_x); + MKBN(ec256_y, bn_y); + ASSERT_INT_EQ(EC_POINT_set_affine_coordinates_GFp( + EC_KEY_get0_group(eck), ecp, bn_x, bn_y, NULL), 1); + ASSERT_INT_EQ(EC_KEY_set_public_key(eck, ecp), 1); + BN_free(bn_x); + BN_free(bn_y); + EC_POINT_free(ecp); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_eckey(p1, eck), 0); + ASSERT_INT_EQ(sshbuf_get_string_direct(p1, &d, &s), 0); + ASSERT_SIZE_T_EQ(s, sizeof(expec256)); + ASSERT_MEM_EQ(d, expec256, sizeof(expec256)); + sshbuf_free(p1); + EC_KEY_free(eck); + TEST_DONE(); + + TEST_START("sshbuf_get_ec"); + eck = EC_KEY_new_by_curve_name(ec256_nid); + ASSERT_PTR_NE(eck, NULL); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_string(p1, expec256, sizeof(expec256)), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expec256) + 4); + ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0); + ASSERT_INT_EQ(sshbuf_get_eckey(p1, eck), 0); + bn_x = BN_new(); + bn_y = BN_new(); + ASSERT_PTR_NE(bn_x, NULL); + ASSERT_PTR_NE(bn_y, NULL); + ASSERT_INT_EQ(EC_POINT_get_affine_coordinates_GFp( + EC_KEY_get0_group(eck), EC_KEY_get0_public_key(eck), + bn_x, bn_y, NULL), 1); + MKBN(ec256_x, bn); + MKBN(ec256_y, bn2); + ASSERT_INT_EQ(BN_cmp(bn_x, bn), 0); + ASSERT_INT_EQ(BN_cmp(bn_y, bn2), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); + sshbuf_free(p1); + EC_KEY_free(eck); + BN_free(bn_x); + BN_free(bn_y); + BN_free(bn); + BN_free(bn2); + TEST_DONE(); +#endif +} + diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c b/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c new file mode 100644 index 000000000..c6b5c29d1 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c @@ -0,0 +1,130 @@ +/* $OpenBSD: test_sshbuf_getput_fuzz.c,v 1.2 2014/05/02 02:54:00 djm Exp $ */ +/* + * Regress test for sshbuf.h buffer API + * + * Placed in the public domain + */ + +#include "includes.h" + +#include +#include +#include +#ifdef HAVE_STDINT_H +# include +#endif +#include +#include + +#include +#include +#ifdef OPENSSL_HAS_NISTP256 +# include +#endif + +#include "../test_helper/test_helper.h" +#include "ssherr.h" +#include "sshbuf.h" + +void sshbuf_getput_fuzz_tests(void); + +static void +attempt_parse_blob(u_char *blob, size_t len) +{ + struct sshbuf *p1; + BIGNUM *bn; +#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) + EC_KEY *eck; +#endif + u_char *s; + size_t l; + u_int8_t u8; + u_int16_t u16; + u_int32_t u32; + u_int64_t u64; + + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put(p1, blob, len), 0); + sshbuf_get_u8(p1, &u8); + sshbuf_get_u16(p1, &u16); + sshbuf_get_u32(p1, &u32); + sshbuf_get_u64(p1, &u64); + if (sshbuf_get_string(p1, &s, &l) == 0) { + bzero(s, l); + free(s); + } + bn = BN_new(); + sshbuf_get_bignum1(p1, bn); + BN_clear_free(bn); + bn = BN_new(); + sshbuf_get_bignum2(p1, bn); + BN_clear_free(bn); +#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) + eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + ASSERT_PTR_NE(eck, NULL); + sshbuf_get_eckey(p1, eck); + EC_KEY_free(eck); +#endif + sshbuf_free(p1); +} + + +static void +onerror(void *fuzz) +{ + fprintf(stderr, "Failed during fuzz:\n"); + fuzz_dump((struct fuzz *)fuzz); +} + +void +sshbuf_getput_fuzz_tests(void) +{ + u_char blob[] = { + /* u8 */ + 0xd0, + /* u16 */ + 0xc0, 0xde, + /* u32 */ + 0xfa, 0xce, 0xde, 0xad, + /* u64 */ + 0xfe, 0xed, 0xac, 0x1d, 0x1f, 0x1c, 0xbe, 0xef, + /* string */ + 0x00, 0x00, 0x00, 0x09, + 'O', ' ', 'G', 'o', 'r', 'g', 'o', 'n', '!', + /* bignum1 */ + 0x79, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + /* bignum2 */ + 0x00, 0x00, 0x00, 0x14, + 0x00, + 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80, + 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00, + 0x7f, 0xff, 0x11, + /* EC point (NIST-256 curve) */ + 0x00, 0x00, 0x00, 0x41, + 0x04, + 0x0c, 0x82, 0x80, 0x04, 0x83, 0x9d, 0x01, 0x06, + 0xaa, 0x59, 0x57, 0x52, 0x16, 0x19, 0x13, 0x57, + 0x34, 0xb4, 0x51, 0x45, 0x9d, 0xad, 0xb5, 0x86, + 0x67, 0x7e, 0xf9, 0xdf, 0x55, 0x78, 0x49, 0x99, + 0x4d, 0x19, 0x6b, 0x50, 0xf0, 0xb4, 0xe9, 0x4b, + 0x3c, 0x73, 0xe3, 0xa9, 0xd4, 0xcd, 0x9d, 0xf2, + 0xc8, 0xf9, 0xa3, 0x5e, 0x42, 0xbd, 0xd0, 0x47, + 0x55, 0x0f, 0x69, 0xd8, 0x0e, 0xc2, 0x3c, 0xd4, + }; + struct fuzz *fuzz; + + TEST_START("fuzz blob parsing"); + fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_2_BIT_FLIP | + FUZZ_1_BYTE_FLIP | FUZZ_2_BYTE_FLIP | + FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, blob, sizeof(blob)); + TEST_ONERROR(onerror, fuzz); + for(; !fuzz_done(fuzz); fuzz_next(fuzz)) + attempt_parse_blob(blob, sizeof(blob)); + fuzz_cleanup(fuzz); + TEST_DONE(); + TEST_ONERROR(NULL, NULL); +} + diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_misc.c b/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_misc.c new file mode 100644 index 000000000..f155491a0 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/test_sshbuf_misc.c @@ -0,0 +1,138 @@ +/* $OpenBSD: test_sshbuf_misc.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */ +/* + * Regress test for sshbuf.h buffer API + * + * Placed in the public domain + */ + +#include "includes.h" + +#include +#include +#include +#ifdef HAVE_STDINT_H +# include +#endif +#include +#include + +#include "../test_helper/test_helper.h" + +#include "sshbuf.h" + +void sshbuf_misc_tests(void); + +void +sshbuf_misc_tests(void) +{ + struct sshbuf *p1; + char tmp[512], *p; + FILE *out; + size_t sz; + + TEST_START("sshbuf_dump"); + out = tmpfile(); + ASSERT_PTR_NE(out, NULL); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0); + sshbuf_dump(p1, out); + fflush(out); + rewind(out); + sz = fread(tmp, 1, sizeof(tmp), out); + ASSERT_INT_EQ(ferror(out), 0); + ASSERT_INT_NE(feof(out), 0); + ASSERT_SIZE_T_GT(sz, 0); + tmp[sz] = '\0'; + ASSERT_PTR_NE(strstr(tmp, "12 34 56 78"), NULL); + fclose(out); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_dtob16"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0); + p = sshbuf_dtob16(p1); + ASSERT_PTR_NE(p, NULL); + ASSERT_STRING_EQ(p, "12345678"); + free(p); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_dtob64 len 1"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0); + p = sshbuf_dtob64(p1); + ASSERT_PTR_NE(p, NULL); + ASSERT_STRING_EQ(p, "EQ=="); + free(p); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_dtob64 len 2"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0); + ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x22), 0); + p = sshbuf_dtob64(p1); + ASSERT_PTR_NE(p, NULL); + ASSERT_STRING_EQ(p, "ESI="); + free(p); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_dtob64 len 3"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0); + ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x22), 0); + ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x33), 0); + p = sshbuf_dtob64(p1); + ASSERT_PTR_NE(p, NULL); + ASSERT_STRING_EQ(p, "ESIz"); + free(p); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_dtob64 len 8191"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_reserve(p1, 8192, NULL), 0); + bzero(sshbuf_mutable_ptr(p1), 8192); + p = sshbuf_dtob64(p1); + ASSERT_PTR_NE(p, NULL); + ASSERT_SIZE_T_EQ(strlen(p), ((8191 + 2) / 3) * 4); + free(p); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_b64tod len 1"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A=="), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); + ASSERT_U8_EQ(*sshbuf_ptr(p1), 0xd0); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_b64tod len 2"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A8="), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); + ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), 0xd00f); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_b64tod len 4"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A/QDw=="), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); + ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), 0xd00fd00f); + sshbuf_free(p1); + TEST_DONE(); +} + diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/tests.c b/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/tests.c new file mode 100644 index 000000000..1557e4342 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshbuf/tests.c @@ -0,0 +1,28 @@ +/* $OpenBSD: tests.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */ +/* + * Regress test for sshbuf.h buffer API + * + * Placed in the public domain + */ + +#include "../test_helper/test_helper.h" + +void sshbuf_tests(void); +void sshbuf_getput_basic_tests(void); +void sshbuf_getput_crypto_tests(void); +void sshbuf_misc_tests(void); +void sshbuf_fuzz_tests(void); +void sshbuf_getput_fuzz_tests(void); +void sshbuf_fixed(void); + +void +tests(void) +{ + sshbuf_tests(); + sshbuf_getput_basic_tests(); + sshbuf_getput_crypto_tests(); + sshbuf_misc_tests(); + sshbuf_fuzz_tests(); + sshbuf_getput_fuzz_tests(); + sshbuf_fixed(); +} diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/Makefile b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/Makefile new file mode 100644 index 000000000..1bcd26676 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/Makefile @@ -0,0 +1,13 @@ +# $OpenBSD: Makefile,v 1.1 2014/06/24 01:14:18 djm Exp $ + +TEST_ENV= "MALLOC_OPTIONS=AFGJPRX" + +PROG=test_sshkey +SRCS=tests.c test_sshkey.c test_file.c test_fuzz.c common.c +REGRESS_TARGETS=run-regress-${PROG} + +run-regress-${PROG}: ${PROG} + env ${TEST_ENV} ./${PROG} -d ${.CURDIR}/testdata + +.include + diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/common.c b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/common.c new file mode 100644 index 000000000..b598f05cb --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/common.c @@ -0,0 +1,84 @@ +/* $OpenBSD: common.c,v 1.2 2015/01/08 13:10:58 djm Exp $ */ +/* + * Helpers for key API tests + * + * Placed in the public domain + */ + +#include "includes.h" + +#include +#include +#include +#include +#include +#ifdef HAVE_STDINT_H +#include +#endif +#include +#include +#include + +#include +#include +#include +#include +#ifdef OPENSSL_HAS_NISTP256 +# include +#endif + +#include "../test_helper/test_helper.h" + +#include "ssherr.h" +#include "authfile.h" +#include "sshkey.h" +#include "sshbuf.h" + +#include "common.h" + +struct sshbuf * +load_file(const char *name) +{ + int fd; + struct sshbuf *ret; + + ASSERT_PTR_NE(ret = sshbuf_new(), NULL); + ASSERT_INT_NE(fd = open(test_data_file(name), O_RDONLY), -1); + ASSERT_INT_EQ(sshkey_load_file(fd, ret), 0); + close(fd); + return ret; +} + +struct sshbuf * +load_text_file(const char *name) +{ + struct sshbuf *ret = load_file(name); + const u_char *p; + + /* Trim whitespace at EOL */ + for (p = sshbuf_ptr(ret); sshbuf_len(ret) > 0;) { + if (p[sshbuf_len(ret) - 1] == '\r' || + p[sshbuf_len(ret) - 1] == '\t' || + p[sshbuf_len(ret) - 1] == ' ' || + p[sshbuf_len(ret) - 1] == '\n') + ASSERT_INT_EQ(sshbuf_consume_end(ret, 1), 0); + else + break; + } + /* \0 terminate */ + ASSERT_INT_EQ(sshbuf_put_u8(ret, 0), 0); + return ret; +} + +BIGNUM * +load_bignum(const char *name) +{ + BIGNUM *ret = NULL; + struct sshbuf *buf; + + buf = load_text_file(name); + ASSERT_INT_NE(BN_hex2bn(&ret, (const char *)sshbuf_ptr(buf)), 0); + sshbuf_free(buf); + return ret; +} + diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/common.h b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/common.h new file mode 100644 index 000000000..bf7d19dce --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/common.h @@ -0,0 +1,16 @@ +/* $OpenBSD: common.h,v 1.1 2014/06/24 01:14:18 djm Exp $ */ +/* + * Helpers for key API tests + * + * Placed in the public domain + */ + +/* Load a binary file into a buffer */ +struct sshbuf *load_file(const char *name); + +/* Load a text file into a buffer */ +struct sshbuf *load_text_file(const char *name); + +/* Load a bignum from a file */ +BIGNUM *load_bignum(const char *name); + diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/mktestdata.sh b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/mktestdata.sh new file mode 100755 index 000000000..e11100145 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/mktestdata.sh @@ -0,0 +1,192 @@ +#!/bin/sh +# $OpenBSD: mktestdata.sh,v 1.5 2015/07/07 14:53:30 markus Exp $ + +PW=mekmitasdigoat + +rsa1_params() { + _in="$1" + _outbase="$2" + set -e + ssh-keygen -f $_in -e -m pkcs8 | \ + openssl rsa -noout -text -pubin | \ + awk '/^Modulus:$/,/^Exponent:/' | \ + grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.n + # XXX need conversion support in ssh-keygen for the other params + for x in n ; do + echo "" >> ${_outbase}.$x + echo ============ ${_outbase}.$x + cat ${_outbase}.$x + echo ============ + done +} + +rsa_params() { + _in="$1" + _outbase="$2" + set -e + openssl rsa -noout -text -in $_in | \ + awk '/^modulus:$/,/^publicExponent:/' | \ + grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.n + openssl rsa -noout -text -in $_in | \ + awk '/^prime1:$/,/^prime2:/' | \ + grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.p + openssl rsa -noout -text -in $_in | \ + awk '/^prime2:$/,/^exponent1:/' | \ + grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.q + for x in n p q ; do + echo "" >> ${_outbase}.$x + echo ============ ${_outbase}.$x + cat ${_outbase}.$x + echo ============ + done +} + +dsa_params() { + _in="$1" + _outbase="$2" + set -e + openssl dsa -noout -text -in $_in | \ + awk '/^priv:$/,/^pub:/' | \ + grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.priv + openssl dsa -noout -text -in $_in | \ + awk '/^pub:/,/^P:/' | #\ + grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.pub + openssl dsa -noout -text -in $_in | \ + awk '/^G:/,0' | \ + grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.g + for x in priv pub g ; do + echo "" >> ${_outbase}.$x + echo ============ ${_outbase}.$x + cat ${_outbase}.$x + echo ============ + done +} + +ecdsa_params() { + _in="$1" + _outbase="$2" + set -e + openssl ec -noout -text -in $_in | \ + awk '/^priv:$/,/^pub:/' | \ + grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.priv + openssl ec -noout -text -in $_in | \ + awk '/^pub:/,/^ASN1 OID:/' | #\ + grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.pub + openssl ec -noout -text -in $_in | \ + grep "ASN1 OID:" | tr -d '\n' | \ + sed 's/.*: //;s/ *$//' > ${_outbase}.curve + for x in priv pub curve ; do + echo "" >> ${_outbase}.$x + echo ============ ${_outbase}.$x + cat ${_outbase}.$x + echo ============ + done +} + +set -ex + +cd testdata + +rm -f rsa1_1 rsa_1 dsa_1 ecdsa_1 ed25519_1 +rm -f rsa1_2 rsa_2 dsa_2 ecdsa_2 ed25519_2 +rm -f rsa_n dsa_n ecdsa_n # new-format keys +rm -f rsa1_1_pw rsa_1_pw dsa_1_pw ecdsa_1_pw ed25519_1_pw +rm -f rsa_n_pw dsa_n_pw ecdsa_n_pw +rm -f pw *.pub *.bn.* *.param.* *.fp *.fp.bb + +ssh-keygen -t rsa1 -b 1024 -C "RSA1 test key #1" -N "" -f rsa1_1 +ssh-keygen -t rsa -b 1024 -C "RSA test key #1" -N "" -f rsa_1 +ssh-keygen -t dsa -b 1024 -C "DSA test key #1" -N "" -f dsa_1 +ssh-keygen -t ecdsa -b 256 -C "ECDSA test key #1" -N "" -f ecdsa_1 +ssh-keygen -t ed25519 -C "ED25519 test key #1" -N "" -f ed25519_1 + +ssh-keygen -t rsa1 -b 2048 -C "RSA1 test key #2" -N "" -f rsa1_2 +ssh-keygen -t rsa -b 2048 -C "RSA test key #2" -N "" -f rsa_2 +ssh-keygen -t dsa -b 1024 -C "DSA test key #2" -N "" -f dsa_2 +ssh-keygen -t ecdsa -b 521 -C "ECDSA test key #2" -N "" -f ecdsa_2 +ssh-keygen -t ed25519 -C "ED25519 test key #1" -N "" -f ed25519_2 + +cp rsa_1 rsa_n +cp dsa_1 dsa_n +cp ecdsa_1 ecdsa_n + +cp rsa1_1 rsa1_1_pw +cp rsa_1 rsa_1_pw +cp dsa_1 dsa_1_pw +cp ecdsa_1 ecdsa_1_pw +cp ed25519_1 ed25519_1_pw +cp rsa_1 rsa_n_pw +cp dsa_1 dsa_n_pw +cp ecdsa_1 ecdsa_n_pw + +ssh-keygen -pf rsa1_1_pw -N "$PW" +ssh-keygen -pf rsa_1_pw -N "$PW" +ssh-keygen -pf dsa_1_pw -N "$PW" +ssh-keygen -pf ecdsa_1_pw -N "$PW" +ssh-keygen -pf ed25519_1_pw -N "$PW" +ssh-keygen -opf rsa_n_pw -N "$PW" +ssh-keygen -opf dsa_n_pw -N "$PW" +ssh-keygen -opf ecdsa_n_pw -N "$PW" + +rsa1_params rsa1_1 rsa1_1.param +rsa1_params rsa1_2 rsa1_2.param +rsa_params rsa_1 rsa_1.param +rsa_params rsa_2 rsa_2.param +dsa_params dsa_1 dsa_1.param +dsa_params dsa_1 dsa_1.param +ecdsa_params ecdsa_1 ecdsa_1.param +ecdsa_params ecdsa_2 ecdsa_2.param +# XXX ed25519 params + +ssh-keygen -s rsa_2 -I hugo -n user1,user2 \ + -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \ + -V 19990101:20110101 -z 1 rsa_1.pub +ssh-keygen -s rsa_2 -I hugo -n user1,user2 \ + -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \ + -V 19990101:20110101 -z 2 dsa_1.pub +ssh-keygen -s rsa_2 -I hugo -n user1,user2 \ + -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \ + -V 19990101:20110101 -z 3 ecdsa_1.pub +ssh-keygen -s rsa_2 -I hugo -n user1,user2 \ + -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \ + -V 19990101:20110101 -z 4 ed25519_1.pub + +ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \ + -V 19990101:20110101 -z 5 rsa_1.pub +ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \ + -V 19990101:20110101 -z 6 dsa_1.pub +ssh-keygen -s ecdsa_1 -I julius -n host1,host2 -h \ + -V 19990101:20110101 -z 7 ecdsa_1.pub +ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \ + -V 19990101:20110101 -z 8 ed25519_1.pub + +ssh-keygen -lf rsa1_1 | awk '{print $2}' > rsa1_1.fp +ssh-keygen -lf rsa_1 | awk '{print $2}' > rsa_1.fp +ssh-keygen -lf dsa_1 | awk '{print $2}' > dsa_1.fp +ssh-keygen -lf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp +ssh-keygen -lf ed25519_1 | awk '{print $2}' > ed25519_1.fp +ssh-keygen -lf rsa1_2 | awk '{print $2}' > rsa1_2.fp +ssh-keygen -lf rsa_2 | awk '{print $2}' > rsa_2.fp +ssh-keygen -lf dsa_2 | awk '{print $2}' > dsa_2.fp +ssh-keygen -lf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp +ssh-keygen -lf ed25519_2 | awk '{print $2}' > ed25519_2.fp + +ssh-keygen -lf dsa_1-cert.pub | awk '{print $2}' > dsa_1-cert.fp +ssh-keygen -lf ecdsa_1-cert.pub | awk '{print $2}' > ecdsa_1-cert.fp +ssh-keygen -lf ed25519_1-cert.pub | awk '{print $2}' > ed25519_1-cert.fp +ssh-keygen -lf rsa_1-cert.pub | awk '{print $2}' > rsa_1-cert.fp + +ssh-keygen -Bf rsa1_1 | awk '{print $2}' > rsa1_1.fp.bb +ssh-keygen -Bf rsa_1 | awk '{print $2}' > rsa_1.fp.bb +ssh-keygen -Bf dsa_1 | awk '{print $2}' > dsa_1.fp.bb +ssh-keygen -Bf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp.bb +ssh-keygen -Bf ed25519_1 | awk '{print $2}' > ed25519_1.fp.bb +ssh-keygen -Bf rsa1_2 | awk '{print $2}' > rsa1_2.fp.bb +ssh-keygen -Bf rsa_2 | awk '{print $2}' > rsa_2.fp.bb +ssh-keygen -Bf dsa_2 | awk '{print $2}' > dsa_2.fp.bb +ssh-keygen -Bf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp.bb +ssh-keygen -Bf ed25519_2 | awk '{print $2}' > ed25519_2.fp.bb + +# XXX Extend ssh-keygen to do detached signatures (better to test/fuzz against) + +echo "$PW" > pw diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/test_file.c b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/test_file.c new file mode 100644 index 000000000..c8a236937 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/test_file.c @@ -0,0 +1,460 @@ +/* $OpenBSD: test_file.c,v 1.4 2015/07/07 14:53:30 markus Exp $ */ +/* + * Regress test for sshkey.h key management API + * + * Placed in the public domain + */ + +#include "includes.h" + +#include +#include +#include +#include +#include +#ifdef HAVE_STDINT_H +#include +#endif +#include +#include +#include + +#include +#include +#include +#include +#ifdef OPENSSL_HAS_NISTP256 +# include +#endif + +#include "../test_helper/test_helper.h" + +#include "ssherr.h" +#include "authfile.h" +#include "sshkey.h" +#include "sshbuf.h" +#include "digest.h" + +#include "common.h" + +void sshkey_file_tests(void); + +void +sshkey_file_tests(void) +{ + struct sshkey *k1, *k2; + struct sshbuf *buf, *pw; + BIGNUM *a, *b, *c; + char *cp; + + TEST_START("load passphrase"); + pw = load_text_file("pw"); + TEST_DONE(); + +#ifdef WITH_SSH1 + TEST_START("parse RSA1 from private"); + buf = load_file("rsa1_1"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "rsa1_1", + &k1, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k1, NULL); + a = load_bignum("rsa1_1.param.n"); + ASSERT_BIGNUM_EQ(k1->rsa->n, a); + BN_free(a); + TEST_DONE(); + + TEST_START("parse RSA1 from private w/ passphrase"); + buf = load_file("rsa1_1_pw"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, + (const char *)sshbuf_ptr(pw), "rsa1_1_pw", &k2, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("load RSA1 from public"); + ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa1_1.pub"), &k2, + NULL), 0); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("RSA1 key hex fingerprint"); + buf = load_text_file("rsa1_1.fp"); + cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64); + ASSERT_PTR_NE(cp, NULL); + ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); + sshbuf_free(buf); + free(cp); + TEST_DONE(); + + TEST_START("RSA1 key bubblebabble fingerprint"); + buf = load_text_file("rsa1_1.fp.bb"); + cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); + ASSERT_PTR_NE(cp, NULL); + ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); + sshbuf_free(buf); + free(cp); + TEST_DONE(); + + sshkey_free(k1); +#endif + + TEST_START("parse RSA from private"); + buf = load_file("rsa_1"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "rsa_1", + &k1, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k1, NULL); + a = load_bignum("rsa_1.param.n"); + b = load_bignum("rsa_1.param.p"); + c = load_bignum("rsa_1.param.q"); + ASSERT_BIGNUM_EQ(k1->rsa->n, a); + ASSERT_BIGNUM_EQ(k1->rsa->p, b); + ASSERT_BIGNUM_EQ(k1->rsa->q, c); + BN_free(a); + BN_free(b); + BN_free(c); + TEST_DONE(); + + TEST_START("parse RSA from private w/ passphrase"); + buf = load_file("rsa_1_pw"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, + (const char *)sshbuf_ptr(pw), "rsa_1_pw", &k2, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("parse RSA from new-format"); + buf = load_file("rsa_n"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, + "", "rsa_n", &k2, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("parse RSA from new-format w/ passphrase"); + buf = load_file("rsa_n_pw"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, + (const char *)sshbuf_ptr(pw), "rsa_n_pw", &k2, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("load RSA from public"); + ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, + NULL), 0); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("load RSA cert"); + ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k2), 0); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(k2->type, KEY_RSA_CERT); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 0); + ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1); + TEST_DONE(); + + TEST_START("RSA key hex fingerprint"); + buf = load_text_file("rsa_1.fp"); + cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64); + ASSERT_PTR_NE(cp, NULL); + ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); + sshbuf_free(buf); + free(cp); + TEST_DONE(); + + TEST_START("RSA cert hex fingerprint"); + buf = load_text_file("rsa_1-cert.fp"); + cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64); + ASSERT_PTR_NE(cp, NULL); + ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); + sshbuf_free(buf); + free(cp); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("RSA key bubblebabble fingerprint"); + buf = load_text_file("rsa_1.fp.bb"); + cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); + ASSERT_PTR_NE(cp, NULL); + ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); + sshbuf_free(buf); + free(cp); + TEST_DONE(); + + sshkey_free(k1); + + TEST_START("parse DSA from private"); + buf = load_file("dsa_1"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "dsa_1", + &k1, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k1, NULL); + a = load_bignum("dsa_1.param.g"); + b = load_bignum("dsa_1.param.priv"); + c = load_bignum("dsa_1.param.pub"); + ASSERT_BIGNUM_EQ(k1->dsa->g, a); + ASSERT_BIGNUM_EQ(k1->dsa->priv_key, b); + ASSERT_BIGNUM_EQ(k1->dsa->pub_key, c); + BN_free(a); + BN_free(b); + BN_free(c); + TEST_DONE(); + + TEST_START("parse DSA from private w/ passphrase"); + buf = load_file("dsa_1_pw"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, + (const char *)sshbuf_ptr(pw), "dsa_1_pw", &k2, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("parse DSA from new-format"); + buf = load_file("dsa_n"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, + "", "dsa_n", &k2, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("parse DSA from new-format w/ passphrase"); + buf = load_file("dsa_n_pw"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, + (const char *)sshbuf_ptr(pw), "dsa_n_pw", &k2, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("load DSA from public"); + ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_1.pub"), &k2, + NULL), 0); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("load DSA cert"); + ASSERT_INT_EQ(sshkey_load_cert(test_data_file("dsa_1"), &k2), 0); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(k2->type, KEY_DSA_CERT); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 0); + ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1); + TEST_DONE(); + + TEST_START("DSA key hex fingerprint"); + buf = load_text_file("dsa_1.fp"); + cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64); + ASSERT_PTR_NE(cp, NULL); + ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); + sshbuf_free(buf); + free(cp); + TEST_DONE(); + + TEST_START("DSA cert hex fingerprint"); + buf = load_text_file("dsa_1-cert.fp"); + cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64); + ASSERT_PTR_NE(cp, NULL); + ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); + sshbuf_free(buf); + free(cp); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("DSA key bubblebabble fingerprint"); + buf = load_text_file("dsa_1.fp.bb"); + cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); + ASSERT_PTR_NE(cp, NULL); + ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); + sshbuf_free(buf); + free(cp); + TEST_DONE(); + + sshkey_free(k1); + +#ifdef OPENSSL_HAS_ECC + TEST_START("parse ECDSA from private"); + buf = load_file("ecdsa_1"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "ecdsa_1", + &k1, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k1, NULL); + buf = load_text_file("ecdsa_1.param.curve"); + ASSERT_STRING_EQ((const char *)sshbuf_ptr(buf), + OBJ_nid2sn(k1->ecdsa_nid)); + sshbuf_free(buf); + a = load_bignum("ecdsa_1.param.priv"); + b = load_bignum("ecdsa_1.param.pub"); + c = EC_POINT_point2bn(EC_KEY_get0_group(k1->ecdsa), + EC_KEY_get0_public_key(k1->ecdsa), POINT_CONVERSION_UNCOMPRESSED, + NULL, NULL); + ASSERT_PTR_NE(c, NULL); + ASSERT_BIGNUM_EQ(EC_KEY_get0_private_key(k1->ecdsa), a); + ASSERT_BIGNUM_EQ(b, c); + BN_free(a); + BN_free(b); + BN_free(c); + TEST_DONE(); + + TEST_START("parse ECDSA from private w/ passphrase"); + buf = load_file("ecdsa_1_pw"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, + (const char *)sshbuf_ptr(pw), "ecdsa_1_pw", &k2, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("parse ECDSA from new-format"); + buf = load_file("ecdsa_n"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, + "", "ecdsa_n", &k2, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("parse ECDSA from new-format w/ passphrase"); + buf = load_file("ecdsa_n_pw"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, + (const char *)sshbuf_ptr(pw), "ecdsa_n_pw", &k2, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("load ECDSA from public"); + ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_1.pub"), &k2, + NULL), 0); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("load ECDSA cert"); + ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ecdsa_1"), &k2), 0); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(k2->type, KEY_ECDSA_CERT); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 0); + ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1); + TEST_DONE(); + + TEST_START("ECDSA key hex fingerprint"); + buf = load_text_file("ecdsa_1.fp"); + cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64); + ASSERT_PTR_NE(cp, NULL); + ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); + sshbuf_free(buf); + free(cp); + TEST_DONE(); + + TEST_START("ECDSA cert hex fingerprint"); + buf = load_text_file("ecdsa_1-cert.fp"); + cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64); + ASSERT_PTR_NE(cp, NULL); + ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); + sshbuf_free(buf); + free(cp); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("ECDSA key bubblebabble fingerprint"); + buf = load_text_file("ecdsa_1.fp.bb"); + cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); + ASSERT_PTR_NE(cp, NULL); + ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); + sshbuf_free(buf); + free(cp); + TEST_DONE(); + + sshkey_free(k1); +#endif /* OPENSSL_HAS_ECC */ + + TEST_START("parse Ed25519 from private"); + buf = load_file("ed25519_1"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "ed25519_1", + &k1, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k1, NULL); + ASSERT_INT_EQ(k1->type, KEY_ED25519); + /* XXX check key contents */ + TEST_DONE(); + + TEST_START("parse Ed25519 from private w/ passphrase"); + buf = load_file("ed25519_1_pw"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, + (const char *)sshbuf_ptr(pw), "ed25519_1_pw", &k2, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("load Ed25519 from public"); + ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_1.pub"), &k2, + NULL), 0); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("load Ed25519 cert"); + ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ed25519_1"), &k2), 0); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(k2->type, KEY_ED25519_CERT); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 0); + ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1); + TEST_DONE(); + + TEST_START("Ed25519 key hex fingerprint"); + buf = load_text_file("ed25519_1.fp"); + cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64); + ASSERT_PTR_NE(cp, NULL); + ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); + sshbuf_free(buf); + free(cp); + TEST_DONE(); + + TEST_START("Ed25519 cert hex fingerprint"); + buf = load_text_file("ed25519_1-cert.fp"); + cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64); + ASSERT_PTR_NE(cp, NULL); + ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); + sshbuf_free(buf); + free(cp); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("Ed25519 key bubblebabble fingerprint"); + buf = load_text_file("ed25519_1.fp.bb"); + cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); + ASSERT_PTR_NE(cp, NULL); + ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); + sshbuf_free(buf); + free(cp); + TEST_DONE(); + + sshkey_free(k1); + + sshbuf_free(pw); + +} diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/test_fuzz.c b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/test_fuzz.c new file mode 100644 index 000000000..1f08a2e43 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/test_fuzz.c @@ -0,0 +1,411 @@ +/* $OpenBSD: test_fuzz.c,v 1.4 2015/03/04 23:22:35 djm Exp $ */ +/* + * Fuzz tests for key parsing + * + * Placed in the public domain + */ + +#include "includes.h" + +#include +#include +#include +#include +#include +#ifdef HAVE_STDINT_H +#include +#endif +#include +#include +#include + +#include +#include +#include +#include +#ifdef OPENSSL_HAS_NISTP256 +# include +#endif + +#include "../test_helper/test_helper.h" + +#include "ssherr.h" +#include "authfile.h" +#include "sshkey.h" +#include "sshbuf.h" + +#include "common.h" + +void sshkey_fuzz_tests(void); + +static void +onerror(void *fuzz) +{ + fprintf(stderr, "Failed during fuzz:\n"); + fuzz_dump((struct fuzz *)fuzz); +} + +static void +public_fuzz(struct sshkey *k) +{ + struct sshkey *k1; + struct sshbuf *buf; + struct fuzz *fuzz; + + ASSERT_PTR_NE(buf = sshbuf_new(), NULL); + ASSERT_INT_EQ(sshkey_putb(k, buf), 0); + /* XXX need a way to run the tests in "slow, but complete" mode */ + fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | /* XXX too slow FUZZ_2_BIT_FLIP | */ + FUZZ_1_BYTE_FLIP | /* XXX too slow FUZZ_2_BYTE_FLIP | */ + FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, + sshbuf_mutable_ptr(buf), sshbuf_len(buf)); + ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(buf), sshbuf_len(buf), + &k1), 0); + sshkey_free(k1); + sshbuf_free(buf); + TEST_ONERROR(onerror, fuzz); + for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { + if (sshkey_from_blob(fuzz_ptr(fuzz), fuzz_len(fuzz), &k1) == 0) + sshkey_free(k1); + } + fuzz_cleanup(fuzz); +} + +static void +sig_fuzz(struct sshkey *k) +{ + struct fuzz *fuzz; + u_char *sig, c[] = "some junk to be signed"; + size_t l; + + ASSERT_INT_EQ(sshkey_sign(k, &sig, &l, c, sizeof(c), 0), 0); + ASSERT_SIZE_T_GT(l, 0); + fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | /* too slow FUZZ_2_BIT_FLIP | */ + FUZZ_1_BYTE_FLIP | FUZZ_2_BYTE_FLIP | + FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, sig, l); + ASSERT_INT_EQ(sshkey_verify(k, sig, l, c, sizeof(c), 0), 0); + free(sig); + TEST_ONERROR(onerror, fuzz); + for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { + /* Ensure 1-bit difference at least */ + if (fuzz_matches_original(fuzz)) + continue; + ASSERT_INT_NE(sshkey_verify(k, fuzz_ptr(fuzz), fuzz_len(fuzz), + c, sizeof(c), 0), 0); + } + fuzz_cleanup(fuzz); +} + +void +sshkey_fuzz_tests(void) +{ + struct sshkey *k1; + struct sshbuf *buf, *fuzzed; + struct fuzz *fuzz; + int r; + +#ifdef WITH_SSH1 + TEST_START("fuzz RSA1 private"); + buf = load_file("rsa1_1"); + fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP | + FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, + sshbuf_mutable_ptr(buf), sshbuf_len(buf)); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", + &k1, NULL), 0); + sshkey_free(k1); + sshbuf_free(buf); + ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); + TEST_ONERROR(onerror, fuzz); + for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { + r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); + ASSERT_INT_EQ(r, 0); + if (sshkey_parse_private_fileblob(fuzzed, "", "key", + &k1, NULL) == 0) + sshkey_free(k1); + sshbuf_reset(fuzzed); + } + sshbuf_free(fuzzed); + fuzz_cleanup(fuzz); + TEST_DONE(); + + TEST_START("fuzz RSA1 public"); + buf = load_file("rsa1_1_pw"); + fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP | + FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, + sshbuf_mutable_ptr(buf), sshbuf_len(buf)); + ASSERT_INT_EQ(sshkey_parse_public_rsa1_fileblob(buf, &k1, NULL), 0); + sshkey_free(k1); + sshbuf_free(buf); + ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); + TEST_ONERROR(onerror, fuzz); + for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { + r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); + ASSERT_INT_EQ(r, 0); + if (sshkey_parse_public_rsa1_fileblob(fuzzed, &k1, NULL) == 0) + sshkey_free(k1); + sshbuf_reset(fuzzed); + } + sshbuf_free(fuzzed); + fuzz_cleanup(fuzz); + TEST_DONE(); +#endif + + TEST_START("fuzz RSA private"); + buf = load_file("rsa_1"); + fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), + sshbuf_len(buf)); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", + &k1, NULL), 0); + sshkey_free(k1); + sshbuf_free(buf); + ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); + TEST_ONERROR(onerror, fuzz); + for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { + r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); + ASSERT_INT_EQ(r, 0); + if (sshkey_parse_private_fileblob(fuzzed, "", "key", + &k1, NULL) == 0) + sshkey_free(k1); + sshbuf_reset(fuzzed); + } + sshbuf_free(fuzzed); + fuzz_cleanup(fuzz); + TEST_DONE(); + + TEST_START("fuzz RSA new-format private"); + buf = load_file("rsa_n"); + fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), + sshbuf_len(buf)); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", + &k1, NULL), 0); + sshkey_free(k1); + sshbuf_free(buf); + ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); + TEST_ONERROR(onerror, fuzz); + for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { + r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); + ASSERT_INT_EQ(r, 0); + if (sshkey_parse_private_fileblob(fuzzed, "", "key", + &k1, NULL) == 0) + sshkey_free(k1); + sshbuf_reset(fuzzed); + } + sshbuf_free(fuzzed); + fuzz_cleanup(fuzz); + TEST_DONE(); + + TEST_START("fuzz DSA private"); + buf = load_file("dsa_1"); + fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), + sshbuf_len(buf)); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", + &k1, NULL), 0); + sshkey_free(k1); + sshbuf_free(buf); + ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); + TEST_ONERROR(onerror, fuzz); + for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { + r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); + ASSERT_INT_EQ(r, 0); + if (sshkey_parse_private_fileblob(fuzzed, "", "key", + &k1, NULL) == 0) + sshkey_free(k1); + sshbuf_reset(fuzzed); + } + sshbuf_free(fuzzed); + fuzz_cleanup(fuzz); + TEST_DONE(); + + TEST_START("fuzz DSA new-format private"); + buf = load_file("dsa_n"); + fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), + sshbuf_len(buf)); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", + &k1, NULL), 0); + sshkey_free(k1); + sshbuf_free(buf); + ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); + TEST_ONERROR(onerror, fuzz); + for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { + r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); + ASSERT_INT_EQ(r, 0); + if (sshkey_parse_private_fileblob(fuzzed, "", "key", + &k1, NULL) == 0) + sshkey_free(k1); + sshbuf_reset(fuzzed); + } + sshbuf_free(fuzzed); + fuzz_cleanup(fuzz); + TEST_DONE(); + +#ifdef OPENSSL_HAS_ECC + TEST_START("fuzz ECDSA private"); + buf = load_file("ecdsa_1"); + fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), + sshbuf_len(buf)); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", + &k1, NULL), 0); + sshkey_free(k1); + sshbuf_free(buf); + ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); + TEST_ONERROR(onerror, fuzz); + for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { + r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); + ASSERT_INT_EQ(r, 0); + if (sshkey_parse_private_fileblob(fuzzed, "", "key", + &k1, NULL) == 0) + sshkey_free(k1); + sshbuf_reset(fuzzed); + } + sshbuf_free(fuzzed); + fuzz_cleanup(fuzz); + TEST_DONE(); + + TEST_START("fuzz ECDSA new-format private"); + buf = load_file("ecdsa_n"); + fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), + sshbuf_len(buf)); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", + &k1, NULL), 0); + sshkey_free(k1); + sshbuf_free(buf); + ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); + TEST_ONERROR(onerror, fuzz); + for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { + r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); + ASSERT_INT_EQ(r, 0); + if (sshkey_parse_private_fileblob(fuzzed, "", "key", + &k1, NULL) == 0) + sshkey_free(k1); + sshbuf_reset(fuzzed); + } + sshbuf_free(fuzzed); + fuzz_cleanup(fuzz); + TEST_DONE(); +#endif + + TEST_START("fuzz Ed25519 private"); + buf = load_file("ed25519_1"); + fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), + sshbuf_len(buf)); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", + &k1, NULL), 0); + sshkey_free(k1); + sshbuf_free(buf); + ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); + TEST_ONERROR(onerror, fuzz); + for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { + r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); + ASSERT_INT_EQ(r, 0); + if (sshkey_parse_private_fileblob(fuzzed, "", "key", + &k1, NULL) == 0) + sshkey_free(k1); + sshbuf_reset(fuzzed); + } + sshbuf_free(fuzzed); + fuzz_cleanup(fuzz); + TEST_DONE(); + + TEST_START("fuzz RSA public"); + buf = load_file("rsa_1"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", + &k1, NULL), 0); + sshbuf_free(buf); + public_fuzz(k1); + sshkey_free(k1); + TEST_DONE(); + + TEST_START("fuzz RSA cert"); + ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0); + public_fuzz(k1); + sshkey_free(k1); + TEST_DONE(); + + TEST_START("fuzz DSA public"); + buf = load_file("dsa_1"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", + &k1, NULL), 0); + sshbuf_free(buf); + public_fuzz(k1); + sshkey_free(k1); + TEST_DONE(); + + TEST_START("fuzz DSA cert"); + ASSERT_INT_EQ(sshkey_load_cert(test_data_file("dsa_1"), &k1), 0); + public_fuzz(k1); + sshkey_free(k1); + TEST_DONE(); + +#ifdef OPENSSL_HAS_ECC + TEST_START("fuzz ECDSA public"); + buf = load_file("ecdsa_1"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", + &k1, NULL), 0); + sshbuf_free(buf); + public_fuzz(k1); + sshkey_free(k1); + TEST_DONE(); + + TEST_START("fuzz ECDSA cert"); + ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ecdsa_1"), &k1), 0); + public_fuzz(k1); + sshkey_free(k1); + TEST_DONE(); +#endif + + TEST_START("fuzz Ed25519 public"); + buf = load_file("ed25519_1"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", + &k1, NULL), 0); + sshbuf_free(buf); + public_fuzz(k1); + sshkey_free(k1); + TEST_DONE(); + + TEST_START("fuzz Ed25519 cert"); + ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ed25519_1"), &k1), 0); + public_fuzz(k1); + sshkey_free(k1); + TEST_DONE(); + + TEST_START("fuzz RSA sig"); + buf = load_file("rsa_1"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", + &k1, NULL), 0); + sshbuf_free(buf); + sig_fuzz(k1); + sshkey_free(k1); + TEST_DONE(); + + TEST_START("fuzz DSA sig"); + buf = load_file("dsa_1"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", + &k1, NULL), 0); + sshbuf_free(buf); + sig_fuzz(k1); + sshkey_free(k1); + TEST_DONE(); + +#ifdef OPENSSL_HAS_ECC + TEST_START("fuzz ECDSA sig"); + buf = load_file("ecdsa_1"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", + &k1, NULL), 0); + sshbuf_free(buf); + sig_fuzz(k1); + sshkey_free(k1); + TEST_DONE(); +#endif + + TEST_START("fuzz Ed25519 sig"); + buf = load_file("ed25519_1"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", + &k1, NULL), 0); + sshbuf_free(buf); + sig_fuzz(k1); + sshkey_free(k1); + TEST_DONE(); + +/* XXX fuzz decoded new-format blobs too */ + +} diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/test_sshkey.c b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/test_sshkey.c new file mode 100644 index 000000000..9b3ce7ee4 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/test_sshkey.c @@ -0,0 +1,521 @@ +/* $OpenBSD: test_sshkey.c,v 1.7 2015/08/05 05:27:33 djm Exp $ */ +/* + * Regress test for sshkey.h key management API + * + * Placed in the public domain + */ + +#include "includes.h" + +#include +#include +#include +#ifdef HAVE_STDINT_H +#include +#endif +#include +#include + +#include +#include +#include +#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) +# include +#endif + +#include "../test_helper/test_helper.h" + +#include "ssherr.h" +#include "sshbuf.h" +#define SSHBUF_INTERNAL 1 /* access internals for testing */ +#include "sshkey.h" + +#include "authfile.h" +#include "common.h" +#include "ssh2.h" + +void sshkey_tests(void); + +static void +put_opt(struct sshbuf *b, const char *name, const char *value) +{ + struct sshbuf *sect; + + sect = sshbuf_new(); + ASSERT_PTR_NE(sect, NULL); + ASSERT_INT_EQ(sshbuf_put_cstring(b, name), 0); + if (value != NULL) + ASSERT_INT_EQ(sshbuf_put_cstring(sect, value), 0); + ASSERT_INT_EQ(sshbuf_put_stringb(b, sect), 0); + sshbuf_free(sect); +} + +static void +build_cert(struct sshbuf *b, const struct sshkey *k, const char *type, + const struct sshkey *sign_key, const struct sshkey *ca_key) +{ + struct sshbuf *ca_buf, *pk, *principals, *critopts, *exts; + u_char *sigblob; + size_t siglen; + + ca_buf = sshbuf_new(); + ASSERT_PTR_NE(ca_buf, NULL); + ASSERT_INT_EQ(sshkey_putb(ca_key, ca_buf), 0); + + /* + * Get the public key serialisation by rendering the key and skipping + * the type string. This is a bit of a hack :/ + */ + pk = sshbuf_new(); + ASSERT_PTR_NE(pk, NULL); + ASSERT_INT_EQ(sshkey_putb_plain(k, pk), 0); + ASSERT_INT_EQ(sshbuf_skip_string(pk), 0); + + principals = sshbuf_new(); + ASSERT_PTR_NE(principals, NULL); + ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gsamsa"), 0); + ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gregor"), 0); + + critopts = sshbuf_new(); + ASSERT_PTR_NE(critopts, NULL); + put_opt(critopts, "force-command", "/usr/local/bin/nethack"); + put_opt(critopts, "source-address", "192.168.0.0/24,127.0.0.1,::1"); + + exts = sshbuf_new(); + ASSERT_PTR_NE(exts, NULL); + put_opt(critopts, "permit-X11-forwarding", NULL); + + ASSERT_INT_EQ(sshbuf_put_cstring(b, type), 0); + ASSERT_INT_EQ(sshbuf_put_cstring(b, "noncenoncenonce!"), 0); /* nonce */ + ASSERT_INT_EQ(sshbuf_putb(b, pk), 0); /* public key serialisation */ + ASSERT_INT_EQ(sshbuf_put_u64(b, 1234), 0); /* serial */ + ASSERT_INT_EQ(sshbuf_put_u32(b, SSH2_CERT_TYPE_USER), 0); /* type */ + ASSERT_INT_EQ(sshbuf_put_cstring(b, "gregor"), 0); /* key ID */ + ASSERT_INT_EQ(sshbuf_put_stringb(b, principals), 0); /* principals */ + ASSERT_INT_EQ(sshbuf_put_u64(b, 0), 0); /* start */ + ASSERT_INT_EQ(sshbuf_put_u64(b, 0xffffffffffffffffULL), 0); /* end */ + ASSERT_INT_EQ(sshbuf_put_stringb(b, critopts), 0); /* options */ + ASSERT_INT_EQ(sshbuf_put_stringb(b, exts), 0); /* extensions */ + ASSERT_INT_EQ(sshbuf_put_string(b, NULL, 0), 0); /* reserved */ + ASSERT_INT_EQ(sshbuf_put_stringb(b, ca_buf), 0); /* signature key */ + ASSERT_INT_EQ(sshkey_sign(sign_key, &sigblob, &siglen, + sshbuf_ptr(b), sshbuf_len(b), 0), 0); + ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */ + + free(sigblob); + sshbuf_free(ca_buf); + sshbuf_free(exts); + sshbuf_free(critopts); + sshbuf_free(principals); + sshbuf_free(pk); +} + +static void +signature_test(struct sshkey *k, struct sshkey *bad, const u_char *d, size_t l) +{ + size_t len; + u_char *sig; + + ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, 0), 0); + ASSERT_SIZE_T_GT(len, 8); + ASSERT_PTR_NE(sig, NULL); + ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, 0), 0); + ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, 0), 0); + /* Fuzz test is more comprehensive, this is just a smoke test */ + sig[len - 5] ^= 0x10; + ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, 0), 0); + free(sig); +} + +static void +banana(u_char *s, size_t l) +{ + size_t o; + const u_char the_banana[] = { 'b', 'a', 'n', 'a', 'n', 'a' }; + + for (o = 0; o < l; o += sizeof(the_banana)) { + if (l - o < sizeof(the_banana)) { + memcpy(s + o, "nanananana", l - o); + break; + } + memcpy(s + o, banana, sizeof(the_banana)); + } +} + +static void +signature_tests(struct sshkey *k, struct sshkey *bad) +{ + u_char i, buf[2049]; + size_t lens[] = { + 1, 2, 7, 8, 9, 15, 16, 17, 31, 32, 33, 127, 128, 129, + 255, 256, 257, 1023, 1024, 1025, 2047, 2048, 2049 + }; + + for (i = 0; i < (sizeof(lens)/sizeof(lens[0])); i++) { + test_subtest_info("%s key, banana length %zu", + sshkey_type(k), lens[i]); + banana(buf, lens[i]); + signature_test(k, bad, buf, lens[i]); + } +} + +static struct sshkey * +get_private(const char *n) +{ + struct sshbuf *b; + struct sshkey *ret; + + b = load_file(n); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", n, &ret, NULL), 0); + sshbuf_free(b); + return ret; +} + +void +sshkey_tests(void) +{ + struct sshkey *k1, *k2, *k3, *k4, *kr, *kd, *kf; +#ifdef OPENSSL_HAS_ECC + struct sshkey *ke; +#endif + struct sshbuf *b; + + TEST_START("new invalid"); + k1 = sshkey_new(-42); + ASSERT_PTR_EQ(k1, NULL); + TEST_DONE(); + + TEST_START("new/free KEY_UNSPEC"); + k1 = sshkey_new(KEY_UNSPEC); + ASSERT_PTR_NE(k1, NULL); + sshkey_free(k1); + TEST_DONE(); + + TEST_START("new/free KEY_RSA1"); + k1 = sshkey_new(KEY_RSA1); + ASSERT_PTR_NE(k1, NULL); + ASSERT_PTR_NE(k1->rsa, NULL); + ASSERT_PTR_NE(k1->rsa->n, NULL); + ASSERT_PTR_NE(k1->rsa->e, NULL); + ASSERT_PTR_EQ(k1->rsa->p, NULL); + sshkey_free(k1); + TEST_DONE(); + + TEST_START("new/free KEY_RSA"); + k1 = sshkey_new(KEY_RSA); + ASSERT_PTR_NE(k1, NULL); + ASSERT_PTR_NE(k1->rsa, NULL); + ASSERT_PTR_NE(k1->rsa->n, NULL); + ASSERT_PTR_NE(k1->rsa->e, NULL); + ASSERT_PTR_EQ(k1->rsa->p, NULL); + sshkey_free(k1); + TEST_DONE(); + + TEST_START("new/free KEY_DSA"); + k1 = sshkey_new(KEY_DSA); + ASSERT_PTR_NE(k1, NULL); + ASSERT_PTR_NE(k1->dsa, NULL); + ASSERT_PTR_NE(k1->dsa->g, NULL); + ASSERT_PTR_EQ(k1->dsa->priv_key, NULL); + sshkey_free(k1); + TEST_DONE(); + +#ifdef OPENSSL_HAS_ECC + TEST_START("new/free KEY_ECDSA"); + k1 = sshkey_new(KEY_ECDSA); + ASSERT_PTR_NE(k1, NULL); + ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */ + sshkey_free(k1); + TEST_DONE(); +#endif + + TEST_START("new/free KEY_ED25519"); + k1 = sshkey_new(KEY_ED25519); + ASSERT_PTR_NE(k1, NULL); + /* These should be blank until key loaded or generated */ + ASSERT_PTR_EQ(k1->ed25519_sk, NULL); + ASSERT_PTR_EQ(k1->ed25519_pk, NULL); + sshkey_free(k1); + TEST_DONE(); + + TEST_START("new_private KEY_RSA"); + k1 = sshkey_new_private(KEY_RSA); + ASSERT_PTR_NE(k1, NULL); + ASSERT_PTR_NE(k1->rsa, NULL); + ASSERT_PTR_NE(k1->rsa->n, NULL); + ASSERT_PTR_NE(k1->rsa->e, NULL); + ASSERT_PTR_NE(k1->rsa->p, NULL); + ASSERT_INT_EQ(sshkey_add_private(k1), 0); + sshkey_free(k1); + TEST_DONE(); + + TEST_START("new_private KEY_DSA"); + k1 = sshkey_new_private(KEY_DSA); + ASSERT_PTR_NE(k1, NULL); + ASSERT_PTR_NE(k1->dsa, NULL); + ASSERT_PTR_NE(k1->dsa->g, NULL); + ASSERT_PTR_NE(k1->dsa->priv_key, NULL); + ASSERT_INT_EQ(sshkey_add_private(k1), 0); + sshkey_free(k1); + TEST_DONE(); + + TEST_START("generate KEY_RSA too small modulus"); + ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 128, &k1), + SSH_ERR_INVALID_ARGUMENT); + ASSERT_PTR_EQ(k1, NULL); + TEST_DONE(); + + TEST_START("generate KEY_RSA too large modulus"); + ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1 << 20, &k1), + SSH_ERR_INVALID_ARGUMENT); + ASSERT_PTR_EQ(k1, NULL); + TEST_DONE(); + + TEST_START("generate KEY_DSA wrong bits"); + ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 2048, &k1), + SSH_ERR_INVALID_ARGUMENT); + ASSERT_PTR_EQ(k1, NULL); + sshkey_free(k1); + TEST_DONE(); + +#ifdef OPENSSL_HAS_ECC + TEST_START("generate KEY_ECDSA wrong bits"); + ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1), + SSH_ERR_INVALID_ARGUMENT); + ASSERT_PTR_EQ(k1, NULL); + sshkey_free(k1); + TEST_DONE(); +#endif + + TEST_START("generate KEY_RSA"); + ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 767, &kr), + SSH_ERR_INVALID_ARGUMENT); + ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0); + ASSERT_PTR_NE(kr, NULL); + ASSERT_PTR_NE(kr->rsa, NULL); + ASSERT_PTR_NE(kr->rsa->n, NULL); + ASSERT_PTR_NE(kr->rsa->e, NULL); + ASSERT_PTR_NE(kr->rsa->p, NULL); + ASSERT_INT_EQ(BN_num_bits(kr->rsa->n), 1024); + TEST_DONE(); + + TEST_START("generate KEY_DSA"); + ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0); + ASSERT_PTR_NE(kd, NULL); + ASSERT_PTR_NE(kd->dsa, NULL); + ASSERT_PTR_NE(kd->dsa->g, NULL); + ASSERT_PTR_NE(kd->dsa->priv_key, NULL); + TEST_DONE(); + +#ifdef OPENSSL_HAS_ECC + TEST_START("generate KEY_ECDSA"); + ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &ke), 0); + ASSERT_PTR_NE(ke, NULL); + ASSERT_PTR_NE(ke->ecdsa, NULL); + ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL); + ASSERT_PTR_NE(EC_KEY_get0_private_key(ke->ecdsa), NULL); + TEST_DONE(); +#endif + + TEST_START("generate KEY_ED25519"); + ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &kf), 0); + ASSERT_PTR_NE(kf, NULL); + ASSERT_INT_EQ(kf->type, KEY_ED25519); + ASSERT_PTR_NE(kf->ed25519_pk, NULL); + ASSERT_PTR_NE(kf->ed25519_sk, NULL); + TEST_DONE(); + + TEST_START("demote KEY_RSA"); + ASSERT_INT_EQ(sshkey_demote(kr, &k1), 0); + ASSERT_PTR_NE(k1, NULL); + ASSERT_PTR_NE(kr, k1); + ASSERT_INT_EQ(k1->type, KEY_RSA); + ASSERT_PTR_NE(k1->rsa, NULL); + ASSERT_PTR_NE(k1->rsa->n, NULL); + ASSERT_PTR_NE(k1->rsa->e, NULL); + ASSERT_PTR_EQ(k1->rsa->p, NULL); + TEST_DONE(); + + TEST_START("equal KEY_RSA/demoted KEY_RSA"); + ASSERT_INT_EQ(sshkey_equal(kr, k1), 1); + sshkey_free(k1); + TEST_DONE(); + + TEST_START("demote KEY_DSA"); + ASSERT_INT_EQ(sshkey_demote(kd, &k1), 0); + ASSERT_PTR_NE(k1, NULL); + ASSERT_PTR_NE(kd, k1); + ASSERT_INT_EQ(k1->type, KEY_DSA); + ASSERT_PTR_NE(k1->dsa, NULL); + ASSERT_PTR_NE(k1->dsa->g, NULL); + ASSERT_PTR_EQ(k1->dsa->priv_key, NULL); + TEST_DONE(); + + TEST_START("equal KEY_DSA/demoted KEY_DSA"); + ASSERT_INT_EQ(sshkey_equal(kd, k1), 1); + sshkey_free(k1); + TEST_DONE(); + +#ifdef OPENSSL_HAS_ECC + TEST_START("demote KEY_ECDSA"); + ASSERT_INT_EQ(sshkey_demote(ke, &k1), 0); + ASSERT_PTR_NE(k1, NULL); + ASSERT_PTR_NE(ke, k1); + ASSERT_INT_EQ(k1->type, KEY_ECDSA); + ASSERT_PTR_NE(k1->ecdsa, NULL); + ASSERT_INT_EQ(k1->ecdsa_nid, ke->ecdsa_nid); + ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL); + ASSERT_PTR_EQ(EC_KEY_get0_private_key(k1->ecdsa), NULL); + TEST_DONE(); + + TEST_START("equal KEY_ECDSA/demoted KEY_ECDSA"); + ASSERT_INT_EQ(sshkey_equal(ke, k1), 1); + sshkey_free(k1); + TEST_DONE(); +#endif + + TEST_START("demote KEY_ED25519"); + ASSERT_INT_EQ(sshkey_demote(kf, &k1), 0); + ASSERT_PTR_NE(k1, NULL); + ASSERT_PTR_NE(kf, k1); + ASSERT_INT_EQ(k1->type, KEY_ED25519); + ASSERT_PTR_NE(k1->ed25519_pk, NULL); + ASSERT_PTR_EQ(k1->ed25519_sk, NULL); + TEST_DONE(); + + TEST_START("equal KEY_ED25519/demoted KEY_ED25519"); + ASSERT_INT_EQ(sshkey_equal(kf, k1), 1); + sshkey_free(k1); + TEST_DONE(); + + TEST_START("equal mismatched key types"); + ASSERT_INT_EQ(sshkey_equal(kd, kr), 0); +#ifdef OPENSSL_HAS_ECC + ASSERT_INT_EQ(sshkey_equal(kd, ke), 0); + ASSERT_INT_EQ(sshkey_equal(kr, ke), 0); + ASSERT_INT_EQ(sshkey_equal(ke, kf), 0); +#endif + ASSERT_INT_EQ(sshkey_equal(kd, kf), 0); + TEST_DONE(); + + TEST_START("equal different keys"); + ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &k1), 0); + ASSERT_INT_EQ(sshkey_equal(kr, k1), 0); + sshkey_free(k1); + ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &k1), 0); + ASSERT_INT_EQ(sshkey_equal(kd, k1), 0); + sshkey_free(k1); +#ifdef OPENSSL_HAS_ECC + ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &k1), 0); + ASSERT_INT_EQ(sshkey_equal(ke, k1), 0); + sshkey_free(k1); +#endif + ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &k1), 0); + ASSERT_INT_EQ(sshkey_equal(kf, k1), 0); + sshkey_free(k1); + TEST_DONE(); + + sshkey_free(kr); + sshkey_free(kd); +#ifdef OPENSSL_HAS_ECC + sshkey_free(ke); +#endif + sshkey_free(kf); + + TEST_START("certify key"); + ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_1.pub"), + &k1, NULL), 0); + k2 = get_private("ed25519_2"); + ASSERT_INT_EQ(sshkey_to_certified(k1), 0); + ASSERT_PTR_NE(k1->cert, NULL); + k1->cert->type = SSH2_CERT_TYPE_USER; + k1->cert->serial = 1234; + k1->cert->key_id = strdup("estragon"); + ASSERT_PTR_NE(k1->cert->key_id, NULL); + k1->cert->principals = calloc(4, sizeof(*k1->cert->principals)); + ASSERT_PTR_NE(k1->cert->principals, NULL); + k1->cert->principals[0] = strdup("estragon"); + k1->cert->principals[1] = strdup("vladimir"); + k1->cert->principals[2] = strdup("pozzo"); + k1->cert->principals[3] = strdup("lucky"); + ASSERT_PTR_NE(k1->cert->principals[0], NULL); + ASSERT_PTR_NE(k1->cert->principals[1], NULL); + ASSERT_PTR_NE(k1->cert->principals[2], NULL); + ASSERT_PTR_NE(k1->cert->principals[3], NULL); + k1->cert->valid_after = 0; + k1->cert->valid_before = (u_int64_t)-1; + k1->cert->critical = sshbuf_new(); + ASSERT_PTR_NE(k1->cert->critical, NULL); + k1->cert->extensions = sshbuf_new(); + ASSERT_PTR_NE(k1->cert->extensions, NULL); + put_opt(k1->cert->critical, "force-command", "/usr/bin/true"); + put_opt(k1->cert->critical, "source-address", "127.0.0.1"); + put_opt(k1->cert->extensions, "permit-X11-forwarding", NULL); + put_opt(k1->cert->extensions, "permit-agent-forwarding", NULL); + ASSERT_INT_EQ(sshkey_from_private(k2, &k1->cert->signature_key), 0); + ASSERT_INT_EQ(sshkey_certify(k1, k2), 0); + b = sshbuf_new(); + ASSERT_PTR_NE(b, NULL); + ASSERT_INT_EQ(sshkey_putb(k1, b), 0); + ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k3), 0); + + sshkey_free(k1); + sshkey_free(k2); + sshkey_free(k3); + sshbuf_reset(b); + TEST_DONE(); + + TEST_START("sign and verify RSA"); + k1 = get_private("rsa_1"); + ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2, + NULL), 0); + signature_tests(k1, k2); + sshkey_free(k1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("sign and verify DSA"); + k1 = get_private("dsa_1"); + ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_2.pub"), &k2, + NULL), 0); + signature_tests(k1, k2); + sshkey_free(k1); + sshkey_free(k2); + TEST_DONE(); + +#ifdef OPENSSL_HAS_ECC + TEST_START("sign and verify ECDSA"); + k1 = get_private("ecdsa_1"); + ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_2.pub"), &k2, + NULL), 0); + signature_tests(k1, k2); + sshkey_free(k1); + sshkey_free(k2); + TEST_DONE(); +#endif + + TEST_START("sign and verify ED25519"); + k1 = get_private("ed25519_1"); + ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_2.pub"), &k2, + NULL), 0); + signature_tests(k1, k2); + sshkey_free(k1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("nested certificate"); + ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0); + ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, + NULL), 0); + k3 = get_private("rsa_1"); + build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1); + ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4), + SSH_ERR_KEY_CERT_INVALID_SIGN_KEY); + ASSERT_PTR_EQ(k4, NULL); + sshkey_free(k1); + sshkey_free(k2); + sshkey_free(k3); + sshbuf_free(b); + TEST_DONE(); + +} diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1 b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1 new file mode 100644 index 000000000..d3f24824f --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1 @@ -0,0 +1,12 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIBvAIBAAKBgQD6kutNFRsHTwEAv6d39Lhsqy1apdHBZ9c2HfyRr7WmypyGIy2m +Ka43vzXI8CNwmRSYs+A6d0vJC7Pl+f9QzJ/04NWOA+MiwfurwrR3CRe61QRYb8Py +mcHOxueHs95IcjrbIPNn86cjnPP5qvv/guUzCjuww4zBdJOXpligrGt2XwIVAKMD +/50qQy7j8JaMk+1+Xtg1pK01AoGBAO7l9QVVbSSoy5lq6cOtvpf8UlwOa6+zBwbl +o4gmFd1RwX1yWkA8kQ7RrhCSg8Hc6mIGnKRgKRli/3LgbSfZ0obFJehkRtEWtN4P +h8fVUeS74iQbIwFQeKlYHIlNTRoGtAbdi3nHdV+BBkEQc1V3rjqYqhjOoz/yNsgz +LND26HrdAoGBAOdXpyfmobEBaOqZAuvgj1P0uhjG2P31Ufurv22FWPBU3A9qrkxb +OXwE0LwvjCvrsQV/lrYhJz/tiys40VeahulWZE5SAHMXGIf95LiLSgaXMjko7joo +t+LK84ltLymwZ4QMnYjnZSSclf1UuyQMcUtb34+I0u9Ycnyhp2mSFsQtAhRYIbQ5 +KfXsZuBPuWe5FJz3ldaEgw== +-----END DSA PRIVATE KEY----- diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1-cert.fp b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1-cert.fp new file mode 100644 index 000000000..75ff0e9cd --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1-cert.fp @@ -0,0 +1 @@ +SHA256:kOLgXSoAT8O5T6r36n5NJUYigbux1d7gdH/rmWiJm6s diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1-cert.pub b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1-cert.pub new file mode 100644 index 000000000..e768db1e7 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1-cert.pub @@ -0,0 +1 @@ +ssh-dss-cert-v01@openssh.com AAAAHHNzaC1kc3MtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgdTlbNU9Hn9Qng3FHxwH971bxCIoq1ern/QWFFDWXgmYAAACBAPqS600VGwdPAQC/p3f0uGyrLVql0cFn1zYd/JGvtabKnIYjLaYprje/NcjwI3CZFJiz4Dp3S8kLs+X5/1DMn/Tg1Y4D4yLB+6vCtHcJF7rVBFhvw/KZwc7G54ez3khyOtsg82fzpyOc8/mq+/+C5TMKO7DDjMF0k5emWKCsa3ZfAAAAFQCjA/+dKkMu4/CWjJPtfl7YNaStNQAAAIEA7uX1BVVtJKjLmWrpw62+l/xSXA5rr7MHBuWjiCYV3VHBfXJaQDyRDtGuEJKDwdzqYgacpGApGWL/cuBtJ9nShsUl6GRG0Ra03g+Hx9VR5LviJBsjAVB4qVgciU1NGga0Bt2Lecd1X4EGQRBzVXeuOpiqGM6jP/I2yDMs0Pboet0AAACBAOdXpyfmobEBaOqZAuvgj1P0uhjG2P31Ufurv22FWPBU3A9qrkxbOXwE0LwvjCvrsQV/lrYhJz/tiys40VeahulWZE5SAHMXGIf95LiLSgaXMjko7joot+LK84ltLymwZ4QMnYjnZSSclf1UuyQMcUtb34+I0u9Ycnyhp2mSFsQtAAAAAAAAAAYAAAACAAAABmp1bGl1cwAAABIAAAAFaG9zdDEAAAAFaG9zdDIAAAAANowB8AAAAABNHmBwAAAAAAAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACBThupGO0X+FLQhbz8CoKPwc7V3JNsQuGtlsgN+F7SMGQAAAFMAAAALc3NoLWVkMjU1MTkAAABAh/z1LIdNL1b66tQ8t9DY9BTB3BQKpTKmc7ezyFKLwl96yaIniZwD9Ticdbe/8i/Li3uCFE3EAt8NAIv9zff8Bg== DSA test key #1 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.fp b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.fp new file mode 100644 index 000000000..75ff0e9cd --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.fp @@ -0,0 +1 @@ +SHA256:kOLgXSoAT8O5T6r36n5NJUYigbux1d7gdH/rmWiJm6s diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.fp.bb b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.fp.bb new file mode 100644 index 000000000..ba37776ee --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.fp.bb @@ -0,0 +1 @@ +xetag-todiz-mifah-torec-mynyv-cyvit-gopon-pygag-rupic-cenav-bexax diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.param.g b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.param.g new file mode 100644 index 000000000..e51c3f9fd --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.param.g @@ -0,0 +1 @@ +00eee5f505556d24a8cb996ae9c3adbe97fc525c0e6bafb30706e5a3882615dd51c17d725a403c910ed1ae109283c1dcea62069ca460291962ff72e06d27d9d286c525e86446d116b4de0f87c7d551e4bbe2241b23015078a9581c894d4d1a06b406dd8b79c7755f81064110735577ae3a98aa18cea33ff236c8332cd0f6e87add diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.param.priv b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.param.priv new file mode 100644 index 000000000..4f743314c --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.param.priv @@ -0,0 +1 @@ +5821b43929f5ec66e04fb967b9149cf795d68483 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.param.pub b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.param.pub new file mode 100644 index 000000000..ba0313bee --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.param.pub @@ -0,0 +1 @@ +00e757a727e6a1b10168ea9902ebe08f53f4ba18c6d8fdf551fbabbf6d8558f054dc0f6aae4c5b397c04d0bc2f8c2bebb1057f96b621273fed8b2b38d1579a86e956644e520073171887fde4b88b4a0697323928ee3a28b7e2caf3896d2f29b067840c9d88e765249c95fd54bb240c714b5bdf8f88d2ef58727ca1a7699216c42d diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.pub b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.pub new file mode 100644 index 000000000..41cae2f69 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1.pub @@ -0,0 +1 @@ +ssh-dss AAAAB3NzaC1kc3MAAACBAPqS600VGwdPAQC/p3f0uGyrLVql0cFn1zYd/JGvtabKnIYjLaYprje/NcjwI3CZFJiz4Dp3S8kLs+X5/1DMn/Tg1Y4D4yLB+6vCtHcJF7rVBFhvw/KZwc7G54ez3khyOtsg82fzpyOc8/mq+/+C5TMKO7DDjMF0k5emWKCsa3ZfAAAAFQCjA/+dKkMu4/CWjJPtfl7YNaStNQAAAIEA7uX1BVVtJKjLmWrpw62+l/xSXA5rr7MHBuWjiCYV3VHBfXJaQDyRDtGuEJKDwdzqYgacpGApGWL/cuBtJ9nShsUl6GRG0Ra03g+Hx9VR5LviJBsjAVB4qVgciU1NGga0Bt2Lecd1X4EGQRBzVXeuOpiqGM6jP/I2yDMs0Pboet0AAACBAOdXpyfmobEBaOqZAuvgj1P0uhjG2P31Ufurv22FWPBU3A9qrkxbOXwE0LwvjCvrsQV/lrYhJz/tiys40VeahulWZE5SAHMXGIf95LiLSgaXMjko7joot+LK84ltLymwZ4QMnYjnZSSclf1UuyQMcUtb34+I0u9Ycnyhp2mSFsQt DSA test key #1 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1_pw b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1_pw new file mode 100644 index 000000000..24c73039f --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_1_pw @@ -0,0 +1,15 @@ +-----BEGIN DSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,BC8386C373B22EB7F00ADC821D5D8BE9 + ++HDV2DQ09sxrIAeXTz9r3YFuPRa2hk1+NGcr3ETkXbC6KiZ14wpTnGTloKwaQjIW +eXTa9mpCOWAoohgvsVb+hOuOlP7AfeHu1IXV4EAS+GDpkiV5UxlCXXwqlD75Buu4 +wwDd/p4SWzILH3WGjDk5JIXoxWNY13LHwC7Q6gtGJx4AicUG7YBRTXMIBDa/Kh77 +6o2rFETKmp4VHBvHbakmiETfptdM8bbWxKWeY2vakThyESgeofsLoTOQCIwlEfJC +s2D/KYL65C8VbHYgIoSLTQnooO45DDyxIuhCqP+H23mhv9vB1Od3nc2atgHj/XFs +dcOPFkF/msDRYqxY3V0AS6+jpKwFodZ7g/hyGcyPxOkzlJVuKoKuH6P5PyQ69Gx0 +iqri0xEPyABr7kGlXNrjjctojX+B4WwSnjg/2euXXWFXCRalIdA7ErATTiQbGOx7 +Vd6Gn8PZbSy1MkqEDrZRip0pfAFJYI/8GXPC75BpnRsrVlfhtrngbW+kBP35LzaN +l2K+RQ3gSB3iFoqNb1Kuu6T5MZlyVl5H2dVlJSeb1euQ2OycXdDoFTyJ4AiyWS7w +Vlh8zeJnso5QRDjMwx99pZilbbuFGSLsahiGEveFc6o= +-----END DSA PRIVATE KEY----- diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_2 b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_2 new file mode 100644 index 000000000..3cc9631af --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_2 @@ -0,0 +1,12 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIBvQIBAAKBgQCbyPXNdHeLsjpobPVCMkfagBkt15Zsltqf/PGNP1y1cuz7rsTX +ZekQwUkSTNm5coqXe+ZOw2O4tjobJDd60I1/VPgaB0NYlQR9Hn87M284WD4f6VY+ +aunHmP134a8ybG5G4NqVNF3ihvxAR2pVITqb7kE46r2uYZNcNlHI8voRCwIVAMcP +bwqFNsQbH5pJyZW30wj4KVZ3AoGBAIK98BVeKQVf8qDFqx9ovMuNgVSxpd+N0Yta +5ZEy1OI2ziu5RhjueIM2K7Gq2Mnp38ob1AM53BUxqlcBJaHEDa6rj6yvuMgW9oCJ +dImBM8sIFxfBbXNbpJiMaDwa6WyT84OkpDE6uuAepTMnWOUWkUVkAiyokHDUGXkG +GyoQblbXAoGBAIsf7TaZ804sUWwRV0wI8DYx+hxD5QdrfYPYMtL2fHn3lICimGt0 +FTtUZ25jKg0E0DMBPdET6ZEHB3ZZkR8hFoUzZhdnyJMu3UjVtgaV88Ue3PrXxchk +0W2jHPaAgQU3JIWzo8HFIFqvC/HEL+EyW3rBTY2uXM3XGI+YcWSA4ZrZAhUAsY2f +bDFNzgZ4DaZ9wLRzTgOswPU= +-----END DSA PRIVATE KEY----- diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_2.fp b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_2.fp new file mode 100644 index 000000000..51fbeb4d8 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_2.fp @@ -0,0 +1 @@ +SHA256:ecwhWcXgpdBxZ2e+OjpRRY7dqXHHCD62BGtoVQQBwCk diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_2.fp.bb b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_2.fp.bb new file mode 100644 index 000000000..4d908ee30 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_2.fp.bb @@ -0,0 +1 @@ +xeser-megad-pocan-rozit-belup-tapoh-fapif-kyvit-vonav-cehab-naxax diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_2.pub b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_2.pub new file mode 100644 index 000000000..77bb555d5 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_2.pub @@ -0,0 +1 @@ +ssh-dss AAAAB3NzaC1kc3MAAACBAJvI9c10d4uyOmhs9UIyR9qAGS3XlmyW2p/88Y0/XLVy7PuuxNdl6RDBSRJM2blyipd75k7DY7i2OhskN3rQjX9U+BoHQ1iVBH0efzszbzhYPh/pVj5q6ceY/XfhrzJsbkbg2pU0XeKG/EBHalUhOpvuQTjqva5hk1w2Ucjy+hELAAAAFQDHD28KhTbEGx+aScmVt9MI+ClWdwAAAIEAgr3wFV4pBV/yoMWrH2i8y42BVLGl343Ri1rlkTLU4jbOK7lGGO54gzYrsarYyenfyhvUAzncFTGqVwElocQNrquPrK+4yBb2gIl0iYEzywgXF8Ftc1ukmIxoPBrpbJPzg6SkMTq64B6lMydY5RaRRWQCLKiQcNQZeQYbKhBuVtcAAACBAIsf7TaZ804sUWwRV0wI8DYx+hxD5QdrfYPYMtL2fHn3lICimGt0FTtUZ25jKg0E0DMBPdET6ZEHB3ZZkR8hFoUzZhdnyJMu3UjVtgaV88Ue3PrXxchk0W2jHPaAgQU3JIWzo8HFIFqvC/HEL+EyW3rBTY2uXM3XGI+YcWSA4ZrZ DSA test key #2 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_n b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_n new file mode 100644 index 000000000..d3f24824f --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_n @@ -0,0 +1,12 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIBvAIBAAKBgQD6kutNFRsHTwEAv6d39Lhsqy1apdHBZ9c2HfyRr7WmypyGIy2m +Ka43vzXI8CNwmRSYs+A6d0vJC7Pl+f9QzJ/04NWOA+MiwfurwrR3CRe61QRYb8Py +mcHOxueHs95IcjrbIPNn86cjnPP5qvv/guUzCjuww4zBdJOXpligrGt2XwIVAKMD +/50qQy7j8JaMk+1+Xtg1pK01AoGBAO7l9QVVbSSoy5lq6cOtvpf8UlwOa6+zBwbl +o4gmFd1RwX1yWkA8kQ7RrhCSg8Hc6mIGnKRgKRli/3LgbSfZ0obFJehkRtEWtN4P +h8fVUeS74iQbIwFQeKlYHIlNTRoGtAbdi3nHdV+BBkEQc1V3rjqYqhjOoz/yNsgz +LND26HrdAoGBAOdXpyfmobEBaOqZAuvgj1P0uhjG2P31Ufurv22FWPBU3A9qrkxb +OXwE0LwvjCvrsQV/lrYhJz/tiys40VeahulWZE5SAHMXGIf95LiLSgaXMjko7joo +t+LK84ltLymwZ4QMnYjnZSSclf1UuyQMcUtb34+I0u9Ycnyhp2mSFsQtAhRYIbQ5 +KfXsZuBPuWe5FJz3ldaEgw== +-----END DSA PRIVATE KEY----- diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_n_pw b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_n_pw new file mode 100644 index 000000000..24ac299a4 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/dsa_n_pw @@ -0,0 +1,21 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABCVs+LsMJ +wnB5zM9U9pTXrGAAAAEAAAAAEAAAGzAAAAB3NzaC1kc3MAAACBAPqS600VGwdPAQC/p3f0 +uGyrLVql0cFn1zYd/JGvtabKnIYjLaYprje/NcjwI3CZFJiz4Dp3S8kLs+X5/1DMn/Tg1Y +4D4yLB+6vCtHcJF7rVBFhvw/KZwc7G54ez3khyOtsg82fzpyOc8/mq+/+C5TMKO7DDjMF0 +k5emWKCsa3ZfAAAAFQCjA/+dKkMu4/CWjJPtfl7YNaStNQAAAIEA7uX1BVVtJKjLmWrpw6 +2+l/xSXA5rr7MHBuWjiCYV3VHBfXJaQDyRDtGuEJKDwdzqYgacpGApGWL/cuBtJ9nShsUl +6GRG0Ra03g+Hx9VR5LviJBsjAVB4qVgciU1NGga0Bt2Lecd1X4EGQRBzVXeuOpiqGM6jP/ +I2yDMs0Pboet0AAACBAOdXpyfmobEBaOqZAuvgj1P0uhjG2P31Ufurv22FWPBU3A9qrkxb +OXwE0LwvjCvrsQV/lrYhJz/tiys40VeahulWZE5SAHMXGIf95LiLSgaXMjko7joot+LK84 +ltLymwZ4QMnYjnZSSclf1UuyQMcUtb34+I0u9Ycnyhp2mSFsQtAAAB4HiOcRW4w+sIqBL0 +TPVbf0glN1hUi0rcE63Pqxmvxb8LkldC4IxAUagPrjhNAEW2AY42+CvPrtGB1z7gDADAIW +xZX6wKwIcXP0Qh+xHE12F4u6mwfasssnAp4t1Ki8uCjMjnimgb3KdWpp0kiUV0oR062TXV +PAdfrWjaq4fw0KOqbHIAG/v36AqzuqjSTfDbqvLZM3y0gp2Q1RxaQVJA5ZIKKyqRyFX7sr +BaEIyCgeE3hM0EB7BycY1oIcS/eNxrACBWVJCENl5N7LtEYXNX7TANFniztfXzwaqGTT6A +fCfbW4gz1UKldLUBzbIrPwMWlirAstbHvOf/2Iay2pNAs/SHhI0aF2jsGfvv5/D6N+r9dG +B2SgDKBg7pywMH1DTvg6YT3P4GjCx0GUHqRCFLvD1rDdk4KSjvaRMpVq1PJ0/Wv6UGtsMS +TR0PaEHDRNZqAX4YxqujnWrGKuRJhuz0eUvp7fZvbWHtiAMKV7368kkeUmkOHanb+TS+zs +KINX8ev8zJZ6WVr8Vl+IQavpv0i2bXwS6QqbEuifpv/+uBb7pqRiU4u8en0eMdX1bZoTPM +R6xHCnGD/Jpb3zS91Ya57T6CiXZ12KCaL6nWGnCkZVpzkfJ2HjFklWSWBQ6uyaosDQ== +-----END OPENSSH PRIVATE KEY----- diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1 b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1 new file mode 100644 index 000000000..80382b62d --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1 @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIPPNyUAnjvFr+eT/7t/IyjuQQd/aLFiTY92LB9gIjyrMoAoGCCqGSM49 +AwEHoUQDQgAEDFlblkOrW9ydKVhtM+9AY3c9saBE7SG3lFx38nBavkADDaI9jh3/ +kvG/Jt9vpm22qwoklTCGDfzCkXkIKaWlBw== +-----END EC PRIVATE KEY----- diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp new file mode 100644 index 000000000..e48304f6f --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp @@ -0,0 +1 @@ +SHA256:8ty77fOpABat1y88aNdclQTfU+lVvWe7jYZGw8VYtfg diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1-cert.pub b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1-cert.pub new file mode 100644 index 000000000..55e2a2568 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1-cert.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgOtFRnMigkGliaYfPmX5IidVWfV3tRH6lqRXv0l8bvKoAAAAIbmlzdHAyNTYAAABBBAxZW5ZDq1vcnSlYbTPvQGN3PbGgRO0ht5Rcd/JwWr5AAw2iPY4d/5Lxvybfb6ZttqsKJJUwhg38wpF5CCmlpQcAAAAAAAAABwAAAAIAAAAGanVsaXVzAAAAEgAAAAVob3N0MQAAAAVob3N0MgAAAAA2jAHwAAAAAE0eYHAAAAAAAAAAAAAAAAAAAABoAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAxZW5ZDq1vcnSlYbTPvQGN3PbGgRO0ht5Rcd/JwWr5AAw2iPY4d/5Lxvybfb6ZttqsKJJUwhg38wpF5CCmlpQcAAABkAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAABJAAAAIHbxGwTnue7KxhHXGFvRcxBnekhQ3Qx84vV/Vs4oVCrpAAAAIQC7vk2+d14aS7td7kVXLQn392oALjEBzMZoDvT1vT/zOA== ECDSA test key #1 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.fp b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.fp new file mode 100644 index 000000000..e48304f6f --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.fp @@ -0,0 +1 @@ +SHA256:8ty77fOpABat1y88aNdclQTfU+lVvWe7jYZGw8VYtfg diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.fp.bb b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.fp.bb new file mode 100644 index 000000000..fa23c33c2 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.fp.bb @@ -0,0 +1 @@ +xibah-vocun-sogyn-byhen-rivem-hegyh-luneh-dozyr-vatyf-dufid-myxyx diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.param.curve b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.param.curve new file mode 100644 index 000000000..fa0400467 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.param.curve @@ -0,0 +1 @@ +prime256v1 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.param.priv b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.param.priv new file mode 100644 index 000000000..dc908ad71 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.param.priv @@ -0,0 +1 @@ +00f3cdc940278ef16bf9e4ffeedfc8ca3b9041dfda2c589363dd8b07d8088f2acc diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.param.pub b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.param.pub new file mode 100644 index 000000000..71c9584d6 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.param.pub @@ -0,0 +1 @@ +040c595b9643ab5bdc9d29586d33ef4063773db1a044ed21b7945c77f2705abe40030da23d8e1dff92f1bf26df6fa66db6ab0a249530860dfcc291790829a5a507 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.pub b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.pub new file mode 100644 index 000000000..84a71f976 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAxZW5ZDq1vcnSlYbTPvQGN3PbGgRO0ht5Rcd/JwWr5AAw2iPY4d/5Lxvybfb6ZttqsKJJUwhg38wpF5CCmlpQc= ECDSA test key #1 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1_pw b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1_pw new file mode 100644 index 000000000..5c83a658c --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_1_pw @@ -0,0 +1,8 @@ +-----BEGIN EC PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,7BA38DE00F67851E4207216809C3BB15 + +8QkFoZHQkj9a2mt032sp+WKaJ1fwteqWDd4RpAW9OzDgqzMx1QO43qJgBDTfhzjt +M2Q8YfiGjfBEYpg4kCbacfcV68DEV4z6Ll7rIzzzO7OfWUNL++brD64vKx4z6f46 ++sn4nbZTXilpkzi/nmPDVzrNmTSywA8T7Yf0QcBUxks= +-----END EC PRIVATE KEY----- diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2 b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2 new file mode 100644 index 000000000..0f4e844d1 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2 @@ -0,0 +1,7 @@ +-----BEGIN EC PRIVATE KEY----- +MIHcAgEBBEIBqBtN7e6Essd3dlsgISViPCXXC0atlNkGtoMgSQdBTKVUfeJOi4lc +RZaXJdXnqWUqI/KEsH8h8QN4YcB8ugmAcc+gBwYFK4EEACOhgYkDgYYABAHZ2VNy +oDedBwqsdzY+kkNptc9DrtRCVmO6cULLj+691MhItqVqTMJbTFlI4MnAg9PoGTF/ +0KmLJfy8vSffXGKqqwGKcFNtd1XCo+7Qu9tXbxron9g6Dmu7y8jaLkixcwZwnwLs +6GmA9qZGuiAfOGV0Gf9/u98sr+vikOa4Ow5JFDTw5g== +-----END EC PRIVATE KEY----- diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.fp b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.fp new file mode 100644 index 000000000..581e48aec --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.fp @@ -0,0 +1 @@ +SHA256:ed8YniRHA6qCrErCRnzrWxPHxYuA62a+CAFYUVxJgaI diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.fp.bb b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.fp.bb new file mode 100644 index 000000000..e1cc664c2 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.fp.bb @@ -0,0 +1 @@ +xufag-danul-putub-mokin-pugaz-covid-dofag-nihuz-sysab-genar-zaxyx diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.param.curve b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.param.curve new file mode 100644 index 000000000..617ea2fb8 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.param.curve @@ -0,0 +1 @@ +secp521r1 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.param.priv b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.param.priv new file mode 100644 index 000000000..dd898d9ab --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.param.priv @@ -0,0 +1 @@ +01a81b4dedee84b2c777765b202125623c25d70b46ad94d906b683204907414ca5547de24e8b895c45969725d5e7a9652a23f284b07f21f1037861c07cba098071cf diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.param.pub b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.param.pub new file mode 100644 index 000000000..94301c991 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.param.pub @@ -0,0 +1 @@ +0401d9d95372a0379d070aac77363e924369b5cf43aed4425663ba7142cb8feebdd4c848b6a56a4cc25b4c5948e0c9c083d3e819317fd0a98b25fcbcbd27df5c62aaab018a70536d7755c2a3eed0bbdb576f1ae89fd83a0e6bbbcbc8da2e48b17306709f02ece86980f6a646ba201f38657419ff7fbbdf2cafebe290e6b83b0e491434f0e6 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.pub b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.pub new file mode 100644 index 000000000..be9d84bf5 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_2.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHZ2VNyoDedBwqsdzY+kkNptc9DrtRCVmO6cULLj+691MhItqVqTMJbTFlI4MnAg9PoGTF/0KmLJfy8vSffXGKqqwGKcFNtd1XCo+7Qu9tXbxron9g6Dmu7y8jaLkixcwZwnwLs6GmA9qZGuiAfOGV0Gf9/u98sr+vikOa4Ow5JFDTw5g== ECDSA test key #2 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_n b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_n new file mode 100644 index 000000000..80382b62d --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_n @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIPPNyUAnjvFr+eT/7t/IyjuQQd/aLFiTY92LB9gIjyrMoAoGCCqGSM49 +AwEHoUQDQgAEDFlblkOrW9ydKVhtM+9AY3c9saBE7SG3lFx38nBavkADDaI9jh3/ +kvG/Jt9vpm22qwoklTCGDfzCkXkIKaWlBw== +-----END EC PRIVATE KEY----- diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_n_pw b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_n_pw new file mode 100644 index 000000000..36b7fa787 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ecdsa_n_pw @@ -0,0 +1,9 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABC4UwEov5 +z0RrCm7AMCxbuiAAAAEAAAAAEAAABoAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlz +dHAyNTYAAABBBAxZW5ZDq1vcnSlYbTPvQGN3PbGgRO0ht5Rcd/JwWr5AAw2iPY4d/5Lxvy +bfb6ZttqsKJJUwhg38wpF5CCmlpQcAAACgbCnAklQTHrf5qiHiMxKYwQJ7k/X9mp4fXD4v +xUbgNZiXSxN26mn8mC2rH+WA6Lk3CexR/hrtLI2ndpBsYu1h6HhVkOwwm3Kd/PMKArCupW +l6sYEabrT0EghXR/3aDEZvj79hgKSdu3RpayLvMdbCR8k1cg0/mDmR9hicWfeJ61n/IH05 +tUR268+0BVRW9kDhh/cuv8tVY4L09jCCQ6CpsA== +-----END OPENSSH PRIVATE KEY----- diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1 b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1 new file mode 100644 index 000000000..6b0ae01cf --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1 @@ -0,0 +1,7 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACBThupGO0X+FLQhbz8CoKPwc7V3JNsQuGtlsgN+F7SMGQAAAJjnj4Ao54+A +KAAAAAtzc2gtZWQyNTUxOQAAACBThupGO0X+FLQhbz8CoKPwc7V3JNsQuGtlsgN+F7SMGQ +AAAED3KgoDbjR54V7bdNpfKlQY5m20UK1QaHytkCR+6rZEDFOG6kY7Rf4UtCFvPwKgo/Bz +tXck2xC4a2WyA34XtIwZAAAAE0VEMjU1MTkgdGVzdCBrZXkgIzEBAg== +-----END OPENSSH PRIVATE KEY----- diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1-cert.fp b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1-cert.fp new file mode 100644 index 000000000..a9674e2b0 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1-cert.fp @@ -0,0 +1 @@ +SHA256:L3k/oJubblSY0lB9Ulsl7emDMnRPKm/8udf2ccwk560 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1-cert.pub b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1-cert.pub new file mode 100644 index 000000000..649b4e804 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1-cert.pub @@ -0,0 +1 @@ +ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIIxzuxl4z3uwAIslne8Huft+1n1IhHAlNbWZkQyyECCGAAAAIFOG6kY7Rf4UtCFvPwKgo/BztXck2xC4a2WyA34XtIwZAAAAAAAAAAgAAAACAAAABmp1bGl1cwAAABIAAAAFaG9zdDEAAAAFaG9zdDIAAAAANowB8AAAAABNHmBwAAAAAAAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACBThupGO0X+FLQhbz8CoKPwc7V3JNsQuGtlsgN+F7SMGQAAAFMAAAALc3NoLWVkMjU1MTkAAABABGTn+Bmz86Ajk+iqKCSdP5NClsYzn4alJd0V5bizhP0Kumc/HbqQfSt684J1WdSzih+EjvnTgBhK9jTBKb90AQ== ED25519 test key #1 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1.fp b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1.fp new file mode 100644 index 000000000..a9674e2b0 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1.fp @@ -0,0 +1 @@ +SHA256:L3k/oJubblSY0lB9Ulsl7emDMnRPKm/8udf2ccwk560 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1.fp.bb b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1.fp.bb new file mode 100644 index 000000000..309f2dafc --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1.fp.bb @@ -0,0 +1 @@ +xubop-rekyd-bakal-nubuf-pahaf-gicuh-logeb-gocif-petod-galip-fuxux diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1.pub b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1.pub new file mode 100644 index 000000000..e533059ea --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFOG6kY7Rf4UtCFvPwKgo/BztXck2xC4a2WyA34XtIwZ ED25519 test key #1 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1_pw b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1_pw new file mode 100644 index 000000000..c3b7ae7f8 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_1_pw @@ -0,0 +1,8 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABCus+kaow +AUjHphacvRp98dAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIFOG6kY7Rf4UtCFv +PwKgo/BztXck2xC4a2WyA34XtIwZAAAAoJaqqgiYQuElraJAmYOm7Tb4nJ3eI4oj9mQ52M +/Yd+ION2Ur1v8BDewpDX+LHEYgKHo3Mlmcn2UyF+QJ+7xUCW7QCtk/4szrJzw74DlEl6mH +T8PT/f/av7PpECBD/YD3NoDlB9OWm/Q4sHcxfBEKfTGD7s2Onn71HgrdEOPqd4Sj/IQigR +drfjtXEMlD32k9n3dd2eS9x7AHWYaGFEMkOcY= +-----END OPENSSH PRIVATE KEY----- diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_2 b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_2 new file mode 100644 index 000000000..e4aed6398 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_2 @@ -0,0 +1,7 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACDPVKyLnm3eZE0lm0IfM3Uy9AsdGSBtozcoCt21blYBCwAAAJix1mBGsdZg +RgAAAAtzc2gtZWQyNTUxOQAAACDPVKyLnm3eZE0lm0IfM3Uy9AsdGSBtozcoCt21blYBCw +AAAECZEQHXs18o3DKjhUYaTyt+bUbhqfMeqmsKjYyFvzGVgs9UrIuebd5kTSWbQh8zdTL0 +Cx0ZIG2jNygK3bVuVgELAAAAE0VEMjU1MTkgdGVzdCBrZXkgIzEBAg== +-----END OPENSSH PRIVATE KEY----- diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_2.fp b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_2.fp new file mode 100644 index 000000000..049662672 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_2.fp @@ -0,0 +1 @@ +SHA256:vMbaARqVciRgXyZPNHDo+P5p5WK5yWG1Oo6VC35Bomw diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_2.fp.bb b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_2.fp.bb new file mode 100644 index 000000000..abba78901 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_2.fp.bb @@ -0,0 +1 @@ +xuces-bapyb-vikob-zesyv-budod-nupip-kebon-tacyc-fofed-lezic-soxax diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_2.pub b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_2.pub new file mode 100644 index 000000000..af34236e7 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/ed25519_2.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM9UrIuebd5kTSWbQh8zdTL0Cx0ZIG2jNygK3bVuVgEL ED25519 test key #1 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/pw b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/pw new file mode 100644 index 000000000..8a1dff98a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/pw @@ -0,0 +1 @@ +mekmitasdigoat diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1 b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1 new file mode 100644 index 0000000000000000000000000000000000000000..161cc04dc700b60ac13cc992f44aeed3b4c2fc73 GIT binary patch literal 533 zcmV+w0_y!!Q%E3CQb|@pR7D_5MOh$5NlZl`Mo&^rK~x|yE-?xK000000000400aQe zjHh~4Zn}tnnucr$N@N0fQ&gxN5QR-NF@gFCH4-DHUzw3#gfr0^oIz)OFnj~UqnKs5 zK5=r=!Ps~+JeUMH*5pPZ2A~F9*IfRm%6}nKi}Lh8D)gMJ?oqNXJKV+Sds)nBAAD&- zr+)D}{re;^2Y0t8G>r?VkPDz|h-WDP5di=J0000GQd2=OAarGObRcVGc_1S(>8a_d z1O6^MLtR;P0Aha?N>efe+@Qqg`T^?BGuRaWqtzg6b(8NfWWp*u01+g>rq2*DV*tRg zgmU;RS>INdHtDFQK5PVMH6CTnl2y-4bv`f*v5~xEmGtMvCWrLmgswuUNyA~iQc#5k zNWgBD{}CKtZ_(LtabRalX6jRb)j*HYQ~?40DY5PO{*~ZB4Np66dUgnEJ+eGhBDMLo z-#aVXxB@qou{1Yvn1urGMb-`0gtLdf+KFEA4ruHC@+H8QXwVNL0sz@^?a0D(O~cgn zwNUbkJU4{y5@DYT)Kqz*9hj2XHJb2x$ZfJXV(?|F^R z0)YYm^D7G^UF0}cT*X;k^H&3-n|P%=XkO2sHniH00000<=N?l literal 0 HcmV?d00001 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1.fp b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1.fp new file mode 100644 index 000000000..21b3d1a9a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1.fp @@ -0,0 +1 @@ +SHA256:/kk7K9S9kwYFiFilnZYFwCsQJweI/SGQVR2nIa8VBhE diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1.fp.bb b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1.fp.bb new file mode 100644 index 000000000..62991b3e0 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1.fp.bb @@ -0,0 +1 @@ +xilil-nabyf-gynih-duheb-gokyp-bofet-nekac-bosod-lozin-kuvyh-poxix diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1.param.n b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1.param.n new file mode 100644 index 000000000..9a2549bbb --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1.param.n @@ -0,0 +1 @@ +00ce8ca77a556eba887f9a866c084a6402785354a81c10854d343181fa09351223a65f99915f8433d11a9c41677d307c03c3a39865b83e7172d2c1d878333c980438d6e4462106a0065cd75cfea7ca7f21538bf2f43f2af49cacee51b22e3bdcc5e87b59cc691f7c6942a77ef13bfdfb24300777b727348d0ba7900ba06b886729 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1.pub b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1.pub new file mode 100644 index 000000000..f665b0d64 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1.pub @@ -0,0 +1 @@ +1024 65537 145043942670517902781741650890610683756045780348507433188994725700923246927874581962206512480287863636935077725837494808988986557337885675565086448774391442851909709751605441036910145362277967349042489937363543710406342212883803780768870873303921572812138116796733586484633244057911618360651775855949808953129 RSA1 test key #1 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1_pw b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_1_pw new file mode 100644 index 0000000000000000000000000000000000000000..e73c6794ade5991924286b3a88e6727cafa4ed36 GIT binary patch literal 533 zcmV+w0_y!!Q%E3CQb|@pR7D_5MOh$5NlZl`Mo&^rK~x|yE-?xK0{{R30000400aQe zjHh~4Zn}tnnucr$N@N0fQ&gxN5QR-NF@gFCH4-DHUzw3#gfr0^oIz)OFnj~UqnKs5 zK5=r=!Ps~+JeUMH*5pPZ2A~F9*IfRm%6}nKi}Lh8D)gMJ?oqNXJKV+Sds)nBAAD&- zr+)D}{re;^2Y0t8G>r?VkPDz|h-WDP5di=J0000GQd2=OAarGObRcVGc_1S(9dX_c zt!-(~5GKp~q7pg{JNHA=o?qT_*ho&?f$UIK9G`Te9*Yv2(xIBWdOVF}EJAbVq-=zq z3dbMWv!)`=%Z-f&>w&YV&d{TvE2ql$;)&1I-9eO?JG|DYj)oaR@#sA9o*X4EqUbQ= z|Au{Sc6RfPBmERdh8WJjN-v0u*nf7hPxO=V{h2B7#DMi>kBt5M1Yvz~2wnK!{X67+ z^UyAq&zuTy-Sycy;sY=0Sf)NyOOBB^4mgY1eBz#XBWW76jM=AM(_iVdb}qg9dBr#< zEur5a{CGeW+_wAOz@vwnlhNe*A~nmmJ#z6|#&BzrB3RwVoN7*RgL`f4WQ@pQRaZDX z^8l2Ixvm->)Jg;>$b!(EdFFixji6xePF3)rK(~MI6`r}qsWuAsfvcHS%_sN!IlB@ z^3zJthZR{-st-L-3pUW$1iQ@M@mjMSquoHg^%-Dgsed_s^>)htwg$d}GWOtMO6m@m zo0WtqW^?+x9lf725=mS_h(e;P9~WrdLQl5+&hD#`Cd$qHgHH+#3A%HwgJ98vx`n$H zWmR0pr8eu02HzSUgb@e8A+9K**t14oor_rSKt-;h#I1je_BmHgYZNN>drq?e5di=J z0000GQd2=OAarGObRcVGc_1S)>7nVN2mp&47ez;2CnBg*EvHadE^)5M3K3hoEiVBK zD%x5Yj5y|Xiwf6HMmEJ4N64vZTtO-A;$qHW;uuGEO)LaP{MKQ+19k?j3*iqdOxXZ> z8DIUkj81uR^~d2a_vitlJ713-Yhba!zN-H+k`#P=*$55g`oo8n%C8nOS$Ribxo?g0 z1RN^250~War6lDH?r|1<9ZZn&R9BxLGxw+M)LEL&m-!5Fu){$PM5Jfn{vV~!EZw^= z=}8RQ^%BRVZMx40wep8@3tq4HUWnh5Ju4N`AzDHATVcDkb`W6tH~yHs*~^h98#7Ii zHr?HRMZHESfUG&XfZ*~_AX`T^W?=*Xx2vEp1QaXFTmpFLT*E*SAcA;*`_4;#VIX%s z2q8kJy|jou6OfeejakO;@ept*7;`F4<&zWE@O91qC~*ANgci3}I-&RYt-s~DBG*lA zE)~Uvj_`axmx{1qTM=AMI*yx8iCwQxyBCF49xk$=S>k5~O3P18)Is+nLarid1OU;- z9zDcq2+H&;NG$Z*Zl8ZR+6oPe@bEF7NNa;=J1!8;jm-vy)Xps;CCP@Qv8szlNFZ-o z`dc{4+6T^HvT^3f&a)O!dQk8tJyO;V21C;+vPoWT1k2N1^2gpv#lD?TU5 zN{DcJm2WIZZJAu}H`vnnK>;LkrGyr_9%!9_uD@Ho^#$T+_ub8^JwEAweiMv~00000 Dc>K$3 literal 0 HcmV?d00001 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_2.fp b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_2.fp new file mode 100644 index 000000000..00516d521 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_2.fp @@ -0,0 +1 @@ +SHA256:JaOeRCnLl/TLe7vn1+aQ4ONyKZCUhK5x3k4VHilmbpE diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_2.fp.bb b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_2.fp.bb new file mode 100644 index 000000000..b4989a588 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_2.fp.bb @@ -0,0 +1 @@ +xipag-zohut-zepuk-pisyv-kamog-pupus-netud-tudis-melup-cynov-gaxox diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_2.param.n b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_2.param.n new file mode 100644 index 000000000..25d438d06 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_2.param.n @@ -0,0 +1 @@ +00cab091b57a154740c1bb7020f46a21a19dc40f647db2aab1babd30cabe241f0437391e68376ba35e48c624b8eaf6b59424d4c1a848c9fd1ef5cdc7c1b7f5e5df23b7ad513b79021286d38c52fdfae35656659e8649b2bf8bedf7c99664e45534007bd1c5dc3de1dafdf2d34ad087155951aa0f3d500b36d0d804bbccdef15ab31ca3dd40bdf5196065a97f397ef576caffb606be8232f6e0614aea0e979b9584296673fabb1dbd9f3212495c428842a2ab1f1768dd424fb6fdceeeab9126cacdfc834f0a0d09ba73ad8360d183ba85bb1565555cc6a536eb8d06df1a1e841107c021ae28a2d8b3465f9d8b58ef4045aea1c4ad7f8bf639574d6b142af67b4eb3 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_2.pub b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_2.pub new file mode 100644 index 000000000..acab6dda6 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa1_2.pub @@ -0,0 +1 @@ +2048 65537 25587207108642486834576012232250034427766229965612147538722032399009467293691448851087324679403117563681753304072089087252850866332601294130674473984011813227791089686736237645788471744456489819306046398653719249100878753563464696688916667605969658659855996383142110932332560049231682024775766802333675397528993897914717996946881193454997890776063024953924432026083898531677702536941151535135950834711001926404724453460085864892836473957600610133803037286539329764689125111700732309717375455919436557475211197800228646235077584780367991159670572954337165006813357814232200750568307753718414790655085790471723847208627 RSA1 test key #2 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1 b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1 new file mode 100644 index 000000000..5de3f8422 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1 @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDLV5lUTt7FrADseB/CGhEZzpoojjEW5y8+ePvLppmK3MmMI18u +d6vxzpK3bwZLYkVSyfJYI0HmIuGhdu7yMrW6wb84gbq8C31Xoe9EORcIUuGSvDKd +NSM1SjlhDquRblDFB8kToqXyx1lqrXecXylxIUOL0jE+u0rU1967pDJx+wIDAQAB +AoGAXyj5mpjmbD+YlxGIWz/zrM4hGsWgd4VteKEJxT6MMI4uzCRpkMd0ck8oHiwZ +GAI/SwUzIsgtONQuH3AXVsUgghW4Ynn+8ksEv0IZ918WDMDwqvqkyrVzsOsZzqYj +Pf8DUDKCpwFjnlknJ04yvWBZvVhWtY4OiZ8GV0Ttsu3k+GECQQD1YHfvBb5FdJBv +Uhde2Il+jaFia8mwVVNNaiD2ECxXx6CzGz54ZLEB9NPVfDUZK8lJ4UJDqelWNh3i +PF3RefWDAkEA1CVBzAFL4mNwpleVPzrfy69xP3gWOa26MxM/GE6zx9jC7HgQ3KPa +WKdG/FuHs085aTRDaDLmGcZ8IvMuu7NgKQJAcIOKmxR0Gd8IN7NZugjqixggb0Pj +mLKXXwESGiJyYtHL0zTj4Uqyi6Ya2GJ66o7UXscmnmYz828fJtTtZBdbRwJBALfi +C2QvA32Zv/0PEXibKXy996WSC4G3ShwXZKtHHKHvCxY5BDSbehk59VesZrVPyG2e +NYdOBxD0cIlCzJE56/ECQAndVkxvO8hwyEFGGwF3faHIAe/OxVb+MjaU25//Pe1/ +h/e6tlCk4w9CODpyV685gV394eYwMcGDcIkipTNUDZs= +-----END RSA PRIVATE KEY----- diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1-cert.fp b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1-cert.fp new file mode 100644 index 000000000..79f380a25 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1-cert.fp @@ -0,0 +1 @@ +SHA256:l6itGumSMcRBBAFteCgmjQBIXqLK/jFGUH3viHX1RmE diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1-cert.pub b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1-cert.pub new file mode 100644 index 000000000..3bacf3c8f --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1-cert.pub @@ -0,0 +1 @@ +ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAg98LhS2EHxLOWCLopZPwHdg/RJXusnkOqQXSc9R7aITkAAAADAQABAAAAgQDLV5lUTt7FrADseB/CGhEZzpoojjEW5y8+ePvLppmK3MmMI18ud6vxzpK3bwZLYkVSyfJYI0HmIuGhdu7yMrW6wb84gbq8C31Xoe9EORcIUuGSvDKdNSM1SjlhDquRblDFB8kToqXyx1lqrXecXylxIUOL0jE+u0rU1967pDJx+wAAAAAAAAAFAAAAAgAAAAZqdWxpdXMAAAASAAAABWhvc3QxAAAABWhvc3QyAAAAADaMAfAAAAAATR5gcAAAAAAAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAgU4bqRjtF/hS0IW8/AqCj8HO1dyTbELhrZbIDfhe0jBkAAABTAAAAC3NzaC1lZDI1NTE5AAAAQI3QGlUCzC07KorupxpDkkGy6tniaZ8EvBflzvv+itXWNchGvfUeHmVT6aX0sRqehdz/lR+GmXRoZBhofwh0qAM= RSA test key #1 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.fp b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.fp new file mode 100644 index 000000000..79f380a25 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.fp @@ -0,0 +1 @@ +SHA256:l6itGumSMcRBBAFteCgmjQBIXqLK/jFGUH3viHX1RmE diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.fp.bb b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.fp.bb new file mode 100644 index 000000000..45bacd519 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.fp.bb @@ -0,0 +1 @@ +xosis-fodod-votot-dibum-ryvac-rediz-naruf-votun-kevis-halis-gexux diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.param.n b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.param.n new file mode 100644 index 000000000..493371213 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.param.n @@ -0,0 +1 @@ +00cb5799544edec5ac00ec781fc21a1119ce9a288e3116e72f3e78fbcba6998adcc98c235f2e77abf1ce92b76f064b624552c9f2582341e622e1a176eef232b5bac1bf3881babc0b7d57a1ef4439170852e192bc329d3523354a39610eab916e50c507c913a2a5f2c7596aad779c5f297121438bd2313ebb4ad4d7debba43271fb diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.param.p b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.param.p new file mode 100644 index 000000000..4783d215e --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.param.p @@ -0,0 +1 @@ +00f56077ef05be4574906f52175ed8897e8da1626bc9b055534d6a20f6102c57c7a0b31b3e7864b101f4d3d57c35192bc949e14243a9e956361de23c5dd179f583 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.param.q b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.param.q new file mode 100644 index 000000000..00fc8a2df --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.param.q @@ -0,0 +1 @@ +00d42541cc014be26370a657953f3adfcbaf713f781639adba33133f184eb3c7d8c2ec7810dca3da58a746fc5b87b34f396934436832e619c67c22f32ebbb36029 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.pub b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.pub new file mode 100644 index 000000000..23ef872e0 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDLV5lUTt7FrADseB/CGhEZzpoojjEW5y8+ePvLppmK3MmMI18ud6vxzpK3bwZLYkVSyfJYI0HmIuGhdu7yMrW6wb84gbq8C31Xoe9EORcIUuGSvDKdNSM1SjlhDquRblDFB8kToqXyx1lqrXecXylxIUOL0jE+u0rU1967pDJx+w== RSA test key #1 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1_pw b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1_pw new file mode 100644 index 000000000..b4c067458 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_1_pw @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,0C3F819F6EEA66A471BAEEDDA8171606 + +AhQNxgw7Z2un3dpm6KPHF1u5qVvOczm0yiTyPK4U11B3TTRhXOHdzPLAcKMX71Xq +fmLm2/JIZATUbLTaysLKIQlmAgtpmXoKLv9b90R3AXLophgToZzOLpvlQTCt+y9G +0E3QQZG/LFy9BLNyw6uD5cy0RHT3FQb5VQDwfBvR/I+K3qWBFLlb7Rw9bCujYczu +D3bimcDj/k6YkrWVsEa81Ch5RF2RClOYufti6bsvc4xIsB0Kd++vokER+kXFuQqf +Tl0Jz+SG0kr9QtjVvkhBtSxzJ6/olAosoUySQ5hqsB8iECufBgp1KelXqsHFJQXy +gCvVmGiivFUinX0rKOuWCHTplsSKQ9BnPSwDAAs8A7ZLcTXcLs/hMQ5r6fmOYfNN +YthhjZyE2ciJO0lydGJUJMb5aJUak0rl+uINRlYCHTRLVwmCOmpfqz9SfcJb1ieU +4Us8NR+pXJar4U0+C2wVlNJkAdpL6GvYxN6vp7vLa+BiFwIZOQozswacIZk/ScXm +QL9rmWug51RCmDeenX46WTEZeB0o0+xi60sDEDhhe4+iNYcJu5L0BJ5lqRFe3I5n +HRRv1mBEjbF2fDcg/ChYfOXsc4gDivH2nObabeASuMFZyadmXfA8tnXRZf+7Wuy/ +LZGYbM2xLeEyV3ss16WBHuIqexDt04OEZvs0jN90zj6Yv7qKCB975bdOcuKkN2Nn +n9lA11R2pgsCs6COp9rYiWXkXZeDf3sW6kdcEV+/SzkVsv4JlHcsIzgk4WGVF/E/ +ZkU4J9AvSdJPzEQDM+yszp0eeUow4+SAgpuNTqZiUO/2UUVbsr3qvlYMoCixhFAN +-----END RSA PRIVATE KEY----- diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2 b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2 new file mode 100644 index 000000000..2441d52bf --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2 @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA9NEUXp78SAkmL4+eAj4mBzPOjk+ccCPVzkTR+mZJdyTwkJAB +HUN4cn4a2kTmh7Er+N8CXCsiqxIOV1GfH2fwaCiBlOEXeQJi/cMjxr9kVWO4FhC6 +l1UqbvPUdrUCUZjFTA9/Ah9MKgk7qGYq5SjE3p+sn4GLhRKbqmq9LjiHgMmkBuv/ +a1Slit+rXHzO2F8fH5hkjeHivyYVgw45aNvGCe2RRfbpoeW2mRtgIv7y9wSewt6a +mhEDXSo/F6mkqA7xVinzro5NettEXLo91tA9Hb6f6x/Mc/GJDNXTKhpWCGeJ6xeW +nAefDZORWAY7Y9YbuAxhEJVi9QL5NWoFOA0C6wIDAQABAoIBAQDtRGVVfwhKWHOl +zK76xXjdqhwaWJXpKRHiI1jOMawpyKdNtAMgdW+apxUnTXePMurG/HuxEC09VvaH +MhfhvD6G9BsCS1UQdnuyLRnTWVLIXyjeWcA9QtEpTy8vDSb+Je2xVaNmTybl5qTn +BH22Mtj6Wg5XWJn7kplDhMdssGTDLsSCMw/rcxe9iT2qOKyltQal23RHzR7SijGp +QTtBp2SDGhvMZcyGuyMqJ084W8sdJpbyVzdDim2iaZdHlk7uvW2n0HcJ56I6yhIq +2U8wfgEEwydGVGHgmQNJ/n+SiT/hv6g5ebhDS46X9F9m5CHDwhdr0DrhPBVSsdhl +1HeJ0+FhAoGBAPuC3uNHToiJis688juKlwc3SQ6ger5ffAg3yaNhEcpHkvOtdZlF +/CfX94xazMov/YqFwkvpSSdKsX+PeXuaqnb1hPKNYX5t45U9RjB/ox7BIQj/2rPx +Bfs99UFW9HKP4HsVmLu1xeJg1Pc9iylTK/xrnwfYiZ+H7IGVccizjnqHAoGBAPkv +n1flAdxBzJH/O0rXoig2EtZsDRMPY51MGDdqVOW14ZOfTVlmu0OSnkSKQm2twfro +TPDVb2TY3wTRutz8H9yOFW1c1Nz4YOyTb8FmJhE2FWAQ9t8QpwUlhn15if72dS/Y +22+vP+AYu7wfqGL7QVVEXho5hGjXi053iEvfXBl9AoGAeZISpo1LGphRLgkKlVky +E1zXxWgwrGB/FYHRx1UeQkZCc+K+Wy4G6kNr9r3VC04TIafx+Lt0jrd+AIibUfG6 +v/GBJ7TLEU+QmAycJskrUaxMiYsSbbPtDjoumDytv8pn2VbhEqqUUg44IqHu6DS5 +qDNlFWfHbgNHgIN6EmcoUXUCgYEAi2G57X4pRjx/4wIy9jAbggaNDuctgQXQoIGZ +4hVWG49a+CnZKDKweKGgaZI0igjxQhmCQAwC3RP520Y9EbLtV38aOSv93QQJowrt +Le6nSGVKG4whqrAz3EsbKUA8kiLldbgFNjl+ryjmidnjZEpKRxmQ0XZuu/4k6+Us +ldQAPjkCgYBwjSm5eDUtK2eEPaBtbJykV05CTv5rn6CKC9L7ZBTkCcdU1hxeqe99 +wb22decnNawGRP1a5cGwqKJPOfkgybJVkdr6aqQW8ClzdFSaenjzs+nVW+T9JTXf +9lFpIZg5kN/geld3B9B4C99riTM0jg9hbe2RQvpLRTrZbnWMA1XoRw== +-----END RSA PRIVATE KEY----- diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.fp b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.fp new file mode 100644 index 000000000..4659639db --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.fp @@ -0,0 +1 @@ +SHA256:NoQh0XBUuYUSWqnzOzOBnfpgJTRWLMj7BlWAb8IbjeE diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.fp.bb b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.fp.bb new file mode 100644 index 000000000..e9d1e4a57 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.fp.bb @@ -0,0 +1 @@ +xogit-gupof-mydon-hocep-zuval-feson-rarif-cefar-tobar-ryvap-kuxex diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.param.n b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.param.n new file mode 100644 index 000000000..a669dbf0b --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.param.n @@ -0,0 +1 @@ +00f4d1145e9efc4809262f8f9e023e260733ce8e4f9c7023d5ce44d1fa66497724f09090011d4378727e1ada44e687b12bf8df025c2b22ab120e57519f1f67f068288194e117790262fdc323c6bf645563b81610ba97552a6ef3d476b5025198c54c0f7f021f4c2a093ba8662ae528c4de9fac9f818b85129baa6abd2e388780c9a406ebff6b54a58adfab5c7cced85f1f1f98648de1e2bf2615830e3968dbc609ed9145f6e9a1e5b6991b6022fef2f7049ec2de9a9a11035d2a3f17a9a4a80ef15629f3ae8e4d7adb445cba3dd6d03d1dbe9feb1fcc73f1890cd5d32a1a56086789eb17969c079f0d939158063b63d61bb80c61109562f502f9356a05380d02eb diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.param.p b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.param.p new file mode 100644 index 000000000..be7c1c36c --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.param.p @@ -0,0 +1 @@ +00fb82dee3474e88898acebcf23b8a970737490ea07abe5f7c0837c9a36111ca4792f3ad759945fc27d7f78c5accca2ffd8a85c24be949274ab17f8f797b9aaa76f584f28d617e6de3953d46307fa31ec12108ffdab3f105fb3df54156f4728fe07b1598bbb5c5e260d4f73d8b29532bfc6b9f07d8899f87ec819571c8b38e7a87 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.param.q b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.param.q new file mode 100644 index 000000000..6f2c542df --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.param.q @@ -0,0 +1 @@ +00f92f9f57e501dc41cc91ff3b4ad7a2283612d66c0d130f639d4c18376a54e5b5e1939f4d5966bb43929e448a426dadc1fae84cf0d56f64d8df04d1badcfc1fdc8e156d5cd4dcf860ec936fc166261136156010f6df10a70525867d7989fef6752fd8db6faf3fe018bbbc1fa862fb4155445e1a398468d78b4e77884bdf5c197d diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.pub b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.pub new file mode 100644 index 000000000..3322fbc9b --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_2.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD00RRenvxICSYvj54CPiYHM86OT5xwI9XORNH6Zkl3JPCQkAEdQ3hyfhraROaHsSv43wJcKyKrEg5XUZ8fZ/BoKIGU4Rd5AmL9wyPGv2RVY7gWELqXVSpu89R2tQJRmMVMD38CH0wqCTuoZirlKMTen6yfgYuFEpuqar0uOIeAyaQG6/9rVKWK36tcfM7YXx8fmGSN4eK/JhWDDjlo28YJ7ZFF9umh5baZG2Ai/vL3BJ7C3pqaEQNdKj8XqaSoDvFWKfOujk1620Rcuj3W0D0dvp/rH8xz8YkM1dMqGlYIZ4nrF5acB58Nk5FYBjtj1hu4DGEQlWL1Avk1agU4DQLr RSA test key #2 diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_n b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_n new file mode 100644 index 000000000..5de3f8422 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_n @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDLV5lUTt7FrADseB/CGhEZzpoojjEW5y8+ePvLppmK3MmMI18u +d6vxzpK3bwZLYkVSyfJYI0HmIuGhdu7yMrW6wb84gbq8C31Xoe9EORcIUuGSvDKd +NSM1SjlhDquRblDFB8kToqXyx1lqrXecXylxIUOL0jE+u0rU1967pDJx+wIDAQAB +AoGAXyj5mpjmbD+YlxGIWz/zrM4hGsWgd4VteKEJxT6MMI4uzCRpkMd0ck8oHiwZ +GAI/SwUzIsgtONQuH3AXVsUgghW4Ynn+8ksEv0IZ918WDMDwqvqkyrVzsOsZzqYj +Pf8DUDKCpwFjnlknJ04yvWBZvVhWtY4OiZ8GV0Ttsu3k+GECQQD1YHfvBb5FdJBv +Uhde2Il+jaFia8mwVVNNaiD2ECxXx6CzGz54ZLEB9NPVfDUZK8lJ4UJDqelWNh3i +PF3RefWDAkEA1CVBzAFL4mNwpleVPzrfy69xP3gWOa26MxM/GE6zx9jC7HgQ3KPa +WKdG/FuHs085aTRDaDLmGcZ8IvMuu7NgKQJAcIOKmxR0Gd8IN7NZugjqixggb0Pj +mLKXXwESGiJyYtHL0zTj4Uqyi6Ya2GJ66o7UXscmnmYz828fJtTtZBdbRwJBALfi +C2QvA32Zv/0PEXibKXy996WSC4G3ShwXZKtHHKHvCxY5BDSbehk59VesZrVPyG2e +NYdOBxD0cIlCzJE56/ECQAndVkxvO8hwyEFGGwF3faHIAe/OxVb+MjaU25//Pe1/ +h/e6tlCk4w9CODpyV685gV394eYwMcGDcIkipTNUDZs= +-----END RSA PRIVATE KEY----- diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_n_pw b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_n_pw new file mode 100644 index 000000000..dc18373bc --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/testdata/rsa_n_pw @@ -0,0 +1,17 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABAFw/Wg/V +I5SAXWj/HJr9qeAAAAEAAAAAEAAACXAAAAB3NzaC1yc2EAAAADAQABAAAAgQDLV5lUTt7F +rADseB/CGhEZzpoojjEW5y8+ePvLppmK3MmMI18ud6vxzpK3bwZLYkVSyfJYI0HmIuGhdu +7yMrW6wb84gbq8C31Xoe9EORcIUuGSvDKdNSM1SjlhDquRblDFB8kToqXyx1lqrXecXylx +IUOL0jE+u0rU1967pDJx+wAAAgD1iSGiMlMJt2VH4kx5yr0wCJS+4UOmX0bxKO7UH5Jcul +K5eaSe5ZoKE7hTYBaz0K5dRF/0fqLsvVZlE4quDjFLN6Hyavgn2W/QM7SUqBHgRMal9pgH +LnxX6mFNWJ+4yb7f3bcbVIdgmMm3sT9Xjwaf5xgzNlR2mkUWtFwjyQh6FxUo5apNzqNBwO +l2Q4xfmyZTp1s++pStQ/su6obXpxnE2Nx5G/D84ZL5iWl+njUy/MvJTazHRbiTSyihU+UA +mUr5ZNuP3WUYY+h3KVlHpYHJYB7l3AMTKuPMFLhY9V7BJ+DuKPaqBgX4hvRzY0eVQiFr61 +ovjWjvfu1ulx550JqdYCgH2PpP0E89OQne35Cxs9QPThfe8DKojC9YquYh9zmVTvr7kNiE +Soluk/7oKpQIDaC+/SRk7AJ2e3Cbt1lXyGNn37PuqaaC/apaF/DOD6Yig9aClS7jOUrT96 +56trFAYfHEIKbRCUSMCiM1+x6HOLYf5ROrGE9KxT3kUD9XMsMpTva+cPpHUpbGpXcYE10N +MyYDz+V5M2/ZoIdEhscJNQ3UnhaZpeEaqcOyNyo90n3Dnaw/WpMDD/kNMGfm8daTaYInnQ +QnwA2gwlYfpTAqxE71oXgOuGmtA0yqJB4778Xq26Pb+B7/mZZZe6n0FVmiNC+ZG37ZGOw/ +iGL9e2Sxzw== +-----END OPENSSH PRIVATE KEY----- diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/tests.c b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/tests.c new file mode 100644 index 000000000..13f265cdb --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/sshkey/tests.c @@ -0,0 +1,27 @@ +/* $OpenBSD: tests.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */ +/* + * Regress test for sshbuf.h buffer API + * + * Placed in the public domain + */ + +#include "includes.h" + +#include + +#include "../test_helper/test_helper.h" + +void sshkey_tests(void); +void sshkey_file_tests(void); +void sshkey_fuzz_tests(void); + +void +tests(void) +{ + OpenSSL_add_all_algorithms(); + ERR_load_CRYPTO_strings(); + + sshkey_tests(); + sshkey_file_tests(); + sshkey_fuzz_tests(); +} diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/test_helper/Makefile b/crypto/external/bsd/openssh/dist/regress/unittests/test_helper/Makefile new file mode 100644 index 000000000..5b3894cbf --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/test_helper/Makefile @@ -0,0 +1,16 @@ +# $OpenBSD: Makefile,v 1.2 2015/01/20 22:58:57 djm Exp $ + +LIB= test_helper +SRCS= test_helper.c fuzz.c + +DEBUGLIBS= no +NOPROFILE= yes +NOPIC= yes + +# Hack to allow building with SUBDIR in ../../Makefile +regress: all + +install: + @echo -n + +.include diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/test_helper/fuzz.c b/crypto/external/bsd/openssh/dist/regress/unittests/test_helper/fuzz.c new file mode 100644 index 000000000..99f1d036c --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/test_helper/fuzz.c @@ -0,0 +1,438 @@ +/* $OpenBSD: fuzz.c,v 1.8 2015/03/03 20:42:49 djm Exp $ */ +/* + * Copyright (c) 2011 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* Utility functions/framework for fuzz tests */ + +#include "includes.h" + +#include +#include + +#include +#include +#include +#ifdef HAVE_STDINT_H +# include +#endif +#include +#include +#include +#include + +#include "test_helper.h" +#include "atomicio.h" + +/* #define FUZZ_DEBUG */ + +#ifdef FUZZ_DEBUG +# define FUZZ_DBG(x) do { \ + printf("%s:%d %s: ", __FILE__, __LINE__, __func__); \ + printf x; \ + printf("\n"); \ + fflush(stdout); \ + } while (0) +#else +# define FUZZ_DBG(x) +#endif + +/* For brevity later */ +typedef unsigned long long fuzz_ullong; + +/* For base-64 fuzzing */ +static const char fuzz_b64chars[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +struct fuzz { + /* Fuzz method currently in use */ + int strategy; + + /* Fuzz methods remaining */ + int strategies; + + /* Original seed data blob */ + void *seed; + size_t slen; + + /* Current working copy of seed with fuzz mutations applied */ + u_char *fuzzed; + + /* Used by fuzz methods */ + size_t o1, o2; +}; + +static const char * +fuzz_ntop(u_int n) +{ + switch (n) { + case 0: + return "NONE"; + case FUZZ_1_BIT_FLIP: + return "FUZZ_1_BIT_FLIP"; + case FUZZ_2_BIT_FLIP: + return "FUZZ_2_BIT_FLIP"; + case FUZZ_1_BYTE_FLIP: + return "FUZZ_1_BYTE_FLIP"; + case FUZZ_2_BYTE_FLIP: + return "FUZZ_2_BYTE_FLIP"; + case FUZZ_TRUNCATE_START: + return "FUZZ_TRUNCATE_START"; + case FUZZ_TRUNCATE_END: + return "FUZZ_TRUNCATE_END"; + case FUZZ_BASE64: + return "FUZZ_BASE64"; + default: + abort(); + } +} + +static int +fuzz_fmt(struct fuzz *fuzz, char *s, size_t n) +{ + if (fuzz == NULL) + return -1; + + switch (fuzz->strategy) { + case FUZZ_1_BIT_FLIP: + snprintf(s, n, "%s case %zu of %zu (bit: %zu)\n", + fuzz_ntop(fuzz->strategy), + fuzz->o1, fuzz->slen * 8, fuzz->o1); + return 0; + case FUZZ_2_BIT_FLIP: + snprintf(s, n, "%s case %llu of %llu (bits: %zu, %zu)\n", + fuzz_ntop(fuzz->strategy), + (((fuzz_ullong)fuzz->o2) * fuzz->slen * 8) + fuzz->o1, + ((fuzz_ullong)fuzz->slen * 8) * fuzz->slen * 8, + fuzz->o1, fuzz->o2); + return 0; + case FUZZ_1_BYTE_FLIP: + snprintf(s, n, "%s case %zu of %zu (byte: %zu)\n", + fuzz_ntop(fuzz->strategy), + fuzz->o1, fuzz->slen, fuzz->o1); + return 0; + case FUZZ_2_BYTE_FLIP: + snprintf(s, n, "%s case %llu of %llu (bytes: %zu, %zu)\n", + fuzz_ntop(fuzz->strategy), + (((fuzz_ullong)fuzz->o2) * fuzz->slen) + fuzz->o1, + ((fuzz_ullong)fuzz->slen) * fuzz->slen, + fuzz->o1, fuzz->o2); + return 0; + case FUZZ_TRUNCATE_START: + snprintf(s, n, "%s case %zu of %zu (offset: %zu)\n", + fuzz_ntop(fuzz->strategy), + fuzz->o1, fuzz->slen, fuzz->o1); + return 0; + case FUZZ_TRUNCATE_END: + snprintf(s, n, "%s case %zu of %zu (offset: %zu)\n", + fuzz_ntop(fuzz->strategy), + fuzz->o1, fuzz->slen, fuzz->o1); + return 0; + case FUZZ_BASE64: + assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1); + snprintf(s, n, "%s case %llu of %llu (offset: %zu char: %c)\n", + fuzz_ntop(fuzz->strategy), + (fuzz->o1 * (fuzz_ullong)64) + fuzz->o2, + fuzz->slen * (fuzz_ullong)64, fuzz->o1, + fuzz_b64chars[fuzz->o2]); + return 0; + default: + return -1; + abort(); + } +} + +static void +dump(u_char *p, size_t len) +{ + size_t i, j; + + for (i = 0; i < len; i += 16) { + fprintf(stderr, "%.4zd: ", i); + for (j = i; j < i + 16; j++) { + if (j < len) + fprintf(stderr, "%02x ", p[j]); + else + fprintf(stderr, " "); + } + fprintf(stderr, " "); + for (j = i; j < i + 16; j++) { + if (j < len) { + if (isascii(p[j]) && isprint(p[j])) + fprintf(stderr, "%c", p[j]); + else + fprintf(stderr, "."); + } + } + fprintf(stderr, "\n"); + } +} + +void +fuzz_dump(struct fuzz *fuzz) +{ + char buf[256]; + + if (fuzz_fmt(fuzz, buf, sizeof(buf)) != 0) { + fprintf(stderr, "%s: fuzz invalid\n", __func__); + abort(); + } + fputs(buf, stderr); + fprintf(stderr, "fuzz original %p len = %zu\n", fuzz->seed, fuzz->slen); + dump(fuzz->seed, fuzz->slen); + fprintf(stderr, "fuzz context %p len = %zu\n", fuzz, fuzz_len(fuzz)); + dump(fuzz_ptr(fuzz), fuzz_len(fuzz)); +} + +#ifdef SIGINFO +static struct fuzz *last_fuzz; + +static void +siginfo(int unused __attribute__((__unused__))) +{ + char buf[256]; + + test_info(buf, sizeof(buf)); + atomicio(vwrite, STDERR_FILENO, buf, strlen(buf)); + if (last_fuzz != NULL) { + fuzz_fmt(last_fuzz, buf, sizeof(buf)); + atomicio(vwrite, STDERR_FILENO, buf, strlen(buf)); + } +} +#endif + +struct fuzz * +fuzz_begin(u_int strategies, const void *p, size_t l) +{ + struct fuzz *ret = calloc(sizeof(*ret), 1); + + assert(p != NULL); + assert(ret != NULL); + ret->seed = malloc(l); + assert(ret->seed != NULL); + memcpy(ret->seed, p, l); + ret->slen = l; + ret->strategies = strategies; + + assert(ret->slen < SIZE_MAX / 8); + assert(ret->strategies <= (FUZZ_MAX|(FUZZ_MAX-1))); + + FUZZ_DBG(("begin, ret = %p", ret)); + + fuzz_next(ret); + +#ifdef SIGINFO + last_fuzz = ret; + signal(SIGINFO, siginfo); +#endif + + return ret; +} + +void +fuzz_cleanup(struct fuzz *fuzz) +{ + FUZZ_DBG(("cleanup, fuzz = %p", fuzz)); +#ifdef SIGINFO + last_fuzz = NULL; + signal(SIGINFO, SIG_DFL); +#endif + assert(fuzz != NULL); + assert(fuzz->seed != NULL); + assert(fuzz->fuzzed != NULL); + free(fuzz->seed); + free(fuzz->fuzzed); + free(fuzz); +} + +static int +fuzz_strategy_done(struct fuzz *fuzz) +{ + FUZZ_DBG(("fuzz = %p, strategy = %s, o1 = %zu, o2 = %zu, slen = %zu", + fuzz, fuzz_ntop(fuzz->strategy), fuzz->o1, fuzz->o2, fuzz->slen)); + + switch (fuzz->strategy) { + case FUZZ_1_BIT_FLIP: + return fuzz->o1 >= fuzz->slen * 8; + case FUZZ_2_BIT_FLIP: + return fuzz->o2 >= fuzz->slen * 8; + case FUZZ_2_BYTE_FLIP: + return fuzz->o2 >= fuzz->slen; + case FUZZ_1_BYTE_FLIP: + case FUZZ_TRUNCATE_START: + case FUZZ_TRUNCATE_END: + case FUZZ_BASE64: + return fuzz->o1 >= fuzz->slen; + default: + abort(); + } +} + +void +fuzz_next(struct fuzz *fuzz) +{ + u_int i; + + FUZZ_DBG(("start, fuzz = %p, strategy = %s, strategies = 0x%lx, " + "o1 = %zu, o2 = %zu, slen = %zu", fuzz, fuzz_ntop(fuzz->strategy), + (u_long)fuzz->strategies, fuzz->o1, fuzz->o2, fuzz->slen)); + + if (fuzz->strategy == 0 || fuzz_strategy_done(fuzz)) { + /* If we are just starting out, we need to allocate too */ + if (fuzz->fuzzed == NULL) { + FUZZ_DBG(("alloc")); + fuzz->fuzzed = calloc(fuzz->slen, 1); + } + /* Pick next strategy */ + FUZZ_DBG(("advance")); + for (i = 1; i <= FUZZ_MAX; i <<= 1) { + if ((fuzz->strategies & i) != 0) { + fuzz->strategy = i; + break; + } + } + FUZZ_DBG(("selected = %u", fuzz->strategy)); + if (fuzz->strategy == 0) { + FUZZ_DBG(("done, no more strategies")); + return; + } + fuzz->strategies &= ~(fuzz->strategy); + fuzz->o1 = fuzz->o2 = 0; + } + + assert(fuzz->fuzzed != NULL); + + switch (fuzz->strategy) { + case FUZZ_1_BIT_FLIP: + assert(fuzz->o1 / 8 < fuzz->slen); + memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen); + fuzz->fuzzed[fuzz->o1 / 8] ^= 1 << (fuzz->o1 % 8); + fuzz->o1++; + break; + case FUZZ_2_BIT_FLIP: + assert(fuzz->o1 / 8 < fuzz->slen); + assert(fuzz->o2 / 8 < fuzz->slen); + memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen); + fuzz->fuzzed[fuzz->o1 / 8] ^= 1 << (fuzz->o1 % 8); + fuzz->fuzzed[fuzz->o2 / 8] ^= 1 << (fuzz->o2 % 8); + fuzz->o1++; + if (fuzz->o1 >= fuzz->slen * 8) { + fuzz->o1 = 0; + fuzz->o2++; + } + break; + case FUZZ_1_BYTE_FLIP: + assert(fuzz->o1 < fuzz->slen); + memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen); + fuzz->fuzzed[fuzz->o1] ^= 0xff; + fuzz->o1++; + break; + case FUZZ_2_BYTE_FLIP: + assert(fuzz->o1 < fuzz->slen); + assert(fuzz->o2 < fuzz->slen); + memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen); + fuzz->fuzzed[fuzz->o1] ^= 0xff; + fuzz->fuzzed[fuzz->o2] ^= 0xff; + fuzz->o1++; + if (fuzz->o1 >= fuzz->slen) { + fuzz->o1 = 0; + fuzz->o2++; + } + break; + case FUZZ_TRUNCATE_START: + case FUZZ_TRUNCATE_END: + assert(fuzz->o1 < fuzz->slen); + memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen); + fuzz->o1++; + break; + case FUZZ_BASE64: + assert(fuzz->o1 < fuzz->slen); + assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1); + memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen); + fuzz->fuzzed[fuzz->o1] = fuzz_b64chars[fuzz->o2]; + fuzz->o2++; + if (fuzz->o2 >= sizeof(fuzz_b64chars) - 1) { + fuzz->o2 = 0; + fuzz->o1++; + } + break; + default: + abort(); + } + + FUZZ_DBG(("done, fuzz = %p, strategy = %s, strategies = 0x%lx, " + "o1 = %zu, o2 = %zu, slen = %zu", fuzz, fuzz_ntop(fuzz->strategy), + (u_long)fuzz->strategies, fuzz->o1, fuzz->o2, fuzz->slen)); +} + +int +fuzz_matches_original(struct fuzz *fuzz) +{ + if (fuzz_len(fuzz) != fuzz->slen) + return 0; + return memcmp(fuzz_ptr(fuzz), fuzz->seed, fuzz->slen) == 0; +} + +int +fuzz_done(struct fuzz *fuzz) +{ + FUZZ_DBG(("fuzz = %p, strategies = 0x%lx", fuzz, + (u_long)fuzz->strategies)); + + return fuzz_strategy_done(fuzz) && fuzz->strategies == 0; +} + +size_t +fuzz_len(struct fuzz *fuzz) +{ + assert(fuzz->fuzzed != NULL); + switch (fuzz->strategy) { + case FUZZ_1_BIT_FLIP: + case FUZZ_2_BIT_FLIP: + case FUZZ_1_BYTE_FLIP: + case FUZZ_2_BYTE_FLIP: + case FUZZ_BASE64: + return fuzz->slen; + case FUZZ_TRUNCATE_START: + case FUZZ_TRUNCATE_END: + assert(fuzz->o1 <= fuzz->slen); + return fuzz->slen - fuzz->o1; + default: + abort(); + } +} + +u_char * +fuzz_ptr(struct fuzz *fuzz) +{ + assert(fuzz->fuzzed != NULL); + switch (fuzz->strategy) { + case FUZZ_1_BIT_FLIP: + case FUZZ_2_BIT_FLIP: + case FUZZ_1_BYTE_FLIP: + case FUZZ_2_BYTE_FLIP: + case FUZZ_BASE64: + return fuzz->fuzzed; + case FUZZ_TRUNCATE_START: + assert(fuzz->o1 <= fuzz->slen); + return fuzz->fuzzed + fuzz->o1; + case FUZZ_TRUNCATE_END: + assert(fuzz->o1 <= fuzz->slen); + return fuzz->fuzzed; + default: + abort(); + } +} + diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/test_helper/test_helper.c b/crypto/external/bsd/openssh/dist/regress/unittests/test_helper/test_helper.c new file mode 100644 index 000000000..26ca26b5e --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/test_helper/test_helper.c @@ -0,0 +1,526 @@ +/* $OpenBSD: test_helper.c,v 1.6 2015/03/03 20:42:49 djm Exp $ */ +/* + * Copyright (c) 2011 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* Utility functions/framework for regress tests */ + +#include "includes.h" + +#include +#include +#include + +#include +#include +#ifdef HAVE_STDINT_H +# include +#endif +#include +#include +#include +#include +#include + +#include + +#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) +# include +#endif + +#include "test_helper.h" +#include "atomicio.h" + +#define TEST_CHECK_INT(r, pred) do { \ + switch (pred) { \ + case TEST_EQ: \ + if (r == 0) \ + return; \ + break; \ + case TEST_NE: \ + if (r != 0) \ + return; \ + break; \ + case TEST_LT: \ + if (r < 0) \ + return; \ + break; \ + case TEST_LE: \ + if (r <= 0) \ + return; \ + break; \ + case TEST_GT: \ + if (r > 0) \ + return; \ + break; \ + case TEST_GE: \ + if (r >= 0) \ + return; \ + break; \ + default: \ + abort(); \ + } \ + } while (0) + +#define TEST_CHECK(x1, x2, pred) do { \ + switch (pred) { \ + case TEST_EQ: \ + if (x1 == x2) \ + return; \ + break; \ + case TEST_NE: \ + if (x1 != x2) \ + return; \ + break; \ + case TEST_LT: \ + if (x1 < x2) \ + return; \ + break; \ + case TEST_LE: \ + if (x1 <= x2) \ + return; \ + break; \ + case TEST_GT: \ + if (x1 > x2) \ + return; \ + break; \ + case TEST_GE: \ + if (x1 >= x2) \ + return; \ + break; \ + default: \ + abort(); \ + } \ + } while (0) + +extern char *__progname; + +static int verbose_mode = 0; +static int quiet_mode = 0; +static char *active_test_name = NULL; +static u_int test_number = 0; +static test_onerror_func_t *test_onerror = NULL; +static void *onerror_ctx = NULL; +static const char *data_dir = NULL; +static char subtest_info[512]; + +int +main(int argc, char **argv) +{ + int ch; + + /* Handle systems without __progname */ + if (__progname == NULL) { + __progname = strrchr(argv[0], '/'); + if (__progname == NULL || __progname[1] == '\0') + __progname = argv[0]; + else + __progname++; + if ((__progname = strdup(__progname)) == NULL) { + fprintf(stderr, "strdup failed\n"); + exit(1); + } + } + + while ((ch = getopt(argc, argv, "vqd:")) != -1) { + switch (ch) { + case 'd': + data_dir = optarg; + break; + case 'q': + verbose_mode = 0; + quiet_mode = 1; + break; + case 'v': + verbose_mode = 1; + quiet_mode = 0; + break; + default: + fprintf(stderr, "Unrecognised command line option\n"); + fprintf(stderr, "Usage: %s [-v]\n", __progname); + exit(1); + } + } + setvbuf(stdout, NULL, _IONBF, 0); + if (!quiet_mode) + printf("%s: ", __progname); + if (verbose_mode) + printf("\n"); + + tests(); + + if (!quiet_mode) + printf(" %u tests ok\n", test_number); + return 0; +} + +const char * +test_data_file(const char *name) +{ + static char ret[PATH_MAX]; + + if (data_dir != NULL) + snprintf(ret, sizeof(ret), "%s/%s", data_dir, name); + else + strlcpy(ret, name, sizeof(ret)); + if (access(ret, F_OK) != 0) { + fprintf(stderr, "Cannot access data file %s: %s\n", + ret, strerror(errno)); + exit(1); + } + return ret; +} + +void +test_info(char *s, size_t len) +{ + snprintf(s, len, "In test %u: \"%s\"%s%s\n", test_number, + active_test_name == NULL ? "" : active_test_name, + *subtest_info != '\0' ? " - " : "", subtest_info); +} + +#ifdef SIGINFO +static void +siginfo(int unused __attribute__((__unused__))) +{ + char buf[256]; + + test_info(buf, sizeof(buf)); + atomicio(vwrite, STDERR_FILENO, buf, strlen(buf)); +} +#endif + +void +test_start(const char *n) +{ + assert(active_test_name == NULL); + assert((active_test_name = strdup(n)) != NULL); + *subtest_info = '\0'; + if (verbose_mode) + printf("test %u - \"%s\": ", test_number, active_test_name); + test_number++; +#ifdef SIGINFO + signal(SIGINFO, siginfo); +#endif +} + +void +set_onerror_func(test_onerror_func_t *f, void *ctx) +{ + test_onerror = f; + onerror_ctx = ctx; +} + +void +test_done(void) +{ + *subtest_info = '\0'; + assert(active_test_name != NULL); + free(active_test_name); + active_test_name = NULL; + if (verbose_mode) + printf("OK\n"); + else if (!quiet_mode) { + printf("."); + fflush(stdout); + } +} + +void +test_subtest_info(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vsnprintf(subtest_info, sizeof(subtest_info), fmt, ap); + va_end(ap); +} + +void +ssl_err_check(const char *file, int line) +{ + long openssl_error = ERR_get_error(); + + if (openssl_error == 0) + return; + + fprintf(stderr, "\n%s:%d: uncaught OpenSSL error: %s", + file, line, ERR_error_string(openssl_error, NULL)); + abort(); +} + +static const char * +pred_name(enum test_predicate p) +{ + switch (p) { + case TEST_EQ: + return "EQ"; + case TEST_NE: + return "NE"; + case TEST_LT: + return "LT"; + case TEST_LE: + return "LE"; + case TEST_GT: + return "GT"; + case TEST_GE: + return "GE"; + default: + return "UNKNOWN"; + } +} + +static void +test_die(void) +{ + if (test_onerror != NULL) + test_onerror(onerror_ctx); + abort(); +} + +static void +test_header(const char *file, int line, const char *a1, const char *a2, + const char *name, enum test_predicate pred) +{ + fprintf(stderr, "\n%s:%d test #%u \"%s\"%s%s\n", + file, line, test_number, active_test_name, + *subtest_info != '\0' ? " - " : "", subtest_info); + fprintf(stderr, "ASSERT_%s_%s(%s%s%s) failed:\n", + name, pred_name(pred), a1, + a2 != NULL ? ", " : "", a2 != NULL ? a2 : ""); +} + +void +assert_bignum(const char *file, int line, const char *a1, const char *a2, + const BIGNUM *aa1, const BIGNUM *aa2, enum test_predicate pred) +{ + int r = BN_cmp(aa1, aa2); + + TEST_CHECK_INT(r, pred); + test_header(file, line, a1, a2, "BIGNUM", pred); + fprintf(stderr, "%12s = 0x%s\n", a1, BN_bn2hex(aa1)); + fprintf(stderr, "%12s = 0x%s\n", a2, BN_bn2hex(aa2)); + test_die(); +} + +void +assert_string(const char *file, int line, const char *a1, const char *a2, + const char *aa1, const char *aa2, enum test_predicate pred) +{ + int r; + + /* Verify pointers are not NULL */ + assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE); + assert_ptr(file, line, a2, "NULL", aa2, NULL, TEST_NE); + + r = strcmp(aa1, aa2); + TEST_CHECK_INT(r, pred); + test_header(file, line, a1, a2, "STRING", pred); + fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1, strlen(aa1)); + fprintf(stderr, "%12s = %s (len %zu)\n", a2, aa2, strlen(aa2)); + test_die(); +} + +static char * +tohex(const void *_s, size_t l) +{ + u_int8_t *s = (u_int8_t *)_s; + size_t i, j; + const char *hex = "0123456789abcdef"; + char *r = malloc((l * 2) + 1); + + assert(r != NULL); + for (i = j = 0; i < l; i++) { + r[j++] = hex[(s[i] >> 4) & 0xf]; + r[j++] = hex[s[i] & 0xf]; + } + r[j] = '\0'; + return r; +} + +void +assert_mem(const char *file, int line, const char *a1, const char *a2, + const void *aa1, const void *aa2, size_t l, enum test_predicate pred) +{ + int r; + + if (l == 0) + return; + /* If length is >0, then verify pointers are not NULL */ + assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE); + assert_ptr(file, line, a2, "NULL", aa2, NULL, TEST_NE); + + r = memcmp(aa1, aa2, l); + TEST_CHECK_INT(r, pred); + test_header(file, line, a1, a2, "STRING", pred); + fprintf(stderr, "%12s = %s (len %zu)\n", a1, tohex(aa1, MIN(l, 256)), l); + fprintf(stderr, "%12s = %s (len %zu)\n", a2, tohex(aa2, MIN(l, 256)), l); + test_die(); +} + +static int +memvalcmp(const u_int8_t *s, u_char v, size_t l, size_t *where) +{ + size_t i; + + for (i = 0; i < l; i++) { + if (s[i] != v) { + *where = i; + return 1; + } + } + return 0; +} + +void +assert_mem_filled(const char *file, int line, const char *a1, + const void *aa1, u_char v, size_t l, enum test_predicate pred) +{ + size_t where = -1; + int r; + char tmp[64]; + + if (l == 0) + return; + /* If length is >0, then verify the pointer is not NULL */ + assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE); + + r = memvalcmp(aa1, v, l, &where); + TEST_CHECK_INT(r, pred); + test_header(file, line, a1, NULL, "MEM_ZERO", pred); + fprintf(stderr, "%20s = %s%s (len %zu)\n", a1, + tohex(aa1, MIN(l, 20)), l > 20 ? "..." : "", l); + snprintf(tmp, sizeof(tmp), "(%s)[%zu]", a1, where); + fprintf(stderr, "%20s = 0x%02x (expected 0x%02x)\n", tmp, + ((u_char *)aa1)[where], v); + test_die(); +} + +void +assert_int(const char *file, int line, const char *a1, const char *a2, + int aa1, int aa2, enum test_predicate pred) +{ + TEST_CHECK(aa1, aa2, pred); + test_header(file, line, a1, a2, "INT", pred); + fprintf(stderr, "%12s = %d\n", a1, aa1); + fprintf(stderr, "%12s = %d\n", a2, aa2); + test_die(); +} + +void +assert_size_t(const char *file, int line, const char *a1, const char *a2, + size_t aa1, size_t aa2, enum test_predicate pred) +{ + TEST_CHECK(aa1, aa2, pred); + test_header(file, line, a1, a2, "SIZE_T", pred); + fprintf(stderr, "%12s = %zu\n", a1, aa1); + fprintf(stderr, "%12s = %zu\n", a2, aa2); + test_die(); +} + +void +assert_u_int(const char *file, int line, const char *a1, const char *a2, + u_int aa1, u_int aa2, enum test_predicate pred) +{ + TEST_CHECK(aa1, aa2, pred); + test_header(file, line, a1, a2, "U_INT", pred); + fprintf(stderr, "%12s = %u / 0x%x\n", a1, aa1, aa1); + fprintf(stderr, "%12s = %u / 0x%x\n", a2, aa2, aa2); + test_die(); +} + +void +assert_long_long(const char *file, int line, const char *a1, const char *a2, + long long aa1, long long aa2, enum test_predicate pred) +{ + TEST_CHECK(aa1, aa2, pred); + test_header(file, line, a1, a2, "LONG LONG", pred); + fprintf(stderr, "%12s = %lld / 0x%llx\n", a1, aa1, aa1); + fprintf(stderr, "%12s = %lld / 0x%llx\n", a2, aa2, aa2); + test_die(); +} + +void +assert_char(const char *file, int line, const char *a1, const char *a2, + char aa1, char aa2, enum test_predicate pred) +{ + char buf[8]; + + TEST_CHECK(aa1, aa2, pred); + test_header(file, line, a1, a2, "CHAR", pred); + fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1, + vis(buf, aa1, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa1); + fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1, + vis(buf, aa2, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa2); + test_die(); +} + +void +assert_u8(const char *file, int line, const char *a1, const char *a2, + u_int8_t aa1, u_int8_t aa2, enum test_predicate pred) +{ + TEST_CHECK(aa1, aa2, pred); + test_header(file, line, a1, a2, "U8", pred); + fprintf(stderr, "%12s = 0x%02x %u\n", a1, aa1, aa1); + fprintf(stderr, "%12s = 0x%02x %u\n", a2, aa2, aa2); + test_die(); +} + +void +assert_u16(const char *file, int line, const char *a1, const char *a2, + u_int16_t aa1, u_int16_t aa2, enum test_predicate pred) +{ + TEST_CHECK(aa1, aa2, pred); + test_header(file, line, a1, a2, "U16", pred); + fprintf(stderr, "%12s = 0x%04x %u\n", a1, aa1, aa1); + fprintf(stderr, "%12s = 0x%04x %u\n", a2, aa2, aa2); + test_die(); +} + +void +assert_u32(const char *file, int line, const char *a1, const char *a2, + u_int32_t aa1, u_int32_t aa2, enum test_predicate pred) +{ + TEST_CHECK(aa1, aa2, pred); + test_header(file, line, a1, a2, "U32", pred); + fprintf(stderr, "%12s = 0x%08x %u\n", a1, aa1, aa1); + fprintf(stderr, "%12s = 0x%08x %u\n", a2, aa2, aa2); + test_die(); +} + +void +assert_u64(const char *file, int line, const char *a1, const char *a2, + u_int64_t aa1, u_int64_t aa2, enum test_predicate pred) +{ + TEST_CHECK(aa1, aa2, pred); + test_header(file, line, a1, a2, "U64", pred); + fprintf(stderr, "%12s = 0x%016llx %llu\n", a1, + (unsigned long long)aa1, (unsigned long long)aa1); + fprintf(stderr, "%12s = 0x%016llx %llu\n", a2, + (unsigned long long)aa2, (unsigned long long)aa2); + test_die(); +} + +void +assert_ptr(const char *file, int line, const char *a1, const char *a2, + const void *aa1, const void *aa2, enum test_predicate pred) +{ + TEST_CHECK(aa1, aa2, pred); + test_header(file, line, a1, a2, "PTR", pred); + fprintf(stderr, "%12s = %p\n", a1, aa1); + fprintf(stderr, "%12s = %p\n", a2, aa2); + test_die(); +} + diff --git a/crypto/external/bsd/openssh/dist/regress/unittests/test_helper/test_helper.h b/crypto/external/bsd/openssh/dist/regress/unittests/test_helper/test_helper.h new file mode 100644 index 000000000..1d9c66986 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/unittests/test_helper/test_helper.h @@ -0,0 +1,303 @@ +/* $OpenBSD: test_helper.h,v 1.6 2015/01/18 19:52:44 djm Exp $ */ +/* + * Copyright (c) 2011 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* Utility functions/framework for regress tests */ + +#ifndef _TEST_HELPER_H +#define _TEST_HELPER_H + +#include "includes.h" + +#include +#ifdef HAVE_STDINT_H +# include +#endif + +#include +#include + +enum test_predicate { + TEST_EQ, TEST_NE, TEST_LT, TEST_LE, TEST_GT, TEST_GE +}; +typedef void (test_onerror_func_t)(void *); + +/* Supplied by test suite */ +void tests(void); + +const char *test_data_file(const char *name); +void test_start(const char *n); +void test_info(char *s, size_t len); +void set_onerror_func(test_onerror_func_t *f, void *ctx); +void test_done(void); +void test_subtest_info(const char *fmt, ...) + __attribute__((format(printf, 1, 2))); +void ssl_err_check(const char *file, int line); +void assert_bignum(const char *file, int line, + const char *a1, const char *a2, + const BIGNUM *aa1, const BIGNUM *aa2, enum test_predicate pred); +void assert_string(const char *file, int line, + const char *a1, const char *a2, + const char *aa1, const char *aa2, enum test_predicate pred); +void assert_mem(const char *file, int line, + const char *a1, const char *a2, + const void *aa1, const void *aa2, size_t l, enum test_predicate pred); +void assert_mem_filled(const char *file, int line, + const char *a1, + const void *aa1, u_char v, size_t l, enum test_predicate pred); +void assert_int(const char *file, int line, + const char *a1, const char *a2, + int aa1, int aa2, enum test_predicate pred); +void assert_size_t(const char *file, int line, + const char *a1, const char *a2, + size_t aa1, size_t aa2, enum test_predicate pred); +void assert_u_int(const char *file, int line, + const char *a1, const char *a2, + u_int aa1, u_int aa2, enum test_predicate pred); +void assert_long_long(const char *file, int line, + const char *a1, const char *a2, + long long aa1, long long aa2, enum test_predicate pred); +void assert_char(const char *file, int line, + const char *a1, const char *a2, + char aa1, char aa2, enum test_predicate pred); +void assert_ptr(const char *file, int line, + const char *a1, const char *a2, + const void *aa1, const void *aa2, enum test_predicate pred); +void assert_u8(const char *file, int line, + const char *a1, const char *a2, + u_int8_t aa1, u_int8_t aa2, enum test_predicate pred); +void assert_u16(const char *file, int line, + const char *a1, const char *a2, + u_int16_t aa1, u_int16_t aa2, enum test_predicate pred); +void assert_u32(const char *file, int line, + const char *a1, const char *a2, + u_int32_t aa1, u_int32_t aa2, enum test_predicate pred); +void assert_u64(const char *file, int line, + const char *a1, const char *a2, + u_int64_t aa1, u_int64_t aa2, enum test_predicate pred); + +#define TEST_START(n) test_start(n) +#define TEST_DONE() test_done() +#define TEST_ONERROR(f, c) set_onerror_func(f, c) +#define SSL_ERR_CHECK() ssl_err_check(__FILE__, __LINE__) + +#define ASSERT_BIGNUM_EQ(a1, a2) \ + assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) +#define ASSERT_STRING_EQ(a1, a2) \ + assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) +#define ASSERT_MEM_EQ(a1, a2, l) \ + assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_EQ) +#define ASSERT_MEM_FILLED_EQ(a1, c, l) \ + assert_mem_filled(__FILE__, __LINE__, #a1, a1, c, l, TEST_EQ) +#define ASSERT_MEM_ZERO_EQ(a1, l) \ + assert_mem_filled(__FILE__, __LINE__, #a1, a1, '\0', l, TEST_EQ) +#define ASSERT_INT_EQ(a1, a2) \ + assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) +#define ASSERT_SIZE_T_EQ(a1, a2) \ + assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) +#define ASSERT_U_INT_EQ(a1, a2) \ + assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) +#define ASSERT_LONG_LONG_EQ(a1, a2) \ + assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) +#define ASSERT_CHAR_EQ(a1, a2) \ + assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) +#define ASSERT_PTR_EQ(a1, a2) \ + assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) +#define ASSERT_U8_EQ(a1, a2) \ + assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) +#define ASSERT_U16_EQ(a1, a2) \ + assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) +#define ASSERT_U32_EQ(a1, a2) \ + assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) +#define ASSERT_U64_EQ(a1, a2) \ + assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) + +#define ASSERT_BIGNUM_NE(a1, a2) \ + assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) +#define ASSERT_STRING_NE(a1, a2) \ + assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) +#define ASSERT_MEM_NE(a1, a2, l) \ + assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_NE) +#define ASSERT_MEM_ZERO_NE(a1, l) \ + assert_mem_filled(__FILE__, __LINE__, #a1, a1, '\0', l, TEST_NE) +#define ASSERT_INT_NE(a1, a2) \ + assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) +#define ASSERT_SIZE_T_NE(a1, a2) \ + assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) +#define ASSERT_U_INT_NE(a1, a2) \ + assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) +#define ASSERT_LONG_LONG_NE(a1, a2) \ + assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) +#define ASSERT_CHAR_NE(a1, a2) \ + assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) +#define ASSERT_PTR_NE(a1, a2) \ + assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) +#define ASSERT_U8_NE(a1, a2) \ + assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) +#define ASSERT_U16_NE(a1, a2) \ + assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) +#define ASSERT_U32_NE(a1, a2) \ + assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) +#define ASSERT_U64_NE(a1, a2) \ + assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) + +#define ASSERT_BIGNUM_LT(a1, a2) \ + assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) +#define ASSERT_STRING_LT(a1, a2) \ + assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) +#define ASSERT_MEM_LT(a1, a2, l) \ + assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_LT) +#define ASSERT_INT_LT(a1, a2) \ + assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) +#define ASSERT_SIZE_T_LT(a1, a2) \ + assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) +#define ASSERT_U_INT_LT(a1, a2) \ + assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) +#define ASSERT_LONG_LONG_LT(a1, a2) \ + assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) +#define ASSERT_CHAR_LT(a1, a2) \ + assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) +#define ASSERT_PTR_LT(a1, a2) \ + assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) +#define ASSERT_U8_LT(a1, a2) \ + assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) +#define ASSERT_U16_LT(a1, a2) \ + assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) +#define ASSERT_U32_LT(a1, a2) \ + assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) +#define ASSERT_U64_LT(a1, a2) \ + assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) + +#define ASSERT_BIGNUM_LE(a1, a2) \ + assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) +#define ASSERT_STRING_LE(a1, a2) \ + assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) +#define ASSERT_MEM_LE(a1, a2, l) \ + assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_LE) +#define ASSERT_INT_LE(a1, a2) \ + assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) +#define ASSERT_SIZE_T_LE(a1, a2) \ + assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) +#define ASSERT_U_INT_LE(a1, a2) \ + assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) +#define ASSERT_LONG_LONG_LE(a1, a2) \ + assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) +#define ASSERT_CHAR_LE(a1, a2) \ + assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) +#define ASSERT_PTR_LE(a1, a2) \ + assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) +#define ASSERT_U8_LE(a1, a2) \ + assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) +#define ASSERT_U16_LE(a1, a2) \ + assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) +#define ASSERT_U32_LE(a1, a2) \ + assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) +#define ASSERT_U64_LE(a1, a2) \ + assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) + +#define ASSERT_BIGNUM_GT(a1, a2) \ + assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) +#define ASSERT_STRING_GT(a1, a2) \ + assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) +#define ASSERT_MEM_GT(a1, a2, l) \ + assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_GT) +#define ASSERT_INT_GT(a1, a2) \ + assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) +#define ASSERT_SIZE_T_GT(a1, a2) \ + assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) +#define ASSERT_U_INT_GT(a1, a2) \ + assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) +#define ASSERT_LONG_LONG_GT(a1, a2) \ + assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) +#define ASSERT_CHAR_GT(a1, a2) \ + assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) +#define ASSERT_PTR_GT(a1, a2) \ + assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) +#define ASSERT_U8_GT(a1, a2) \ + assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) +#define ASSERT_U16_GT(a1, a2) \ + assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) +#define ASSERT_U32_GT(a1, a2) \ + assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) +#define ASSERT_U64_GT(a1, a2) \ + assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) + +#define ASSERT_BIGNUM_GE(a1, a2) \ + assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) +#define ASSERT_STRING_GE(a1, a2) \ + assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) +#define ASSERT_MEM_GE(a1, a2, l) \ + assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_GE) +#define ASSERT_INT_GE(a1, a2) \ + assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) +#define ASSERT_SIZE_T_GE(a1, a2) \ + assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) +#define ASSERT_U_INT_GE(a1, a2) \ + assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) +#define ASSERT_LONG_LONG_GE(a1, a2) \ + assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) +#define ASSERT_CHAR_GE(a1, a2) \ + assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) +#define ASSERT_PTR_GE(a1, a2) \ + assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) +#define ASSERT_U8_GE(a1, a2) \ + assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) +#define ASSERT_U16_GE(a1, a2) \ + assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) +#define ASSERT_U32_GE(a1, a2) \ + assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) +#define ASSERT_U64_GE(a1, a2) \ + assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) + +/* Fuzzing support */ + +struct fuzz; +#define FUZZ_1_BIT_FLIP 0x00000001 /* Flip one bit at a time */ +#define FUZZ_2_BIT_FLIP 0x00000002 /* Flip two bits at a time */ +#define FUZZ_1_BYTE_FLIP 0x00000004 /* Flip one byte at a time */ +#define FUZZ_2_BYTE_FLIP 0x00000008 /* Flip two bytes at a time */ +#define FUZZ_TRUNCATE_START 0x00000010 /* Truncate from beginning */ +#define FUZZ_TRUNCATE_END 0x00000020 /* Truncate from end */ +#define FUZZ_BASE64 0x00000040 /* Try all base64 chars */ +#define FUZZ_MAX FUZZ_BASE64 + +/* Start fuzzing a blob of data with selected strategies (bitmask) */ +struct fuzz *fuzz_begin(u_int strategies, const void *p, size_t l); + +/* Free a fuzz context */ +void fuzz_cleanup(struct fuzz *fuzz); + +/* Prepare the next fuzz case in the series */ +void fuzz_next(struct fuzz *fuzz); + +/* + * Check whether this fuzz case is identical to the original + * This is slow, but useful if the caller needs to ensure that all tests + * generated change the input (e.g. when fuzzing signatures). + */ +int fuzz_matches_original(struct fuzz *fuzz); + +/* Determine whether the current fuzz sequence is exhausted (nonzero = yes) */ +int fuzz_done(struct fuzz *fuzz); + +/* Return the length and a pointer to the current fuzzed case */ +size_t fuzz_len(struct fuzz *fuzz); +u_char *fuzz_ptr(struct fuzz *fuzz); + +/* Dump the current fuzz case to stderr */ +void fuzz_dump(struct fuzz *fuzz); + +#endif /* _TEST_HELPER_H */ diff --git a/crypto/external/bsd/openssh/dist/regress/valgrind-unit.sh b/crypto/external/bsd/openssh/dist/regress/valgrind-unit.sh new file mode 100755 index 000000000..433cb069a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/valgrind-unit.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +UNIT_BINARY="$1" +shift +UNIT_ARGS="$@" + +test "x$OBJ" = "x" && OBJ=$PWD + +# This mostly replicates the logic in test-exec.sh for running the +# regress tests under valgrind. +VG_TEST=`basename $UNIT_BINARY` +VG_LOG="$OBJ/valgrind-out/${VG_TEST}.%p" +VG_OPTS="--track-origins=yes --leak-check=full --log-file=${VG_LOG}" +VG_OPTS="$VG_OPTS --trace-children=yes" +VG_PATH="valgrind" +if [ "x$VALGRIND_PATH" != "x" ]; then + VG_PATH="$VALGRIND_PATH" +fi + +exec $VG_PATH $VG_OPTS $UNIT_BINARY $UNIT_ARGS diff --git a/crypto/external/bsd/openssh/dist/regress/yes-head.sh b/crypto/external/bsd/openssh/dist/regress/yes-head.sh new file mode 100644 index 000000000..1fc754211 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/regress/yes-head.sh @@ -0,0 +1,15 @@ +# $OpenBSD: yes-head.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ +# Placed in the Public Domain. + +tid="yes pipe head" + +for p in ${SSH_PROTOCOLS}; do + lines=`${SSH} -$p -F $OBJ/ssh_proxy thishost 'sh -c "while true;do echo yes;done | _POSIX2_VERSION=199209 head -2000"' | (sleep 3 ; wc -l)` + if [ $? -ne 0 ]; then + fail "yes|head test failed" + lines = 0; + fi + if [ $lines -ne 2000 ]; then + fail "yes|head returns $lines lines instead of 2000" + fi +done diff --git a/crypto/external/bsd/openssh/dist/sandbox-capsicum.c b/crypto/external/bsd/openssh/dist/sandbox-capsicum.c new file mode 100644 index 000000000..655f0d217 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/sandbox-capsicum.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2011 Dag-Erling Smorgrav + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#ifdef SANDBOX_CAPSICUM + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "monitor.h" +#include "ssh-sandbox.h" +#include "xmalloc.h" + +/* + * Capsicum sandbox that sets zero nfiles, nprocs and filesize rlimits, + * limits rights on stdout, stdin, stderr, monitor and switches to + * capability mode. + */ + +struct ssh_sandbox { + struct monitor *monitor; + pid_t child_pid; +}; + +struct ssh_sandbox * +ssh_sandbox_init(struct monitor *monitor) +{ + struct ssh_sandbox *box; + + /* + * Strictly, we don't need to maintain any state here but we need + * to return non-NULL to satisfy the API. + */ + debug3("%s: preparing capsicum sandbox", __func__); + box = xcalloc(1, sizeof(*box)); + box->monitor = monitor; + box->child_pid = 0; + + return box; +} + +void +ssh_sandbox_child(struct ssh_sandbox *box) +{ + struct rlimit rl_zero; + cap_rights_t rights; + + rl_zero.rlim_cur = rl_zero.rlim_max = 0; + + if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1) + fatal("%s: setrlimit(RLIMIT_FSIZE, { 0, 0 }): %s", + __func__, strerror(errno)); +#ifndef SANDBOX_SKIP_RLIMIT_NOFILE + if (setrlimit(RLIMIT_NOFILE, &rl_zero) == -1) + fatal("%s: setrlimit(RLIMIT_NOFILE, { 0, 0 }): %s", + __func__, strerror(errno)); +#endif + if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1) + fatal("%s: setrlimit(RLIMIT_NPROC, { 0, 0 }): %s", + __func__, strerror(errno)); + + cap_rights_init(&rights); + + if (cap_rights_limit(STDIN_FILENO, &rights) < 0 && errno != ENOSYS) + fatal("can't limit stdin: %m"); + if (cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS) + fatal("can't limit stdout: %m"); + if (cap_rights_limit(STDERR_FILENO, &rights) < 0 && errno != ENOSYS) + fatal("can't limit stderr: %m"); + + cap_rights_init(&rights, CAP_READ, CAP_WRITE); + if (cap_rights_limit(box->monitor->m_recvfd, &rights) < 0 && + errno != ENOSYS) + fatal("%s: failed to limit the network socket", __func__); + cap_rights_init(&rights, CAP_WRITE); + if (cap_rights_limit(box->monitor->m_log_sendfd, &rights) < 0 && + errno != ENOSYS) + fatal("%s: failed to limit the logging socket", __func__); + if (cap_enter() < 0 && errno != ENOSYS) + fatal("%s: failed to enter capability mode", __func__); + +} + +void +ssh_sandbox_parent_finish(struct ssh_sandbox *box) +{ + free(box); + debug3("%s: finished", __func__); +} + +void +ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) +{ + box->child_pid = child_pid; +} + +#endif /* SANDBOX_CAPSICUM */ diff --git a/crypto/external/bsd/openssh/dist/sandbox-darwin.c b/crypto/external/bsd/openssh/dist/sandbox-darwin.c new file mode 100644 index 000000000..35f0c4d1a --- /dev/null +++ b/crypto/external/bsd/openssh/dist/sandbox-darwin.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2011 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#ifdef SANDBOX_DARWIN + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "sandbox.h" +#include "xmalloc.h" + +/* Darwin/OS X sandbox */ + +struct ssh_sandbox { + pid_t child_pid; +}; + +struct ssh_sandbox * +ssh_sandbox_init(struct monitor *monitor) +{ + struct ssh_sandbox *box; + + /* + * Strictly, we don't need to maintain any state here but we need + * to return non-NULL to satisfy the API. + */ + debug3("%s: preparing Darwin sandbox", __func__); + box = xcalloc(1, sizeof(*box)); + box->child_pid = 0; + + return box; +} + +void +ssh_sandbox_child(struct ssh_sandbox *box) +{ + char *errmsg; + struct rlimit rl_zero; + + debug3("%s: starting Darwin sandbox", __func__); + if (sandbox_init(kSBXProfilePureComputation, SANDBOX_NAMED, + &errmsg) == -1) + fatal("%s: sandbox_init: %s", __func__, errmsg); + + /* + * The kSBXProfilePureComputation still allows sockets, so + * we must disable these using rlimit. + */ + rl_zero.rlim_cur = rl_zero.rlim_max = 0; + if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1) + fatal("%s: setrlimit(RLIMIT_FSIZE, { 0, 0 }): %s", + __func__, strerror(errno)); + if (setrlimit(RLIMIT_NOFILE, &rl_zero) == -1) + fatal("%s: setrlimit(RLIMIT_NOFILE, { 0, 0 }): %s", + __func__, strerror(errno)); + if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1) + fatal("%s: setrlimit(RLIMIT_NPROC, { 0, 0 }): %s", + __func__, strerror(errno)); +} + +void +ssh_sandbox_parent_finish(struct ssh_sandbox *box) +{ + free(box); + debug3("%s: finished", __func__); +} + +void +ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) +{ + box->child_pid = child_pid; +} + +#endif /* SANDBOX_DARWIN */ diff --git a/crypto/external/bsd/openssh/dist/sandbox-null.c b/crypto/external/bsd/openssh/dist/sandbox-null.c new file mode 100644 index 000000000..d4cb9188b --- /dev/null +++ b/crypto/external/bsd/openssh/dist/sandbox-null.c @@ -0,0 +1,72 @@ +/* $OpenBSD$ */ +/* + * Copyright (c) 2011 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#ifdef SANDBOX_NULL + +#include + +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "ssh-sandbox.h" +#include "xmalloc.h" + +/* dummy sandbox */ + +struct ssh_sandbox { + int junk; +}; + +struct ssh_sandbox * +ssh_sandbox_init(struct monitor *monitor) +{ + struct ssh_sandbox *box; + + /* + * Strictly, we don't need to maintain any state here but we need + * to return non-NULL to satisfy the API. + */ + box = xcalloc(1, sizeof(*box)); + return box; +} + +void +ssh_sandbox_child(struct ssh_sandbox *box) +{ + /* Nothing to do here */ +} + +void +ssh_sandbox_parent_finish(struct ssh_sandbox *box) +{ + free(box); +} + +void +ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) +{ + /* Nothing to do here */ +} + +#endif /* SANDBOX_NULL */ diff --git a/crypto/external/bsd/openssh/dist/sandbox-seccomp-filter.c b/crypto/external/bsd/openssh/dist/sandbox-seccomp-filter.c new file mode 100644 index 000000000..2462bcc88 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/sandbox-seccomp-filter.c @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2012 Will Drewry + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Uncomment the SANDBOX_SECCOMP_FILTER_DEBUG macro below to help diagnose + * filter breakage during development. *Do not* use this in production, + * as it relies on making library calls that are unsafe in signal context. + * + * Instead, live systems the auditctl(8) may be used to monitor failures. + * E.g. + * auditctl -a task,always -F uid= + */ +/* #define SANDBOX_SECCOMP_FILTER_DEBUG 1 */ + +/* XXX it should be possible to do logging via the log socket safely */ + +#ifdef SANDBOX_SECCOMP_FILTER_DEBUG +/* Use the kernel headers in case of an older toolchain. */ +# include +# define __have_siginfo_t 1 +# define __have_sigval_t 1 +# define __have_sigevent_t 1 +#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ + +#include "includes.h" + +#ifdef SANDBOX_SECCOMP_FILTER + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include /* for offsetof */ +#include +#include +#include +#include + +#include "log.h" +#include "ssh-sandbox.h" +#include "xmalloc.h" + +/* Linux seccomp_filter sandbox */ +#define SECCOMP_FILTER_FAIL SECCOMP_RET_KILL + +/* Use a signal handler to emit violations when debugging */ +#ifdef SANDBOX_SECCOMP_FILTER_DEBUG +# undef SECCOMP_FILTER_FAIL +# define SECCOMP_FILTER_FAIL SECCOMP_RET_TRAP +#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ + +/* Simple helpers to avoid manual errors (but larger BPF programs). */ +#define SC_DENY(_nr, _errno) \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \ + BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO|(_errno)) +#define SC_ALLOW(_nr) \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \ + BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW) +#define SC_ALLOW_ARG(_nr, _arg_nr, _arg_val) \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 4), \ + /* load first syscall argument */ \ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ + offsetof(struct seccomp_data, args[(_arg_nr)])), \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_arg_val), 0, 1), \ + BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), \ + /* reload syscall number; all rules expect it in accumulator */ \ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ + offsetof(struct seccomp_data, nr)) + +/* Syscall filtering set for preauth. */ +static const struct sock_filter preauth_insns[] = { + /* Ensure the syscall arch convention is as expected. */ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, + offsetof(struct seccomp_data, arch)), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SECCOMP_AUDIT_ARCH, 1, 0), + BPF_STMT(BPF_RET+BPF_K, SECCOMP_FILTER_FAIL), + /* Load the syscall number for checking. */ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, + offsetof(struct seccomp_data, nr)), + + /* Syscalls to non-fatally deny */ +#ifdef __NR_fstat + SC_DENY(fstat, EACCES), +#endif +#ifdef __NR_fstat64 + SC_DENY(fstat64, EACCES), +#endif +#ifdef __NR_open + SC_DENY(open, EACCES), +#endif +#ifdef __NR_openat + SC_DENY(openat, EACCES), +#endif +#ifdef __NR_newfstatat + SC_DENY(newfstatat, EACCES), +#endif +#ifdef __NR_stat + SC_DENY(stat, EACCES), +#endif +#ifdef __NR_stat64 + SC_DENY(stat64, EACCES), +#endif + + /* Syscalls to permit */ +#ifdef __NR_brk + SC_ALLOW(brk), +#endif +#ifdef __NR_clock_gettime + SC_ALLOW(clock_gettime), +#endif +#ifdef __NR_close + SC_ALLOW(close), +#endif +#ifdef __NR_exit + SC_ALLOW(exit), +#endif +#ifdef __NR_exit_group + SC_ALLOW(exit_group), +#endif +#ifdef __NR_getpgid + SC_ALLOW(getpgid), +#endif +#ifdef __NR_getpid + SC_ALLOW(getpid), +#endif +#ifdef __NR_gettimeofday + SC_ALLOW(gettimeofday), +#endif +#ifdef __NR_madvise + SC_ALLOW(madvise), +#endif +#ifdef __NR_mmap + SC_ALLOW(mmap), +#endif +#ifdef __NR_mmap2 + SC_ALLOW(mmap2), +#endif +#ifdef __NR_mremap + SC_ALLOW(mremap), +#endif +#ifdef __NR_munmap + SC_ALLOW(munmap), +#endif +#ifdef __NR__newselect + SC_ALLOW(_newselect), +#endif +#ifdef __NR_poll + SC_ALLOW(poll), +#endif +#ifdef __NR_pselect6 + SC_ALLOW(pselect6), +#endif +#ifdef __NR_read + SC_ALLOW(read), +#endif +#ifdef __NR_rt_sigprocmask + SC_ALLOW(rt_sigprocmask), +#endif +#ifdef __NR_select + SC_ALLOW(select), +#endif +#ifdef __NR_shutdown + SC_ALLOW(shutdown), +#endif +#ifdef __NR_sigprocmask + SC_ALLOW(sigprocmask), +#endif +#ifdef __NR_time + SC_ALLOW(time), +#endif +#ifdef __NR_write + SC_ALLOW(write), +#endif +#ifdef __NR_socketcall + SC_ALLOW_ARG(socketcall, 0, SYS_SHUTDOWN), +#endif + + /* Default deny */ + BPF_STMT(BPF_RET+BPF_K, SECCOMP_FILTER_FAIL), +}; + +static const struct sock_fprog preauth_program = { + .len = (unsigned short)(sizeof(preauth_insns)/sizeof(preauth_insns[0])), + .filter = (struct sock_filter *)preauth_insns, +}; + +struct ssh_sandbox { + pid_t child_pid; +}; + +struct ssh_sandbox * +ssh_sandbox_init(struct monitor *monitor) +{ + struct ssh_sandbox *box; + + /* + * Strictly, we don't need to maintain any state here but we need + * to return non-NULL to satisfy the API. + */ + debug3("%s: preparing seccomp filter sandbox", __func__); + box = xcalloc(1, sizeof(*box)); + box->child_pid = 0; + + return box; +} + +#ifdef SANDBOX_SECCOMP_FILTER_DEBUG +extern struct monitor *pmonitor; +void mm_log_handler(LogLevel level, const char *msg, void *ctx); + +static void +ssh_sandbox_violation(int signum, siginfo_t *info, void *void_context) +{ + char msg[256]; + + snprintf(msg, sizeof(msg), + "%s: unexpected system call (arch:0x%x,syscall:%d @ %p)", + __func__, info->si_arch, info->si_syscall, info->si_call_addr); + mm_log_handler(SYSLOG_LEVEL_FATAL, msg, pmonitor); + _exit(1); +} + +static void +ssh_sandbox_child_debugging(void) +{ + struct sigaction act; + sigset_t mask; + + debug3("%s: installing SIGSYS handler", __func__); + memset(&act, 0, sizeof(act)); + sigemptyset(&mask); + sigaddset(&mask, SIGSYS); + + act.sa_sigaction = &ssh_sandbox_violation; + act.sa_flags = SA_SIGINFO; + if (sigaction(SIGSYS, &act, NULL) == -1) + fatal("%s: sigaction(SIGSYS): %s", __func__, strerror(errno)); + if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1) + fatal("%s: sigprocmask(SIGSYS): %s", + __func__, strerror(errno)); +} +#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ + +void +ssh_sandbox_child(struct ssh_sandbox *box) +{ + struct rlimit rl_zero; + int nnp_failed = 0; + + /* Set rlimits for completeness if possible. */ + rl_zero.rlim_cur = rl_zero.rlim_max = 0; + if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1) + fatal("%s: setrlimit(RLIMIT_FSIZE, { 0, 0 }): %s", + __func__, strerror(errno)); + if (setrlimit(RLIMIT_NOFILE, &rl_zero) == -1) + fatal("%s: setrlimit(RLIMIT_NOFILE, { 0, 0 }): %s", + __func__, strerror(errno)); + if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1) + fatal("%s: setrlimit(RLIMIT_NPROC, { 0, 0 }): %s", + __func__, strerror(errno)); + +#ifdef SANDBOX_SECCOMP_FILTER_DEBUG + ssh_sandbox_child_debugging(); +#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ + + debug3("%s: setting PR_SET_NO_NEW_PRIVS", __func__); + if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) { + debug("%s: prctl(PR_SET_NO_NEW_PRIVS): %s", + __func__, strerror(errno)); + nnp_failed = 1; + } + debug3("%s: attaching seccomp filter program", __func__); + if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &preauth_program) == -1) + debug("%s: prctl(PR_SET_SECCOMP): %s", + __func__, strerror(errno)); + else if (nnp_failed) + fatal("%s: SECCOMP_MODE_FILTER activated but " + "PR_SET_NO_NEW_PRIVS failed", __func__); +} + +void +ssh_sandbox_parent_finish(struct ssh_sandbox *box) +{ + free(box); + debug3("%s: finished", __func__); +} + +void +ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) +{ + box->child_pid = child_pid; +} + +#endif /* SANDBOX_SECCOMP_FILTER */ diff --git a/crypto/external/bsd/openssh/dist/scard/.cvsignore b/crypto/external/bsd/openssh/dist/scard/.cvsignore new file mode 100644 index 000000000..5349d34ae --- /dev/null +++ b/crypto/external/bsd/openssh/dist/scard/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Ssh.bin diff --git a/crypto/external/bsd/openssh/dist/scp.0 b/crypto/external/bsd/openssh/dist/scp.0 new file mode 100644 index 000000000..8f41f6140 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/scp.0 @@ -0,0 +1,165 @@ +SCP(1) General Commands Manual SCP(1) + +NAME + scp M-bM-^@M-^S secure copy (remote file copy program) + +SYNOPSIS + scp [-12346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file] + [-l limit] [-o ssh_option] [-P port] [-S program] + [[user@]host1:]file1 ... [[user@]host2:]file2 + +DESCRIPTION + scp copies files between hosts on a network. It uses ssh(1) for data + transfer, and uses the same authentication and provides the same security + as ssh(1). scp will ask for passwords or passphrases if they are needed + for authentication. + + File names may contain a user and host specification to indicate that the + file is to be copied to/from that host. Local file names can be made + explicit using absolute or relative pathnames to avoid scp treating file + names containing M-bM-^@M-^X:M-bM-^@M-^Y as host specifiers. Copies between two remote hosts + are also permitted. + + The options are as follows: + + -1 Forces scp to use protocol 1. + + -2 Forces scp to use protocol 2. + + -3 Copies between two remote hosts are transferred through the local + host. Without this option the data is copied directly between + the two remote hosts. Note that this option disables the + progress meter. + + -4 Forces scp to use IPv4 addresses only. + + -6 Forces scp to use IPv6 addresses only. + + -B Selects batch mode (prevents asking for passwords or + passphrases). + + -C Compression enable. Passes the -C flag to ssh(1) to enable + compression. + + -c cipher + Selects the cipher to use for encrypting the data transfer. This + option is directly passed to ssh(1). + + -F ssh_config + Specifies an alternative per-user configuration file for ssh. + This option is directly passed to ssh(1). + + -i identity_file + Selects the file from which the identity (private key) for public + key authentication is read. This option is directly passed to + ssh(1). + + -l limit + Limits the used bandwidth, specified in Kbit/s. + + -o ssh_option + Can be used to pass options to ssh in the format used in + ssh_config(5). This is useful for specifying options for which + there is no separate scp command-line flag. For full details of + the options listed below, and their possible values, see + ssh_config(5). + + AddressFamily + BatchMode + BindAddress + CanonicalDomains + CanonicalizeFallbackLocal + CanonicalizeHostname + CanonicalizeMaxDots + CanonicalizePermittedCNAMEs + ChallengeResponseAuthentication + CheckHostIP + Cipher + Ciphers + Compression + CompressionLevel + ConnectionAttempts + ConnectTimeout + ControlMaster + ControlPath + ControlPersist + GlobalKnownHostsFile + GSSAPIAuthentication + GSSAPIDelegateCredentials + HashKnownHosts + Host + HostbasedAuthentication + HostbasedKeyTypes + HostKeyAlgorithms + HostKeyAlias + HostName + IdentityFile + IdentitiesOnly + IPQoS + KbdInteractiveAuthentication + KbdInteractiveDevices + KexAlgorithms + LogLevel + MACs + NoHostAuthenticationForLocalhost + NumberOfPasswordPrompts + PasswordAuthentication + PKCS11Provider + Port + PreferredAuthentications + Protocol + ProxyCommand + PubkeyAcceptedKeyTypes + PubkeyAuthentication + RekeyLimit + RhostsRSAAuthentication + RSAAuthentication + SendEnv + ServerAliveInterval + ServerAliveCountMax + StrictHostKeyChecking + TCPKeepAlive + UpdateHostKeys + UsePrivilegedPort + User + UserKnownHostsFile + VerifyHostKeyDNS + + -P port + Specifies the port to connect to on the remote host. Note that + this option is written with a capital M-bM-^@M-^XPM-bM-^@M-^Y, because -p is already + reserved for preserving the times and modes of the file. + + -p Preserves modification times, access times, and modes from the + original file. + + -q Quiet mode: disables the progress meter as well as warning and + diagnostic messages from ssh(1). + + -r Recursively copy entire directories. Note that scp follows + symbolic links encountered in the tree traversal. + + -S program + Name of program to use for the encrypted connection. The program + must understand ssh(1) options. + + -v Verbose mode. Causes scp and ssh(1) to print debugging messages + about their progress. This is helpful in debugging connection, + authentication, and configuration problems. + +EXIT STATUS + The scp utility exitsM-BM- 0 on success, andM-BM- >0 if an error occurs. + +SEE ALSO + sftp(1), ssh(1), ssh-add(1), ssh-agent(1), ssh-keygen(1), ssh_config(5), + sshd(8) + +HISTORY + scp is based on the rcp program in BSD source code from the Regents of + the University of California. + +AUTHORS + Timo Rinne + Tatu Ylonen + +OpenBSD 5.8 July 10, 2015 OpenBSD 5.8 diff --git a/crypto/external/bsd/openssh/dist/sftp-server.0 b/crypto/external/bsd/openssh/dist/sftp-server.0 new file mode 100644 index 000000000..b971cef40 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/sftp-server.0 @@ -0,0 +1,96 @@ +SFTP-SERVER(8) System Manager's Manual SFTP-SERVER(8) + +NAME + sftp-server M-bM-^@M-^S SFTP server subsystem + +SYNOPSIS + sftp-server [-ehR] [-d start_directory] [-f log_facility] [-l log_level] + [-P blacklisted_requests] [-p whitelisted_requests] + [-u umask] + sftp-server -Q protocol_feature + +DESCRIPTION + sftp-server is a program that speaks the server side of SFTP protocol to + stdout and expects client requests from stdin. sftp-server is not + intended to be called directly, but from sshd(8) using the Subsystem + option. + + Command-line flags to sftp-server should be specified in the Subsystem + declaration. See sshd_config(5) for more information. + + Valid options are: + + -d start_directory + specifies an alternate starting directory for users. The + pathname may contain the following tokens that are expanded at + runtime: %% is replaced by a literal '%', %d is replaced by the + home directory of the user being authenticated, and %u is + replaced by the username of that user. The default is to use the + user's home directory. This option is useful in conjunction with + the sshd_config(5) ChrootDirectory option. + + -e Causes sftp-server to print logging information to stderr instead + of syslog for debugging. + + -f log_facility + Specifies the facility code that is used when logging messages + from sftp-server. The possible values are: DAEMON, USER, AUTH, + LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. + The default is AUTH. + + -h Displays sftp-server usage information. + + -l log_level + Specifies which messages will be logged by sftp-server. The + possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, + DEBUG1, DEBUG2, and DEBUG3. INFO and VERBOSE log transactions + that sftp-server performs on behalf of the client. DEBUG and + DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify higher + levels of debugging output. The default is ERROR. + + -P blacklisted_requests + Specify a comma-separated list of SFTP protocol requests that are + banned by the server. sftp-server will reply to any blacklisted + request with a failure. The -Q flag can be used to determine the + supported request types. If both a blacklist and a whitelist are + specified, then the blacklist is applied before the whitelist. + + -p whitelisted_requests + Specify a comma-separated list of SFTP protocol requests that are + permitted by the server. All request types that are not on the + whitelist will be logged and replied to with a failure message. + + Care must be taken when using this feature to ensure that + requests made implicitly by SFTP clients are permitted. + + -Q protocol_feature + Query protocol features supported by sftp-server. At present the + only feature that may be queried is M-bM-^@M-^\requestsM-bM-^@M-^], which may be used + for black or whitelisting (flags -P and -p respectively). + + -R Places this instance of sftp-server into a read-only mode. + Attempts to open files for writing, as well as other operations + that change the state of the filesystem, will be denied. + + -u umask + Sets an explicit umask(2) to be applied to newly-created files + and directories, instead of the user's default mask. + + On some systems, sftp-server must be able to access /dev/log for logging + to work, and use of sftp-server in a chroot configuration therefore + requires that syslogd(8) establish a logging socket inside the chroot + directory. + +SEE ALSO + sftp(1), ssh(1), sshd_config(5), sshd(8) + + T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh- + filexfer-02.txt, October 2001, work in progress material. + +HISTORY + sftp-server first appeared in OpenBSD 2.8. + +AUTHORS + Markus Friedl + +OpenBSD 5.8 December 11, 2014 OpenBSD 5.8 diff --git a/crypto/external/bsd/openssh/dist/sftp.0 b/crypto/external/bsd/openssh/dist/sftp.0 new file mode 100644 index 000000000..550f27648 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/sftp.0 @@ -0,0 +1,383 @@ +SFTP(1) General Commands Manual SFTP(1) + +NAME + sftp M-bM-^@M-^S secure file transfer program + +SYNOPSIS + sftp [-1246aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher] + [-D sftp_server_path] [-F ssh_config] [-i identity_file] [-l limit] + [-o ssh_option] [-P port] [-R num_requests] [-S program] + [-s subsystem | sftp_server] host + sftp [user@]host[:file ...] + sftp [user@]host[:dir[/]] + sftp -b batchfile [user@]host + +DESCRIPTION + sftp is an interactive file transfer program, similar to ftp(1), which + performs all operations over an encrypted ssh(1) transport. It may also + use many features of ssh, such as public key authentication and + compression. sftp connects and logs into the specified host, then enters + an interactive command mode. + + The second usage format will retrieve files automatically if a non- + interactive authentication method is used; otherwise it will do so after + successful interactive authentication. + + The third usage format allows sftp to start in a remote directory. + + The final usage format allows for automated sessions using the -b option. + In such cases, it is necessary to configure non-interactive + authentication to obviate the need to enter a password at connection time + (see sshd(8) and ssh-keygen(1) for details). + + Since some usage formats use colon characters to delimit host names from + path names, IPv6 addresses must be enclosed in square brackets to avoid + ambiguity. + + The options are as follows: + + -1 Specify the use of protocol version 1. + + -2 Specify the use of protocol version 2. + + -4 Forces sftp to use IPv4 addresses only. + + -6 Forces sftp to use IPv6 addresses only. + + -a Attempt to continue interrupted transfers rather than overwriting + existing partial or complete copies of files. If the partial + contents differ from those being transferred, then the resultant + file is likely to be corrupt. + + -B buffer_size + Specify the size of the buffer that sftp uses when transferring + files. Larger buffers require fewer round trips at the cost of + higher memory consumption. The default is 32768 bytes. + + -b batchfile + Batch mode reads a series of commands from an input batchfile + instead of stdin. Since it lacks user interaction it should be + used in conjunction with non-interactive authentication. A + batchfile of M-bM-^@M-^X-M-bM-^@M-^Y may be used to indicate standard input. sftp + will abort if any of the following commands fail: get, put, + reget, reput, rename, ln, rm, mkdir, chdir, ls, lchdir, chmod, + chown, chgrp, lpwd, df, symlink, and lmkdir. Termination on + error can be suppressed on a command by command basis by + prefixing the command with a M-bM-^@M-^X-M-bM-^@M-^Y character (for example, -rm + /tmp/blah*). + + -C Enables compression (via ssh's -C flag). + + -c cipher + Selects the cipher to use for encrypting the data transfers. + This option is directly passed to ssh(1). + + -D sftp_server_path + Connect directly to a local sftp server (rather than via ssh(1)). + This option may be useful in debugging the client and server. + + -F ssh_config + Specifies an alternative per-user configuration file for ssh(1). + This option is directly passed to ssh(1). + + -f Requests that files be flushed to disk immediately after + transfer. When uploading files, this feature is only enabled if + the server implements the "fsync@openssh.com" extension. + + -i identity_file + Selects the file from which the identity (private key) for public + key authentication is read. This option is directly passed to + ssh(1). + + -l limit + Limits the used bandwidth, specified in Kbit/s. + + -o ssh_option + Can be used to pass options to ssh in the format used in + ssh_config(5). This is useful for specifying options for which + there is no separate sftp command-line flag. For example, to + specify an alternate port use: sftp -oPort=24. For full details + of the options listed below, and their possible values, see + ssh_config(5). + + AddressFamily + BatchMode + BindAddress + CanonicalDomains + CanonicalizeFallbackLocal + CanonicalizeHostname + CanonicalizeMaxDots + CanonicalizePermittedCNAMEs + ChallengeResponseAuthentication + CheckHostIP + Cipher + Ciphers + Compression + CompressionLevel + ConnectionAttempts + ConnectTimeout + ControlMaster + ControlPath + ControlPersist + GlobalKnownHostsFile + GSSAPIAuthentication + GSSAPIDelegateCredentials + HashKnownHosts + Host + HostbasedAuthentication + HostbasedKeyTypes + HostKeyAlgorithms + HostKeyAlias + HostName + IdentityFile + IdentitiesOnly + IPQoS + KbdInteractiveAuthentication + KbdInteractiveDevices + KexAlgorithms + LogLevel + MACs + NoHostAuthenticationForLocalhost + NumberOfPasswordPrompts + PasswordAuthentication + PKCS11Provider + Port + PreferredAuthentications + Protocol + ProxyCommand + PubkeyAuthentication + RekeyLimit + RhostsRSAAuthentication + RSAAuthentication + SendEnv + ServerAliveInterval + ServerAliveCountMax + StrictHostKeyChecking + TCPKeepAlive + UpdateHostKeys + UsePrivilegedPort + User + UserKnownHostsFile + VerifyHostKeyDNS + + -P port + Specifies the port to connect to on the remote host. + + -p Preserves modification times, access times, and modes from the + original files transferred. + + -q Quiet mode: disables the progress meter as well as warning and + diagnostic messages from ssh(1). + + -R num_requests + Specify how many requests may be outstanding at any one time. + Increasing this may slightly improve file transfer speed but will + increase memory usage. The default is 64 outstanding requests. + + -r Recursively copy entire directories when uploading and + downloading. Note that sftp does not follow symbolic links + encountered in the tree traversal. + + -S program + Name of the program to use for the encrypted connection. The + program must understand ssh(1) options. + + -s subsystem | sftp_server + Specifies the SSH2 subsystem or the path for an sftp server on + the remote host. A path is useful for using sftp over protocol + version 1, or when the remote sshd(8) does not have an sftp + subsystem configured. + + -v Raise logging level. This option is also passed to ssh. + +INTERACTIVE COMMANDS + Once in interactive mode, sftp understands a set of commands similar to + those of ftp(1). Commands are case insensitive. Pathnames that contain + spaces must be enclosed in quotes. Any special characters contained + within pathnames that are recognized by glob(3) must be escaped with + backslashes (M-bM-^@M-^X\M-bM-^@M-^Y). + + bye Quit sftp. + + cd path + Change remote directory to path. + + chgrp grp path + Change group of file path to grp. path may contain glob(3) + characters and may match multiple files. grp must be a numeric + GID. + + chmod mode path + Change permissions of file path to mode. path may contain + glob(3) characters and may match multiple files. + + chown own path + Change owner of file path to own. path may contain glob(3) + characters and may match multiple files. own must be a numeric + UID. + + df [-hi] [path] + Display usage information for the filesystem holding the current + directory (or path if specified). If the -h flag is specified, + the capacity information will be displayed using "human-readable" + suffixes. The -i flag requests display of inode information in + addition to capacity information. This command is only supported + on servers that implement the M-bM-^@M-^\statvfs@openssh.comM-bM-^@M-^] extension. + + exit Quit sftp. + + get [-afPpr] remote-path [local-path] + Retrieve the remote-path and store it on the local machine. If + the local path name is not specified, it is given the same name + it has on the remote machine. remote-path may contain glob(3) + characters and may match multiple files. If it does and + local-path is specified, then local-path must specify a + directory. + + If the -a flag is specified, then attempt to resume partial + transfers of existing files. Note that resumption assumes that + any partial copy of the local file matches the remote copy. If + the remote file contents differ from the partial local copy then + the resultant file is likely to be corrupt. + + If the -f flag is specified, then fsync(2) will be called after + the file transfer has completed to flush the file to disk. + + If either the -P or -p flag is specified, then full file + permissions and access times are copied too. + + If the -r flag is specified then directories will be copied + recursively. Note that sftp does not follow symbolic links when + performing recursive transfers. + + help Display help text. + + lcd path + Change local directory to path. + + lls [ls-options [path]] + Display local directory listing of either path or current + directory if path is not specified. ls-options may contain any + flags supported by the local system's ls(1) command. path may + contain glob(3) characters and may match multiple files. + + lmkdir path + Create local directory specified by path. + + ln [-s] oldpath newpath + Create a link from oldpath to newpath. If the -s flag is + specified the created link is a symbolic link, otherwise it is a + hard link. + + lpwd Print local working directory. + + ls [-1afhlnrSt] [path] + Display a remote directory listing of either path or the current + directory if path is not specified. path may contain glob(3) + characters and may match multiple files. + + The following flags are recognized and alter the behaviour of ls + accordingly: + + -1 Produce single columnar output. + + -a List files beginning with a dot (M-bM-^@M-^X.M-bM-^@M-^Y). + + -f Do not sort the listing. The default sort order is + lexicographical. + + -h When used with a long format option, use unit suffixes: + Byte, Kilobyte, Megabyte, Gigabyte, Terabyte, Petabyte, + and Exabyte in order to reduce the number of digits to + four or fewer using powers of 2 for sizes (K=1024, + M=1048576, etc.). + + -l Display additional details including permissions and + ownership information. + + -n Produce a long listing with user and group information + presented numerically. + + -r Reverse the sort order of the listing. + + -S Sort the listing by file size. + + -t Sort the listing by last modification time. + + lumask umask + Set local umask to umask. + + mkdir path + Create remote directory specified by path. + + progress + Toggle display of progress meter. + + put [-afPpr] local-path [remote-path] + Upload local-path and store it on the remote machine. If the + remote path name is not specified, it is given the same name it + has on the local machine. local-path may contain glob(3) + characters and may match multiple files. If it does and + remote-path is specified, then remote-path must specify a + directory. + + If the -a flag is specified, then attempt to resume partial + transfers of existing files. Note that resumption assumes that + any partial copy of the remote file matches the local copy. If + the local file contents differ from the remote local copy then + the resultant file is likely to be corrupt. + + If the -f flag is specified, then a request will be sent to the + server to call fsync(2) after the file has been transferred. + Note that this is only supported by servers that implement the + "fsync@openssh.com" extension. + + If either the -P or -p flag is specified, then full file + permissions and access times are copied too. + + If the -r flag is specified then directories will be copied + recursively. Note that sftp does not follow symbolic links when + performing recursive transfers. + + pwd Display remote working directory. + + quit Quit sftp. + + reget [-Ppr] remote-path [local-path] + Resume download of remote-path. Equivalent to get with the -a + flag set. + + reput [-Ppr] [local-path] remote-path + Resume upload of [local-path]. Equivalent to put with the -a + flag set. + + rename oldpath newpath + Rename remote file from oldpath to newpath. + + rm path + Delete remote file specified by path. + + rmdir path + Remove remote directory specified by path. + + symlink oldpath newpath + Create a symbolic link from oldpath to newpath. + + version + Display the sftp protocol version. + + !command + Execute command in local shell. + + ! Escape to local shell. + + ? Synonym for help. + +SEE ALSO + ftp(1), ls(1), scp(1), ssh(1), ssh-add(1), ssh-keygen(1), glob(3), + ssh_config(5), sftp-server(8), sshd(8) + + T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh- + filexfer-00.txt, January 2001, work in progress material. + +OpenBSD 5.8 January 30, 2015 OpenBSD 5.8 diff --git a/crypto/external/bsd/openssh/dist/ssh-add.0 b/crypto/external/bsd/openssh/dist/ssh-add.0 new file mode 100644 index 000000000..29db710ab --- /dev/null +++ b/crypto/external/bsd/openssh/dist/ssh-add.0 @@ -0,0 +1,129 @@ +SSH-ADD(1) General Commands Manual SSH-ADD(1) + +NAME + ssh-add M-bM-^@M-^S adds private key identities to the authentication agent + +SYNOPSIS + ssh-add [-cDdkLlXx] [-E fingerprint_hash] [-t life] [file ...] + ssh-add -s pkcs11 + ssh-add -e pkcs11 + +DESCRIPTION + ssh-add adds private key identities to the authentication agent, + ssh-agent(1). When run without arguments, it adds the files + ~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 and + ~/.ssh/identity. After loading a private key, ssh-add will try to load + corresponding certificate information from the filename obtained by + appending -cert.pub to the name of the private key file. Alternative + file names can be given on the command line. + + If any file requires a passphrase, ssh-add asks for the passphrase from + the user. The passphrase is read from the user's tty. ssh-add retries + the last passphrase if multiple identity files are given. + + The authentication agent must be running and the SSH_AUTH_SOCK + environment variable must contain the name of its socket for ssh-add to + work. + + The options are as follows: + + -c Indicates that added identities should be subject to confirmation + before being used for authentication. Confirmation is performed + by ssh-askpass(1). Successful confirmation is signaled by a zero + exit status from ssh-askpass(1), rather than text entered into + the requester. + + -D Deletes all identities from the agent. + + -d Instead of adding identities, removes identities from the agent. + If ssh-add has been run without arguments, the keys for the + default identities and their corresponding certificates will be + removed. Otherwise, the argument list will be interpreted as a + list of paths to public key files to specify keys and + certificates to be removed from the agent. If no public key is + found at a given path, ssh-add will append .pub and retry. + + -E fingerprint_hash + Specifies the hash algorithm used when displaying key + fingerprints. Valid options are: M-bM-^@M-^\md5M-bM-^@M-^] and M-bM-^@M-^\sha256M-bM-^@M-^]. The + default is M-bM-^@M-^\sha256M-bM-^@M-^]. + + -e pkcs11 + Remove keys provided by the PKCS#11 shared library pkcs11. + + -k When loading keys into or deleting keys from the agent, process + plain private keys only and skip certificates. + + -L Lists public key parameters of all identities currently + represented by the agent. + + -l Lists fingerprints of all identities currently represented by the + agent. + + -s pkcs11 + Add keys provided by the PKCS#11 shared library pkcs11. + + -t life + Set a maximum lifetime when adding identities to an agent. The + lifetime may be specified in seconds or in a time format + specified in sshd_config(5). + + -X Unlock the agent. + + -x Lock the agent with a password. + +ENVIRONMENT + DISPLAY and SSH_ASKPASS + If ssh-add needs a passphrase, it will read the passphrase from + the current terminal if it was run from a terminal. If ssh-add + does not have a terminal associated with it but DISPLAY and + SSH_ASKPASS are set, it will execute the program specified by + SSH_ASKPASS (by default M-bM-^@M-^\ssh-askpassM-bM-^@M-^]) and open an X11 window to + read the passphrase. This is particularly useful when calling + ssh-add from a .xsession or related script. (Note that on some + machines it may be necessary to redirect the input from /dev/null + to make this work.) + + SSH_AUTH_SOCK + Identifies the path of a UNIX-domain socket used to communicate + with the agent. + +FILES + ~/.ssh/identity + Contains the protocol version 1 RSA authentication identity of + the user. + + ~/.ssh/id_dsa + Contains the protocol version 2 DSA authentication identity of + the user. + + ~/.ssh/id_ecdsa + Contains the protocol version 2 ECDSA authentication identity of + the user. + + ~/.ssh/id_ed25519 + Contains the protocol version 2 Ed25519 authentication identity + of the user. + + ~/.ssh/id_rsa + Contains the protocol version 2 RSA authentication identity of + the user. + + Identity files should not be readable by anyone but the user. Note that + ssh-add ignores identity files if they are accessible by others. + +EXIT STATUS + Exit status is 0 on success, 1 if the specified command fails, and 2 if + ssh-add is unable to contact the authentication agent. + +SEE ALSO + ssh(1), ssh-agent(1), ssh-askpass(1), ssh-keygen(1), sshd(8) + +AUTHORS + OpenSSH is a derivative of the original and free ssh 1.2.12 release by + Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo + de Raadt and Dug Song removed many bugs, re-added newer features and + created OpenSSH. Markus Friedl contributed the support for SSH protocol + versions 1.5 and 2.0. + +OpenBSD 5.8 March 30, 2015 OpenBSD 5.8 diff --git a/crypto/external/bsd/openssh/dist/ssh-keygen.0 b/crypto/external/bsd/openssh/dist/ssh-keygen.0 new file mode 100644 index 000000000..07a45b36b --- /dev/null +++ b/crypto/external/bsd/openssh/dist/ssh-keygen.0 @@ -0,0 +1,566 @@ +SSH-KEYGEN(1) General Commands Manual SSH-KEYGEN(1) + +NAME + ssh-keygen M-bM-^@M-^S authentication key generation, management and conversion + +SYNOPSIS + ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa | rsa1] + [-N new_passphrase] [-C comment] [-f output_keyfile] + ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile] + ssh-keygen -i [-m key_format] [-f input_keyfile] + ssh-keygen -e [-m key_format] [-f input_keyfile] + ssh-keygen -y [-f input_keyfile] + ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile] + ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile] + ssh-keygen -B [-f input_keyfile] + ssh-keygen -D pkcs11 + ssh-keygen -F hostname [-f known_hosts_file] [-l] + ssh-keygen -H [-f known_hosts_file] + ssh-keygen -R hostname [-f known_hosts_file] + ssh-keygen -r hostname [-f input_keyfile] [-g] + ssh-keygen -G output_file [-v] [-b bits] [-M memory] [-S start_point] + ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines] + [-j start_line] [-K checkpt] [-W generator] + ssh-keygen -s ca_key -I certificate_identity [-h] [-n principals] + [-O option] [-V validity_interval] [-z serial_number] file ... + ssh-keygen -L [-f input_keyfile] + ssh-keygen -A + ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number] + file ... + ssh-keygen -Q -f krl_file file ... + +DESCRIPTION + ssh-keygen generates, manages and converts authentication keys for + ssh(1). ssh-keygen can create RSA keys for use by SSH protocol version 1 + and DSA, ECDSA, Ed25519 or RSA keys for use by SSH protocol version 2. + The type of key to be generated is specified with the -t option. If + invoked without any arguments, ssh-keygen will generate an RSA key for + use in SSH protocol 2 connections. + + ssh-keygen is also used to generate groups for use in Diffie-Hellman + group exchange (DH-GEX). See the MODULI GENERATION section for details. + + Finally, ssh-keygen can be used to generate and update Key Revocation + Lists, and to test whether given keys have been revoked by one. See the + KEY REVOCATION LISTS section for details. + + Normally each user wishing to use SSH with public key authentication runs + this once to create the authentication key in ~/.ssh/identity, + ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 or ~/.ssh/id_rsa. + Additionally, the system administrator may use this to generate host + keys, as seen in /etc/rc. + + Normally this program generates the key and asks for a file in which to + store the private key. The public key is stored in a file with the same + name but M-bM-^@M-^\.pubM-bM-^@M-^] appended. The program also asks for a passphrase. The + passphrase may be empty to indicate no passphrase (host keys must have an + empty passphrase), or it may be a string of arbitrary length. A + passphrase is similar to a password, except it can be a phrase with a + series of words, punctuation, numbers, whitespace, or any string of + characters you want. Good passphrases are 10-30 characters long, are not + simple sentences or otherwise easily guessable (English prose has only + 1-2 bits of entropy per character, and provides very bad passphrases), + and contain a mix of upper and lowercase letters, numbers, and non- + alphanumeric characters. The passphrase can be changed later by using + the -p option. + + There is no way to recover a lost passphrase. If the passphrase is lost + or forgotten, a new key must be generated and the corresponding public + key copied to other machines. + + For RSA1 keys, there is also a comment field in the key file that is only + for convenience to the user to help identify the key. The comment can + tell what the key is for, or whatever is useful. The comment is + initialized to M-bM-^@M-^\user@hostM-bM-^@M-^] when the key is created, but can be changed + using the -c option. + + After a key is generated, instructions below detail where the keys should + be placed to be activated. + + The options are as follows: + + -A For each of the key types (rsa1, rsa, dsa, ecdsa and ed25519) for + which host keys do not exist, generate the host keys with the + default key file path, an empty passphrase, default bits for the + key type, and default comment. This is used by /etc/rc to + generate new host keys. + + -a rounds + When saving a new-format private key (i.e. an ed25519 key or any + SSH protocol 2 key when the -o flag is set), this option + specifies the number of KDF (key derivation function) rounds + used. Higher numbers result in slower passphrase verification + and increased resistance to brute-force password cracking (should + the keys be stolen). + + When screening DH-GEX candidates ( using the -T command). This + option specifies the number of primality tests to perform. + + -B Show the bubblebabble digest of specified private or public key + file. + + -b bits + Specifies the number of bits in the key to create. For RSA keys, + the minimum size is 1024 bits and the default is 2048 bits. + Generally, 2048 bits is considered sufficient. DSA keys must be + exactly 1024 bits as specified by FIPS 186-2. For ECDSA keys, + the -b flag determines the key length by selecting from one of + three elliptic curve sizes: 256, 384 or 521 bits. Attempting to + use bit lengths other than these three values for ECDSA keys will + fail. Ed25519 keys have a fixed length and the -b flag will be + ignored. + + -C comment + Provides a new comment. + + -c Requests changing the comment in the private and public key + files. This operation is only supported for RSA1 keys. The + program will prompt for the file containing the private keys, for + the passphrase if the key has one, and for the new comment. + + -D pkcs11 + Download the RSA public keys provided by the PKCS#11 shared + library pkcs11. When used in combination with -s, this option + indicates that a CA key resides in a PKCS#11 token (see the + CERTIFICATES section for details). + + -E fingerprint_hash + Specifies the hash algorithm used when displaying key + fingerprints. Valid options are: M-bM-^@M-^\md5M-bM-^@M-^] and M-bM-^@M-^\sha256M-bM-^@M-^]. The + default is M-bM-^@M-^\sha256M-bM-^@M-^]. + + -e This option will read a private or public OpenSSH key file and + print to stdout the key in one of the formats specified by the -m + option. The default export format is M-bM-^@M-^\RFC4716M-bM-^@M-^]. This option + allows exporting OpenSSH keys for use by other programs, + including several commercial SSH implementations. + + -F hostname + Search for the specified hostname in a known_hosts file, listing + any occurrences found. This option is useful to find hashed host + names or addresses and may also be used in conjunction with the + -H option to print found keys in a hashed format. + + -f filename + Specifies the filename of the key file. + + -G output_file + Generate candidate primes for DH-GEX. These primes must be + screened for safety (using the -T option) before use. + + -g Use generic DNS format when printing fingerprint resource records + using the -r command. + + -H Hash a known_hosts file. This replaces all hostnames and + addresses with hashed representations within the specified file; + the original content is moved to a file with a .old suffix. + These hashes may be used normally by ssh and sshd, but they do + not reveal identifying information should the file's contents be + disclosed. This option will not modify existing hashed hostnames + and is therefore safe to use on files that mix hashed and non- + hashed names. + + -h When signing a key, create a host certificate instead of a user + certificate. Please see the CERTIFICATES section for details. + + -I certificate_identity + Specify the key identity when signing a public key. Please see + the CERTIFICATES section for details. + + -i This option will read an unencrypted private (or public) key file + in the format specified by the -m option and print an OpenSSH + compatible private (or public) key to stdout. This option allows + importing keys from other software, including several commercial + SSH implementations. The default import format is M-bM-^@M-^\RFC4716M-bM-^@M-^]. + + -J num_lines + Exit after screening the specified number of lines while + performing DH candidate screening using the -T option. + + -j start_line + Start screening at the specified line number while performing DH + candidate screening using the -T option. + + -K checkpt + Write the last line processed to the file checkpt while + performing DH candidate screening using the -T option. This will + be used to skip lines in the input file that have already been + processed if the job is restarted. + + -k Generate a KRL file. In this mode, ssh-keygen will generate a + KRL file at the location specified via the -f flag that revokes + every key or certificate presented on the command line. + Keys/certificates to be revoked may be specified by public key + file or using the format described in the KEY REVOCATION LISTS + section. + + -L Prints the contents of a certificate. + + -l Show fingerprint of specified public key file. Private RSA1 keys + are also supported. For RSA and DSA keys ssh-keygen tries to + find the matching public key file and prints its fingerprint. If + combined with -v, an ASCII art representation of the key is + supplied with the fingerprint. + + -M memory + Specify the amount of memory to use (in megabytes) when + generating candidate moduli for DH-GEX. + + -m key_format + Specify a key format for the -i (import) or -e (export) + conversion options. The supported key formats are: M-bM-^@M-^\RFC4716M-bM-^@M-^] + (RFC 4716/SSH2 public or private key), M-bM-^@M-^\PKCS8M-bM-^@M-^] (PEM PKCS8 public + key) or M-bM-^@M-^\PEMM-bM-^@M-^] (PEM public key). The default conversion format is + M-bM-^@M-^\RFC4716M-bM-^@M-^]. + + -N new_passphrase + Provides the new passphrase. + + -n principals + Specify one or more principals (user or host names) to be + included in a certificate when signing a key. Multiple + principals may be specified, separated by commas. Please see the + CERTIFICATES section for details. + + -O option + Specify a certificate option when signing a key. This option may + be specified multiple times. Please see the CERTIFICATES section + for details. The options that are valid for user certificates + are: + + clear Clear all enabled permissions. This is useful for + clearing the default set of permissions so permissions + may be added individually. + + force-command=command + Forces the execution of command instead of any shell or + command specified by the user when the certificate is + used for authentication. + + no-agent-forwarding + Disable ssh-agent(1) forwarding (permitted by default). + + no-port-forwarding + Disable port forwarding (permitted by default). + + no-pty Disable PTY allocation (permitted by default). + + no-user-rc + Disable execution of ~/.ssh/rc by sshd(8) (permitted by + default). + + no-x11-forwarding + Disable X11 forwarding (permitted by default). + + permit-agent-forwarding + Allows ssh-agent(1) forwarding. + + permit-port-forwarding + Allows port forwarding. + + permit-pty + Allows PTY allocation. + + permit-user-rc + Allows execution of ~/.ssh/rc by sshd(8). + + permit-x11-forwarding + Allows X11 forwarding. + + source-address=address_list + Restrict the source addresses from which the certificate + is considered valid. The address_list is a comma- + separated list of one or more address/netmask pairs in + CIDR format. + + At present, no options are valid for host keys. + + -o Causes ssh-keygen to save SSH protocol 2 private keys using the + new OpenSSH format rather than the more compatible PEM format. + The new format has increased resistance to brute-force password + cracking but is not supported by versions of OpenSSH prior to + 6.5. Ed25519 keys always use the new private key format. + + -P passphrase + Provides the (old) passphrase. + + -p Requests changing the passphrase of a private key file instead of + creating a new private key. The program will prompt for the file + containing the private key, for the old passphrase, and twice for + the new passphrase. + + -Q Test whether keys have been revoked in a KRL. + + -q Silence ssh-keygen. + + -R hostname + Removes all keys belonging to hostname from a known_hosts file. + This option is useful to delete hashed hosts (see the -H option + above). + + -r hostname + Print the SSHFP fingerprint resource record named hostname for + the specified public key file. + + -S start + Specify start point (in hex) when generating candidate moduli for + DH-GEX. + + -s ca_key + Certify (sign) a public key using the specified CA key. Please + see the CERTIFICATES section for details. + + When generating a KRL, -s specifies a path to a CA public key + file used to revoke certificates directly by key ID or serial + number. See the KEY REVOCATION LISTS section for details. + + -T output_file + Test DH group exchange candidate primes (generated using the -G + option) for safety. + + -t dsa | ecdsa | ed25519 | rsa | rsa1 + Specifies the type of key to create. The possible values are + M-bM-^@M-^\rsa1M-bM-^@M-^] for protocol version 1 and M-bM-^@M-^\dsaM-bM-^@M-^], M-bM-^@M-^\ecdsaM-bM-^@M-^], M-bM-^@M-^\ed25519M-bM-^@M-^], or + M-bM-^@M-^\rsaM-bM-^@M-^] for protocol version 2. + + -u Update a KRL. When specified with -k, keys listed via the + command line are added to the existing KRL rather than a new KRL + being created. + + -V validity_interval + Specify a validity interval when signing a certificate. A + validity interval may consist of a single time, indicating that + the certificate is valid beginning now and expiring at that time, + or may consist of two times separated by a colon to indicate an + explicit time interval. The start time may be specified as a + date in YYYYMMDD format, a time in YYYYMMDDHHMMSS format or a + relative time (to the current time) consisting of a minus sign + followed by a relative time in the format described in the TIME + FORMATS section of sshd_config(5). The end time may be specified + as a YYYYMMDD date, a YYYYMMDDHHMMSS time or a relative time + starting with a plus character. + + For example: M-bM-^@M-^\+52w1dM-bM-^@M-^] (valid from now to 52 weeks and one day + from now), M-bM-^@M-^\-4w:+4wM-bM-^@M-^] (valid from four weeks ago to four weeks + from now), M-bM-^@M-^\20100101123000:20110101123000M-bM-^@M-^] (valid from 12:30 PM, + January 1st, 2010 to 12:30 PM, January 1st, 2011), M-bM-^@M-^\-1d:20110101M-bM-^@M-^] + (valid from yesterday to midnight, January 1st, 2011). + + -v Verbose mode. Causes ssh-keygen to print debugging messages + about its progress. This is helpful for debugging moduli + generation. Multiple -v options increase the verbosity. The + maximum is 3. + + -W generator + Specify desired generator when testing candidate moduli for DH- + GEX. + + -y This option will read a private OpenSSH format file and print an + OpenSSH public key to stdout. + + -z serial_number + Specifies a serial number to be embedded in the certificate to + distinguish this certificate from others from the same CA. The + default serial number is zero. + + When generating a KRL, the -z flag is used to specify a KRL + version number. + +MODULI GENERATION + ssh-keygen may be used to generate groups for the Diffie-Hellman Group + Exchange (DH-GEX) protocol. Generating these groups is a two-step + process: first, candidate primes are generated using a fast, but memory + intensive process. These candidate primes are then tested for + suitability (a CPU-intensive process). + + Generation of primes is performed using the -G option. The desired + length of the primes may be specified by the -b option. For example: + + # ssh-keygen -G moduli-2048.candidates -b 2048 + + By default, the search for primes begins at a random point in the desired + length range. This may be overridden using the -S option, which + specifies a different start point (in hex). + + Once a set of candidates have been generated, they must be screened for + suitability. This may be performed using the -T option. In this mode + ssh-keygen will read candidates from standard input (or a file specified + using the -f option). For example: + + # ssh-keygen -T moduli-2048 -f moduli-2048.candidates + + By default, each candidate will be subjected to 100 primality tests. + This may be overridden using the -a option. The DH generator value will + be chosen automatically for the prime under consideration. If a specific + generator is desired, it may be requested using the -W option. Valid + generator values are 2, 3, and 5. + + Screened DH groups may be installed in /etc/moduli. It is important that + this file contains moduli of a range of bit lengths and that both ends of + a connection share common moduli. + +CERTIFICATES + ssh-keygen supports signing of keys to produce certificates that may be + used for user or host authentication. Certificates consist of a public + key, some identity information, zero or more principal (user or host) + names and a set of options that are signed by a Certification Authority + (CA) key. Clients or servers may then trust only the CA key and verify + its signature on a certificate rather than trusting many user/host keys. + Note that OpenSSH certificates are a different, and much simpler, format + to the X.509 certificates used in ssl(8). + + ssh-keygen supports two types of certificates: user and host. User + certificates authenticate users to servers, whereas host certificates + authenticate server hosts to users. To generate a user certificate: + + $ ssh-keygen -s /path/to/ca_key -I key_id /path/to/user_key.pub + + The resultant certificate will be placed in /path/to/user_key-cert.pub. + A host certificate requires the -h option: + + $ ssh-keygen -s /path/to/ca_key -I key_id -h /path/to/host_key.pub + + The host certificate will be output to /path/to/host_key-cert.pub. + + It is possible to sign using a CA key stored in a PKCS#11 token by + providing the token library using -D and identifying the CA key by + providing its public half as an argument to -s: + + $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id user_key.pub + + In all cases, key_id is a "key identifier" that is logged by the server + when the certificate is used for authentication. + + Certificates may be limited to be valid for a set of principal + (user/host) names. By default, generated certificates are valid for all + users or hosts. To generate a certificate for a specified set of + principals: + + $ ssh-keygen -s ca_key -I key_id -n user1,user2 user_key.pub + $ ssh-keygen -s ca_key -I key_id -h -n host.domain host_key.pub + + Additional limitations on the validity and use of user certificates may + be specified through certificate options. A certificate option may + disable features of the SSH session, may be valid only when presented + from particular source addresses or may force the use of a specific + command. For a list of valid certificate options, see the documentation + for the -O option above. + + Finally, certificates may be defined with a validity lifetime. The -V + option allows specification of certificate start and end times. A + certificate that is presented at a time outside this range will not be + considered valid. By default, certificates are valid from UNIX Epoch to + the distant future. + + For certificates to be used for user or host authentication, the CA + public key must be trusted by sshd(8) or ssh(1). Please refer to those + manual pages for details. + +KEY REVOCATION LISTS + ssh-keygen is able to manage OpenSSH format Key Revocation Lists (KRLs). + These binary files specify keys or certificates to be revoked using a + compact format, taking as little as one bit per certificate if they are + being revoked by serial number. + + KRLs may be generated using the -k flag. This option reads one or more + files from the command line and generates a new KRL. The files may + either contain a KRL specification (see below) or public keys, listed one + per line. Plain public keys are revoked by listing their hash or + contents in the KRL and certificates revoked by serial number or key ID + (if the serial is zero or not available). + + Revoking keys using a KRL specification offers explicit control over the + types of record used to revoke keys and may be used to directly revoke + certificates by serial number or key ID without having the complete + original certificate on hand. A KRL specification consists of lines + containing one of the following directives followed by a colon and some + directive-specific information. + + serial: serial_number[-serial_number] + Revokes a certificate with the specified serial number. Serial + numbers are 64-bit values, not including zero and may be + expressed in decimal, hex or octal. If two serial numbers are + specified separated by a hyphen, then the range of serial numbers + including and between each is revoked. The CA key must have been + specified on the ssh-keygen command line using the -s option. + + id: key_id + Revokes a certificate with the specified key ID string. The CA + key must have been specified on the ssh-keygen command line using + the -s option. + + key: public_key + Revokes the specified key. If a certificate is listed, then it + is revoked as a plain public key. + + sha1: public_key + Revokes the specified key by its SHA1 hash. + + KRLs may be updated using the -u flag in addition to -k. When this + option is specified, keys listed via the command line are merged into the + KRL, adding to those already there. + + It is also possible, given a KRL, to test whether it revokes a particular + key (or keys). The -Q flag will query an existing KRL, testing each key + specified on the commandline. If any key listed on the command line has + been revoked (or an error encountered) then ssh-keygen will exit with a + non-zero exit status. A zero exit status will only be returned if no key + was revoked. + +FILES + ~/.ssh/identity + Contains the protocol version 1 RSA authentication identity of + the user. This file should not be readable by anyone but the + user. It is possible to specify a passphrase when generating the + key; that passphrase will be used to encrypt the private part of + this file using 3DES. This file is not automatically accessed by + ssh-keygen but it is offered as the default file for the private + key. ssh(1) will read this file when a login attempt is made. + + ~/.ssh/identity.pub + Contains the protocol version 1 RSA public key for + authentication. The contents of this file should be added to + ~/.ssh/authorized_keys on all machines where the user wishes to + log in using RSA authentication. There is no need to keep the + contents of this file secret. + + ~/.ssh/id_dsa + ~/.ssh/id_ecdsa + ~/.ssh/id_ed25519 + ~/.ssh/id_rsa + Contains the protocol version 2 DSA, ECDSA, Ed25519 or RSA + authentication identity of the user. This file should not be + readable by anyone but the user. It is possible to specify a + passphrase when generating the key; that passphrase will be used + to encrypt the private part of this file using 128-bit AES. This + file is not automatically accessed by ssh-keygen but it is + offered as the default file for the private key. ssh(1) will + read this file when a login attempt is made. + + ~/.ssh/id_dsa.pub + ~/.ssh/id_ecdsa.pub + ~/.ssh/id_ed25519.pub + ~/.ssh/id_rsa.pub + Contains the protocol version 2 DSA, ECDSA, Ed25519 or RSA public + key for authentication. The contents of this file should be + added to ~/.ssh/authorized_keys on all machines where the user + wishes to log in using public key authentication. There is no + need to keep the contents of this file secret. + + /etc/moduli + Contains Diffie-Hellman groups used for DH-GEX. The file format + is described in moduli(5). + +SEE ALSO + ssh(1), ssh-add(1), ssh-agent(1), moduli(5), sshd(8) + + The Secure Shell (SSH) Public Key File Format, RFC 4716, 2006. + +AUTHORS + OpenSSH is a derivative of the original and free ssh 1.2.12 release by + Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo + de Raadt and Dug Song removed many bugs, re-added newer features and + created OpenSSH. Markus Friedl contributed the support for SSH protocol + versions 1.5 and 2.0. + +OpenBSD 5.8 August 20, 2015 OpenBSD 5.8 diff --git a/crypto/external/bsd/openssh/dist/ssh-keyscan.0 b/crypto/external/bsd/openssh/dist/ssh-keyscan.0 new file mode 100644 index 000000000..500c1dd30 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/ssh-keyscan.0 @@ -0,0 +1,109 @@ +SSH-KEYSCAN(1) General Commands Manual SSH-KEYSCAN(1) + +NAME + ssh-keyscan M-bM-^@M-^S gather ssh public keys + +SYNOPSIS + ssh-keyscan [-46Hv] [-f file] [-p port] [-T timeout] [-t type] + [host | addrlist namelist] ... + +DESCRIPTION + ssh-keyscan is a utility for gathering the public ssh host keys of a + number of hosts. It was designed to aid in building and verifying + ssh_known_hosts files. ssh-keyscan provides a minimal interface suitable + for use by shell and perl scripts. + + ssh-keyscan uses non-blocking socket I/O to contact as many hosts as + possible in parallel, so it is very efficient. The keys from a domain of + 1,000 hosts can be collected in tens of seconds, even when some of those + hosts are down or do not run ssh. For scanning, one does not need login + access to the machines that are being scanned, nor does the scanning + process involve any encryption. + + The options are as follows: + + -4 Forces ssh-keyscan to use IPv4 addresses only. + + -6 Forces ssh-keyscan to use IPv6 addresses only. + + -f file + Read hosts or M-bM-^@M-^\addrlist namelistM-bM-^@M-^] pairs from file, one per line. + If - is supplied instead of a filename, ssh-keyscan will read + hosts or M-bM-^@M-^\addrlist namelistM-bM-^@M-^] pairs from the standard input. + + -H Hash all hostnames and addresses in the output. Hashed names may + be used normally by ssh and sshd, but they do not reveal + identifying information should the file's contents be disclosed. + + -p port + Port to connect to on the remote host. + + -T timeout + Set the timeout for connection attempts. If timeout seconds have + elapsed since a connection was initiated to a host or since the + last time anything was read from that host, then the connection + is closed and the host in question considered unavailable. + Default is 5 seconds. + + -t type + Specifies the type of the key to fetch from the scanned hosts. + The possible values are M-bM-^@M-^\rsa1M-bM-^@M-^] for protocol version 1 and M-bM-^@M-^\dsaM-bM-^@M-^], + M-bM-^@M-^\ecdsaM-bM-^@M-^], M-bM-^@M-^\ed25519M-bM-^@M-^], or M-bM-^@M-^\rsaM-bM-^@M-^] for protocol version 2. Multiple + values may be specified by separating them with commas. The + default is to fetch M-bM-^@M-^\rsaM-bM-^@M-^], M-bM-^@M-^\ecdsaM-bM-^@M-^], and M-bM-^@M-^\ed25519M-bM-^@M-^] keys. + + -v Verbose mode. Causes ssh-keyscan to print debugging messages + about its progress. + +SECURITY + If an ssh_known_hosts file is constructed using ssh-keyscan without + verifying the keys, users will be vulnerable to man in the middle + attacks. On the other hand, if the security model allows such a risk, + ssh-keyscan can help in the detection of tampered keyfiles or man in the + middle attacks which have begun after the ssh_known_hosts file was + created. + +FILES + Input format: + + 1.2.3.4,1.2.4.4 name.my.domain,name,n.my.domain,n,1.2.3.4,1.2.4.4 + + Output format for RSA1 keys: + + host-or-namelist bits exponent modulus + + Output format for RSA, DSA, ECDSA, and Ed25519 keys: + + host-or-namelist keytype base64-encoded-key + + Where keytype is either M-bM-^@M-^\ecdsa-sha2-nistp256M-bM-^@M-^], M-bM-^@M-^\ecdsa-sha2-nistp384M-bM-^@M-^], + M-bM-^@M-^\ecdsa-sha2-nistp521M-bM-^@M-^], M-bM-^@M-^\ssh-ed25519M-bM-^@M-^], M-bM-^@M-^\ssh-dssM-bM-^@M-^] or M-bM-^@M-^\ssh-rsaM-bM-^@M-^]. + + /etc/ssh/ssh_known_hosts + +EXAMPLES + Print the rsa host key for machine hostname: + + $ ssh-keyscan hostname + + Find all hosts from the file ssh_hosts which have new or different keys + from those in the sorted file ssh_known_hosts: + + $ ssh-keyscan -t rsa,dsa,ecdsa,ed25519 -f ssh_hosts | \ + sort -u - ssh_known_hosts | diff ssh_known_hosts - + +SEE ALSO + ssh(1), sshd(8) + +AUTHORS + David Mazieres wrote the initial version, and Wayne + Davison added support for protocol version + 2. + +BUGS + It generates "Connection closed by remote host" messages on the consoles + of all the machines it scans if the server is older than version 2.9. + This is because it opens a connection to the ssh port, reads the public + key, and drops the connection as soon as it gets the key. + +OpenBSD 5.8 August 30, 2014 OpenBSD 5.8 diff --git a/crypto/external/bsd/openssh/dist/ssh-pkcs11-helper.0 b/crypto/external/bsd/openssh/dist/ssh-pkcs11-helper.0 new file mode 100644 index 000000000..7fac805ff --- /dev/null +++ b/crypto/external/bsd/openssh/dist/ssh-pkcs11-helper.0 @@ -0,0 +1,25 @@ +SSH-PKCS11-HELPER(8) System Manager's Manual SSH-PKCS11-HELPER(8) + +NAME + ssh-pkcs11-helper M-bM-^@M-^S ssh-agent helper program for PKCS#11 support + +SYNOPSIS + ssh-pkcs11-helper + +DESCRIPTION + ssh-pkcs11-helper is used by ssh-agent(1) to access keys provided by a + PKCS#11 token. + + ssh-pkcs11-helper is not intended to be invoked by the user, but from + ssh-agent(1). + +SEE ALSO + ssh(1), ssh-add(1), ssh-agent(1) + +HISTORY + ssh-pkcs11-helper first appeared in OpenBSD 4.7. + +AUTHORS + Markus Friedl + +OpenBSD 5.8 July 16, 2013 OpenBSD 5.8 diff --git a/crypto/external/bsd/openssh/dist/ssh.0 b/crypto/external/bsd/openssh/dist/ssh.0 new file mode 100644 index 000000000..ad4817aff --- /dev/null +++ b/crypto/external/bsd/openssh/dist/ssh.0 @@ -0,0 +1,972 @@ +SSH(1) General Commands Manual SSH(1) + +NAME + ssh M-bM-^@M-^S OpenSSH SSH client (remote login program) + +SYNOPSIS + ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec] + [-D [bind_address:]port] [-E log_file] [-e escape_char] + [-F configfile] [-I pkcs11] [-i identity_file] [-L address] + [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] + [-Q cipher | cipher-auth | mac | kex | key | protocol-version] + [-R address] [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]] + [user@]hostname [command] + +DESCRIPTION + ssh (SSH client) is a program for logging into a remote machine and for + executing commands on a remote machine. It is intended to replace rlogin + and rsh, and provide secure encrypted communications between two + untrusted hosts over an insecure network. X11 connections, arbitrary TCP + ports and UNIX-domain sockets can also be forwarded over the secure + channel. + + ssh connects and logs into the specified hostname (with optional user + name). The user must prove his/her identity to the remote machine using + one of several methods depending on the protocol version used (see + below). + + If command is specified, it is executed on the remote host instead of a + login shell. + + The options are as follows: + + -1 Forces ssh to try protocol version 1 only. + + -2 Forces ssh to try protocol version 2 only. + + -4 Forces ssh to use IPv4 addresses only. + + -6 Forces ssh to use IPv6 addresses only. + + -A Enables forwarding of the authentication agent connection. This + can also be specified on a per-host basis in a configuration + file. + + Agent forwarding should be enabled with caution. Users with the + ability to bypass file permissions on the remote host (for the + agent's UNIX-domain socket) can access the local agent through + the forwarded connection. An attacker cannot obtain key material + from the agent, however they can perform operations on the keys + that enable them to authenticate using the identities loaded into + the agent. + + -a Disables forwarding of the authentication agent connection. + + -b bind_address + Use bind_address on the local machine as the source address of + the connection. Only useful on systems with more than one + address. + + -C Requests compression of all data (including stdin, stdout, + stderr, and data for forwarded X11, TCP and UNIX-domain + connections). The compression algorithm is the same used by + gzip(1), and the M-bM-^@M-^\levelM-bM-^@M-^] can be controlled by the + CompressionLevel option for protocol version 1. Compression is + desirable on modem lines and other slow connections, but will + only slow down things on fast networks. The default value can be + set on a host-by-host basis in the configuration files; see the + Compression option. + + -c cipher_spec + Selects the cipher specification for encrypting the session. + + Protocol version 1 allows specification of a single cipher. The + supported values are M-bM-^@M-^\3desM-bM-^@M-^], M-bM-^@M-^\blowfishM-bM-^@M-^], and M-bM-^@M-^\desM-bM-^@M-^]. For protocol + version 2, cipher_spec is a comma-separated list of ciphers + listed in order of preference. See the Ciphers keyword in + ssh_config(5) for more information. + + -D [bind_address:]port + Specifies a local M-bM-^@M-^\dynamicM-bM-^@M-^] application-level port forwarding. + This works by allocating a socket to listen to port on the local + side, optionally bound to the specified bind_address. Whenever a + connection is made to this port, the connection is forwarded over + the secure channel, and the application protocol is then used to + determine where to connect to from the remote machine. Currently + the SOCKS4 and SOCKS5 protocols are supported, and ssh will act + as a SOCKS server. Only root can forward privileged ports. + Dynamic port forwardings can also be specified in the + configuration file. + + IPv6 addresses can be specified by enclosing the address in + square brackets. Only the superuser can forward privileged + ports. By default, the local port is bound in accordance with + the GatewayPorts setting. However, an explicit bind_address may + be used to bind the connection to a specific address. The + bind_address of M-bM-^@M-^\localhostM-bM-^@M-^] indicates that the listening port be + bound for local use only, while an empty address or M-bM-^@M-^X*M-bM-^@M-^Y indicates + that the port should be available from all interfaces. + + -E log_file + Append debug logs to log_file instead of standard error. + + -e escape_char + Sets the escape character for sessions with a pty (default: M-bM-^@M-^X~M-bM-^@M-^Y). + The escape character is only recognized at the beginning of a + line. The escape character followed by a dot (M-bM-^@M-^X.M-bM-^@M-^Y) closes the + connection; followed by control-Z suspends the connection; and + followed by itself sends the escape character once. Setting the + character to M-bM-^@M-^\noneM-bM-^@M-^] disables any escapes and makes the session + fully transparent. + + -F configfile + Specifies an alternative per-user configuration file. If a + configuration file is given on the command line, the system-wide + configuration file (/etc/ssh/ssh_config) will be ignored. The + default for the per-user configuration file is ~/.ssh/config. + + -f Requests ssh to go to background just before command execution. + This is useful if ssh is going to ask for passwords or + passphrases, but the user wants it in the background. This + implies -n. The recommended way to start X11 programs at a + remote site is with something like ssh -f host xterm. + + If the ExitOnForwardFailure configuration option is set to M-bM-^@M-^\yesM-bM-^@M-^], + then a client started with -f will wait for all remote port + forwards to be successfully established before placing itself in + the background. + + -G Causes ssh to print its configuration after evaluating Host and + Match blocks and exit. + + -g Allows remote hosts to connect to local forwarded ports. If used + on a multiplexed connection, then this option must be specified + on the master process. + + -I pkcs11 + Specify the PKCS#11 shared library ssh should use to communicate + with a PKCS#11 token providing the user's private RSA key. + + -i identity_file + Selects a file from which the identity (private key) for public + key authentication is read. The default is ~/.ssh/identity for + protocol version 1, and ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, + ~/.ssh/id_ed25519 and ~/.ssh/id_rsa for protocol version 2. + Identity files may also be specified on a per-host basis in the + configuration file. It is possible to have multiple -i options + (and multiple identities specified in configuration files). ssh + will also try to load certificate information from the filename + obtained by appending -cert.pub to identity filenames. + + -K Enables GSSAPI-based authentication and forwarding (delegation) + of GSSAPI credentials to the server. + + -k Disables forwarding (delegation) of GSSAPI credentials to the + server. + + -L [bind_address:]port:host:hostport + -L [bind_address:]port:remote_socket + -L local_socket:host:hostport + -L local_socket:remote_socket + Specifies that connections to the given TCP port or Unix socket + on the local (client) host are to be forwarded to the given host + and port, or Unix socket, on the remote side. This works by + allocating a socket to listen to either a TCP port on the local + side, optionally bound to the specified bind_address, or to a + Unix socket. Whenever a connection is made to the local port or + socket, the connection is forwarded over the secure channel, and + a connection is made to either host port hostport, or the Unix + socket remote_socket, from the remote machine. + + Port forwardings can also be specified in the configuration file. + Only the superuser can forward privileged ports. IPv6 addresses + can be specified by enclosing the address in square brackets. + + By default, the local port is bound in accordance with the + GatewayPorts setting. However, an explicit bind_address may be + used to bind the connection to a specific address. The + bind_address of M-bM-^@M-^\localhostM-bM-^@M-^] indicates that the listening port be + bound for local use only, while an empty address or M-bM-^@M-^X*M-bM-^@M-^Y indicates + that the port should be available from all interfaces. + + -l login_name + Specifies the user to log in as on the remote machine. This also + may be specified on a per-host basis in the configuration file. + + -M Places the ssh client into M-bM-^@M-^\masterM-bM-^@M-^] mode for connection sharing. + Multiple -M options places ssh into M-bM-^@M-^\masterM-bM-^@M-^] mode with + confirmation required before slave connections are accepted. + Refer to the description of ControlMaster in ssh_config(5) for + details. + + -m mac_spec + Additionally, for protocol version 2 a comma-separated list of + MAC (message authentication code) algorithms can be specified in + order of preference. See the MACs keyword for more information. + + -N Do not execute a remote command. This is useful for just + forwarding ports (protocol version 2 only). + + -n Redirects stdin from /dev/null (actually, prevents reading from + stdin). This must be used when ssh is run in the background. A + common trick is to use this to run X11 programs on a remote + machine. For example, ssh -n shadows.cs.hut.fi emacs & will + start an emacs on shadows.cs.hut.fi, and the X11 connection will + be automatically forwarded over an encrypted channel. The ssh + program will be put in the background. (This does not work if + ssh needs to ask for a password or passphrase; see also the -f + option.) + + -O ctl_cmd + Control an active connection multiplexing master process. When + the -O option is specified, the ctl_cmd argument is interpreted + and passed to the master process. Valid commands are: M-bM-^@M-^\checkM-bM-^@M-^] + (check that the master process is running), M-bM-^@M-^\forwardM-bM-^@M-^] (request + forwardings without command execution), M-bM-^@M-^\cancelM-bM-^@M-^] (cancel + forwardings), M-bM-^@M-^\exitM-bM-^@M-^] (request the master to exit), and M-bM-^@M-^\stopM-bM-^@M-^] + (request the master to stop accepting further multiplexing + requests). + + -o option + Can be used to give options in the format used in the + configuration file. This is useful for specifying options for + which there is no separate command-line flag. For full details + of the options listed below, and their possible values, see + ssh_config(5). + + AddressFamily + BatchMode + BindAddress + CanonicalDomains + CanonicalizeFallbackLocal + CanonicalizeHostname + CanonicalizeMaxDots + CanonicalizePermittedCNAMEs + ChallengeResponseAuthentication + CheckHostIP + Cipher + Ciphers + ClearAllForwardings + Compression + CompressionLevel + ConnectionAttempts + ConnectTimeout + ControlMaster + ControlPath + ControlPersist + DynamicForward + EscapeChar + ExitOnForwardFailure + FingerprintHash + ForwardAgent + ForwardX11 + ForwardX11Timeout + ForwardX11Trusted + GatewayPorts + GlobalKnownHostsFile + GSSAPIAuthentication + GSSAPIDelegateCredentials + HashKnownHosts + Host + HostbasedAuthentication + HostbasedKeyTypes + HostKeyAlgorithms + HostKeyAlias + HostName + IdentityFile + IdentitiesOnly + IPQoS + KbdInteractiveAuthentication + KbdInteractiveDevices + KexAlgorithms + LocalCommand + LocalForward + LogLevel + MACs + Match + NoHostAuthenticationForLocalhost + NumberOfPasswordPrompts + PasswordAuthentication + PermitLocalCommand + PKCS11Provider + Port + PreferredAuthentications + Protocol + ProxyCommand + ProxyUseFdpass + PubkeyAcceptedKeyTypes + PubkeyAuthentication + RekeyLimit + RemoteForward + RequestTTY + RhostsRSAAuthentication + RSAAuthentication + SendEnv + ServerAliveInterval + ServerAliveCountMax + StreamLocalBindMask + StreamLocalBindUnlink + StrictHostKeyChecking + TCPKeepAlive + Tunnel + TunnelDevice + UpdateHostKeys + UsePrivilegedPort + User + UserKnownHostsFile + VerifyHostKeyDNS + VisualHostKey + XAuthLocation + + -p port + Port to connect to on the remote host. This can be specified on + a per-host basis in the configuration file. + + -Q cipher | cipher-auth | mac | kex | key | protocol-version + Queries ssh for the algorithms supported for the specified + version 2. The available features are: cipher (supported + symmetric ciphers), cipher-auth (supported symmetric ciphers that + support authenticated encryption), mac (supported message + integrity codes), kex (key exchange algorithms), key (key types) + and protocol-version (supported SSH protocol versions). + + -q Quiet mode. Causes most warning and diagnostic messages to be + suppressed. + + -R [bind_address:]port:host:hostport + -R [bind_address:]port:local_socket + -R remote_socket:host:hostport + -R remote_socket:local_socket + Specifies that connections to the given TCP port or Unix socket + on the remote (server) host are to be forwarded to the given host + and port, or Unix socket, on the local side. This works by + allocating a socket to listen to either a TCP port or to a Unix + socket on the remote side. Whenever a connection is made to this + port or Unix socket, the connection is forwarded over the secure + channel, and a connection is made to either host port hostport, + or local_socket, from the local machine. + + Port forwardings can also be specified in the configuration file. + Privileged ports can be forwarded only when logging in as root on + the remote machine. IPv6 addresses can be specified by enclosing + the address in square brackets. + + By default, TCP listening sockets on the server will be bound to + the loopback interface only. This may be overridden by + specifying a bind_address. An empty bind_address, or the address + M-bM-^@M-^X*M-bM-^@M-^Y, indicates that the remote socket should listen on all + interfaces. Specifying a remote bind_address will only succeed + if the server's GatewayPorts option is enabled (see + sshd_config(5)). + + If the port argument is M-bM-^@M-^X0M-bM-^@M-^Y, the listen port will be dynamically + allocated on the server and reported to the client at run time. + When used together with -O forward the allocated port will be + printed to the standard output. + + -S ctl_path + Specifies the location of a control socket for connection + sharing, or the string M-bM-^@M-^\noneM-bM-^@M-^] to disable connection sharing. + Refer to the description of ControlPath and ControlMaster in + ssh_config(5) for details. + + -s May be used to request invocation of a subsystem on the remote + system. Subsystems are a feature of the SSH2 protocol which + facilitate the use of SSH as a secure transport for other + applications (eg. sftp(1)). The subsystem is specified as the + remote command. + + -T Disable pseudo-terminal allocation. + + -t Force pseudo-terminal allocation. This can be used to execute + arbitrary screen-based programs on a remote machine, which can be + very useful, e.g. when implementing menu services. Multiple -t + options force tty allocation, even if ssh has no local tty. + + -V Display the version number and exit. + + -v Verbose mode. Causes ssh to print debugging messages about its + progress. This is helpful in debugging connection, + authentication, and configuration problems. Multiple -v options + increase the verbosity. The maximum is 3. + + -W host:port + Requests that standard input and output on the client be + forwarded to host on port over the secure channel. Implies -N, + -T, ExitOnForwardFailure and ClearAllForwardings. Works with + Protocol version 2 only. + + -w local_tun[:remote_tun] + Requests tunnel device forwarding with the specified tun(4) + devices between the client (local_tun) and the server + (remote_tun). + + The devices may be specified by numerical ID or the keyword + M-bM-^@M-^\anyM-bM-^@M-^], which uses the next available tunnel device. If + remote_tun is not specified, it defaults to M-bM-^@M-^\anyM-bM-^@M-^]. See also the + Tunnel and TunnelDevice directives in ssh_config(5). If the + Tunnel directive is unset, it is set to the default tunnel mode, + which is M-bM-^@M-^\point-to-pointM-bM-^@M-^]. + + -X Enables X11 forwarding. This can also be specified on a per-host + basis in a configuration file. + + X11 forwarding should be enabled with caution. Users with the + ability to bypass file permissions on the remote host (for the + user's X authorization database) can access the local X11 display + through the forwarded connection. An attacker may then be able + to perform activities such as keystroke monitoring. + + For this reason, X11 forwarding is subjected to X11 SECURITY + extension restrictions by default. Please refer to the ssh -Y + option and the ForwardX11Trusted directive in ssh_config(5) for + more information. + + -x Disables X11 forwarding. + + -Y Enables trusted X11 forwarding. Trusted X11 forwardings are not + subjected to the X11 SECURITY extension controls. + + -y Send log information using the syslog(3) system module. By + default this information is sent to stderr. + + ssh may additionally obtain configuration data from a per-user + configuration file and a system-wide configuration file. The file format + and configuration options are described in ssh_config(5). + +AUTHENTICATION + The OpenSSH SSH client supports SSH protocols 1 and 2. The default is to + use protocol 2 only, though this can be changed via the Protocol option + in ssh_config(5) or the -1 and -2 options (see above). Both protocols + support similar authentication methods, but protocol 2 is the default + since it provides additional mechanisms for confidentiality (the traffic + is encrypted using AES, 3DES, Blowfish, CAST128, or Arcfour) and + integrity (hmac-md5, hmac-sha1, hmac-sha2-256, hmac-sha2-512, umac-64, + umac-128, hmac-ripemd160). Protocol 1 lacks a strong mechanism for + ensuring the integrity of the connection. + + The methods available for authentication are: GSSAPI-based + authentication, host-based authentication, public key authentication, + challenge-response authentication, and password authentication. + Authentication methods are tried in the order specified above, though + protocol 2 has a configuration option to change the default order: + PreferredAuthentications. + + Host-based authentication works as follows: If the machine the user logs + in from is listed in /etc/hosts.equiv or /etc/shosts.equiv on the remote + machine, and the user names are the same on both sides, or if the files + ~/.rhosts or ~/.shosts exist in the user's home directory on the remote + machine and contain a line containing the name of the client machine and + the name of the user on that machine, the user is considered for login. + Additionally, the server must be able to verify the client's host key + (see the description of /etc/ssh/ssh_known_hosts and ~/.ssh/known_hosts, + below) for login to be permitted. This authentication method closes + security holes due to IP spoofing, DNS spoofing, and routing spoofing. + [Note to the administrator: /etc/hosts.equiv, ~/.rhosts, and the + rlogin/rsh protocol in general, are inherently insecure and should be + disabled if security is desired.] + + Public key authentication works as follows: The scheme is based on + public-key cryptography, using cryptosystems where encryption and + decryption are done using separate keys, and it is unfeasible to derive + the decryption key from the encryption key. The idea is that each user + creates a public/private key pair for authentication purposes. The + server knows the public key, and only the user knows the private key. + ssh implements public key authentication protocol automatically, using + one of the DSA, ECDSA, Ed25519 or RSA algorithms. Protocol 1 is + restricted to using only RSA keys, but protocol 2 may use any. The + HISTORY section of ssl(8) contains a brief discussion of the DSA and RSA + algorithms. + + The file ~/.ssh/authorized_keys lists the public keys that are permitted + for logging in. When the user logs in, the ssh program tells the server + which key pair it would like to use for authentication. The client + proves that it has access to the private key and the server checks that + the corresponding public key is authorized to accept the account. + + The user creates his/her key pair by running ssh-keygen(1). This stores + the private key in ~/.ssh/identity (protocol 1), ~/.ssh/id_dsa (protocol + 2 DSA), ~/.ssh/id_ecdsa (protocol 2 ECDSA), ~/.ssh/id_ed25519 (protocol 2 + Ed25519), or ~/.ssh/id_rsa (protocol 2 RSA) and stores the public key in + ~/.ssh/identity.pub (protocol 1), ~/.ssh/id_dsa.pub (protocol 2 DSA), + ~/.ssh/id_ecdsa.pub (protocol 2 ECDSA), ~/.ssh/id_ed25519.pub (protocol 2 + Ed25519), or ~/.ssh/id_rsa.pub (protocol 2 RSA) in the user's home + directory. The user should then copy the public key to + ~/.ssh/authorized_keys in his/her home directory on the remote machine. + The authorized_keys file corresponds to the conventional ~/.rhosts file, + and has one key per line, though the lines can be very long. After this, + the user can log in without giving the password. + + A variation on public key authentication is available in the form of + certificate authentication: instead of a set of public/private keys, + signed certificates are used. This has the advantage that a single + trusted certification authority can be used in place of many + public/private keys. See the CERTIFICATES section of ssh-keygen(1) for + more information. + + The most convenient way to use public key or certificate authentication + may be with an authentication agent. See ssh-agent(1) for more + information. + + Challenge-response authentication works as follows: The server sends an + arbitrary "challenge" text, and prompts for a response. Protocol 2 + allows multiple challenges and responses; protocol 1 is restricted to + just one challenge/response. Examples of challenge-response + authentication include BSD Authentication (see login.conf(5)) and PAM + (some non-OpenBSD systems). + + Finally, if other authentication methods fail, ssh prompts the user for a + password. The password is sent to the remote host for checking; however, + since all communications are encrypted, the password cannot be seen by + someone listening on the network. + + ssh automatically maintains and checks a database containing + identification for all hosts it has ever been used with. Host keys are + stored in ~/.ssh/known_hosts in the user's home directory. Additionally, + the file /etc/ssh/ssh_known_hosts is automatically checked for known + hosts. Any new hosts are automatically added to the user's file. If a + host's identification ever changes, ssh warns about this and disables + password authentication to prevent server spoofing or man-in-the-middle + attacks, which could otherwise be used to circumvent the encryption. The + StrictHostKeyChecking option can be used to control logins to machines + whose host key is not known or has changed. + + When the user's identity has been accepted by the server, the server + either executes the given command in a non-interactive session or, if no + command has been specified, logs into the machine and gives the user a + normal shell as an interactive session. All communication with the + remote command or shell will be automatically encrypted. + + If an interactive session is requested ssh by default will only request a + pseudo-terminal (pty) for interactive sessions when the client has one. + The flags -T and -t can be used to override this behaviour. + + If a pseudo-terminal has been allocated the user may use the escape + characters noted below. + + If no pseudo-terminal has been allocated, the session is transparent and + can be used to reliably transfer binary data. On most systems, setting + the escape character to M-bM-^@M-^\noneM-bM-^@M-^] will also make the session transparent + even if a tty is used. + + The session terminates when the command or shell on the remote machine + exits and all X11 and TCP connections have been closed. + +ESCAPE CHARACTERS + When a pseudo-terminal has been requested, ssh supports a number of + functions through the use of an escape character. + + A single tilde character can be sent as ~~ or by following the tilde by a + character other than those described below. The escape character must + always follow a newline to be interpreted as special. The escape + character can be changed in configuration files using the EscapeChar + configuration directive or on the command line by the -e option. + + The supported escapes (assuming the default M-bM-^@M-^X~M-bM-^@M-^Y) are: + + ~. Disconnect. + + ~^Z Background ssh. + + ~# List forwarded connections. + + ~& Background ssh at logout when waiting for forwarded connection / + X11 sessions to terminate. + + ~? Display a list of escape characters. + + ~B Send a BREAK to the remote system (only useful for SSH protocol + version 2 and if the peer supports it). + + ~C Open command line. Currently this allows the addition of port + forwardings using the -L, -R and -D options (see above). It also + allows the cancellation of existing port-forwardings with + -KL[bind_address:]port for local, -KR[bind_address:]port for + remote and -KD[bind_address:]port for dynamic port-forwardings. + !command allows the user to execute a local command if the + PermitLocalCommand option is enabled in ssh_config(5). Basic + help is available, using the -h option. + + ~R Request rekeying of the connection (only useful for SSH protocol + version 2 and if the peer supports it). + + ~V Decrease the verbosity (LogLevel) when errors are being written + to stderr. + + ~v Increase the verbosity (LogLevel) when errors are being written + to stderr. + +TCP FORWARDING + Forwarding of arbitrary TCP connections over the secure channel can be + specified either on the command line or in a configuration file. One + possible application of TCP forwarding is a secure connection to a mail + server; another is going through firewalls. + + In the example below, we look at encrypting communication between an IRC + client and server, even though the IRC server does not directly support + encrypted communications. This works as follows: the user connects to + the remote host using ssh, specifying a port to be used to forward + connections to the remote server. After that it is possible to start the + service which is to be encrypted on the client machine, connecting to the + same local port, and ssh will encrypt and forward the connection. + + The following example tunnels an IRC session from client machine + M-bM-^@M-^\127.0.0.1M-bM-^@M-^] (localhost) to remote server M-bM-^@M-^\server.example.comM-bM-^@M-^]: + + $ ssh -f -L 1234:localhost:6667 server.example.com sleep 10 + $ irc -c '#users' -p 1234 pinky 127.0.0.1 + + This tunnels a connection to IRC server M-bM-^@M-^\server.example.comM-bM-^@M-^], joining + channel M-bM-^@M-^\#usersM-bM-^@M-^], nickname M-bM-^@M-^\pinkyM-bM-^@M-^], using port 1234. It doesn't matter + which port is used, as long as it's greater than 1023 (remember, only + root can open sockets on privileged ports) and doesn't conflict with any + ports already in use. The connection is forwarded to port 6667 on the + remote server, since that's the standard port for IRC services. + + The -f option backgrounds ssh and the remote command M-bM-^@M-^\sleep 10M-bM-^@M-^] is + specified to allow an amount of time (10 seconds, in the example) to + start the service which is to be tunnelled. If no connections are made + within the time specified, ssh will exit. + +X11 FORWARDING + If the ForwardX11 variable is set to M-bM-^@M-^\yesM-bM-^@M-^] (or see the description of the + -X, -x, and -Y options above) and the user is using X11 (the DISPLAY + environment variable is set), the connection to the X11 display is + automatically forwarded to the remote side in such a way that any X11 + programs started from the shell (or command) will go through the + encrypted channel, and the connection to the real X server will be made + from the local machine. The user should not manually set DISPLAY. + Forwarding of X11 connections can be configured on the command line or in + configuration files. + + The DISPLAY value set by ssh will point to the server machine, but with a + display number greater than zero. This is normal, and happens because + ssh creates a M-bM-^@M-^\proxyM-bM-^@M-^] X server on the server machine for forwarding the + connections over the encrypted channel. + + ssh will also automatically set up Xauthority data on the server machine. + For this purpose, it will generate a random authorization cookie, store + it in Xauthority on the server, and verify that any forwarded connections + carry this cookie and replace it by the real cookie when the connection + is opened. The real authentication cookie is never sent to the server + machine (and no cookies are sent in the plain). + + If the ForwardAgent variable is set to M-bM-^@M-^\yesM-bM-^@M-^] (or see the description of + the -A and -a options above) and the user is using an authentication + agent, the connection to the agent is automatically forwarded to the + remote side. + +VERIFYING HOST KEYS + When connecting to a server for the first time, a fingerprint of the + server's public key is presented to the user (unless the option + StrictHostKeyChecking has been disabled). Fingerprints can be determined + using ssh-keygen(1): + + $ ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key + + If the fingerprint is already known, it can be matched and the key can be + accepted or rejected. If only legacy (MD5) fingerprints for the server + are available, the ssh-keygen(1) -E option may be used to downgrade the + fingerprint algorithm to match. + + Because of the difficulty of comparing host keys just by looking at + fingerprint strings, there is also support to compare host keys visually, + using random art. By setting the VisualHostKey option to M-bM-^@M-^\yesM-bM-^@M-^], a small + ASCII graphic gets displayed on every login to a server, no matter if the + session itself is interactive or not. By learning the pattern a known + server produces, a user can easily find out that the host key has changed + when a completely different pattern is displayed. Because these patterns + are not unambiguous however, a pattern that looks similar to the pattern + remembered only gives a good probability that the host key is the same, + not guaranteed proof. + + To get a listing of the fingerprints along with their random art for all + known hosts, the following command line can be used: + + $ ssh-keygen -lv -f ~/.ssh/known_hosts + + If the fingerprint is unknown, an alternative method of verification is + available: SSH fingerprints verified by DNS. An additional resource + record (RR), SSHFP, is added to a zonefile and the connecting client is + able to match the fingerprint with that of the key presented. + + In this example, we are connecting a client to a server, + M-bM-^@M-^\host.example.comM-bM-^@M-^]. The SSHFP resource records should first be added to + the zonefile for host.example.com: + + $ ssh-keygen -r host.example.com. + + The output lines will have to be added to the zonefile. To check that + the zone is answering fingerprint queries: + + $ dig -t SSHFP host.example.com + + Finally the client connects: + + $ ssh -o "VerifyHostKeyDNS ask" host.example.com + [...] + Matching host key fingerprint found in DNS. + Are you sure you want to continue connecting (yes/no)? + + See the VerifyHostKeyDNS option in ssh_config(5) for more information. + +SSH-BASED VIRTUAL PRIVATE NETWORKS + ssh contains support for Virtual Private Network (VPN) tunnelling using + the tun(4) network pseudo-device, allowing two networks to be joined + securely. The sshd_config(5) configuration option PermitTunnel controls + whether the server supports this, and at what level (layer 2 or 3 + traffic). + + The following example would connect client network 10.0.50.0/24 with + remote network 10.0.99.0/24 using a point-to-point connection from + 10.1.1.1 to 10.1.1.2, provided that the SSH server running on the gateway + to the remote network, at 192.168.1.15, allows it. + + On the client: + + # ssh -f -w 0:1 192.168.1.15 true + # ifconfig tun0 10.1.1.1 10.1.1.2 netmask 255.255.255.252 + # route add 10.0.99.0/24 10.1.1.2 + + On the server: + + # ifconfig tun1 10.1.1.2 10.1.1.1 netmask 255.255.255.252 + # route add 10.0.50.0/24 10.1.1.1 + + Client access may be more finely tuned via the /root/.ssh/authorized_keys + file (see below) and the PermitRootLogin server option. The following + entry would permit connections on tun(4) device 1 from user M-bM-^@M-^\janeM-bM-^@M-^] and on + tun device 2 from user M-bM-^@M-^\johnM-bM-^@M-^], if PermitRootLogin is set to + M-bM-^@M-^\forced-commands-onlyM-bM-^@M-^]: + + tunnel="1",command="sh /etc/netstart tun1" ssh-rsa ... jane + tunnel="2",command="sh /etc/netstart tun2" ssh-rsa ... john + + Since an SSH-based setup entails a fair amount of overhead, it may be + more suited to temporary setups, such as for wireless VPNs. More + permanent VPNs are better provided by tools such as ipsecctl(8) and + isakmpd(8). + +ENVIRONMENT + ssh will normally set the following environment variables: + + DISPLAY The DISPLAY variable indicates the location of the + X11 server. It is automatically set by ssh to + point to a value of the form M-bM-^@M-^\hostname:nM-bM-^@M-^], where + M-bM-^@M-^\hostnameM-bM-^@M-^] indicates the host where the shell runs, + and M-bM-^@M-^XnM-bM-^@M-^Y is an integer M-bM-^IM-% 1. ssh uses this special + value to forward X11 connections over the secure + channel. The user should normally not set DISPLAY + explicitly, as that will render the X11 connection + insecure (and will require the user to manually + copy any required authorization cookies). + + HOME Set to the path of the user's home directory. + + LOGNAME Synonym for USER; set for compatibility with + systems that use this variable. + + MAIL Set to the path of the user's mailbox. + + PATH Set to the default PATH, as specified when + compiling ssh. + + SSH_ASKPASS If ssh needs a passphrase, it will read the + passphrase from the current terminal if it was run + from a terminal. If ssh does not have a terminal + associated with it but DISPLAY and SSH_ASKPASS are + set, it will execute the program specified by + SSH_ASKPASS and open an X11 window to read the + passphrase. This is particularly useful when + calling ssh from a .xsession or related script. + (Note that on some machines it may be necessary to + redirect the input from /dev/null to make this + work.) + + SSH_AUTH_SOCK Identifies the path of a UNIX-domain socket used to + communicate with the agent. + + SSH_CONNECTION Identifies the client and server ends of the + connection. The variable contains four space- + separated values: client IP address, client port + number, server IP address, and server port number. + + SSH_ORIGINAL_COMMAND This variable contains the original command line if + a forced command is executed. It can be used to + extract the original arguments. + + SSH_TTY This is set to the name of the tty (path to the + device) associated with the current shell or + command. If the current session has no tty, this + variable is not set. + + TZ This variable is set to indicate the present time + zone if it was set when the daemon was started + (i.e. the daemon passes the value on to new + connections). + + USER Set to the name of the user logging in. + + Additionally, ssh reads ~/.ssh/environment, and adds lines of the format + M-bM-^@M-^\VARNAME=valueM-bM-^@M-^] to the environment if the file exists and users are + allowed to change their environment. For more information, see the + PermitUserEnvironment option in sshd_config(5). + +FILES + ~/.rhosts + This file is used for host-based authentication (see above). On + some machines this file may need to be world-readable if the + user's home directory is on an NFS partition, because sshd(8) + reads it as root. Additionally, this file must be owned by the + user, and must not have write permissions for anyone else. The + recommended permission for most machines is read/write for the + user, and not accessible by others. + + ~/.shosts + This file is used in exactly the same way as .rhosts, but allows + host-based authentication without permitting login with + rlogin/rsh. + + ~/.ssh/ + This directory is the default location for all user-specific + configuration and authentication information. There is no + general requirement to keep the entire contents of this directory + secret, but the recommended permissions are read/write/execute + for the user, and not accessible by others. + + ~/.ssh/authorized_keys + Lists the public keys (DSA, ECDSA, Ed25519, RSA) that can be used + for logging in as this user. The format of this file is + described in the sshd(8) manual page. This file is not highly + sensitive, but the recommended permissions are read/write for the + user, and not accessible by others. + + ~/.ssh/config + This is the per-user configuration file. The file format and + configuration options are described in ssh_config(5). Because of + the potential for abuse, this file must have strict permissions: + read/write for the user, and not writable by others. + + ~/.ssh/environment + Contains additional definitions for environment variables; see + ENVIRONMENT, above. + + ~/.ssh/identity + ~/.ssh/id_dsa + ~/.ssh/id_ecdsa + ~/.ssh/id_ed25519 + ~/.ssh/id_rsa + Contains the private key for authentication. These files contain + sensitive data and should be readable by the user but not + accessible by others (read/write/execute). ssh will simply + ignore a private key file if it is accessible by others. It is + possible to specify a passphrase when generating the key which + will be used to encrypt the sensitive part of this file using + 3DES. + + ~/.ssh/identity.pub + ~/.ssh/id_dsa.pub + ~/.ssh/id_ecdsa.pub + ~/.ssh/id_ed25519.pub + ~/.ssh/id_rsa.pub + Contains the public key for authentication. These files are not + sensitive and can (but need not) be readable by anyone. + + ~/.ssh/known_hosts + Contains a list of host keys for all hosts the user has logged + into that are not already in the systemwide list of known host + keys. See sshd(8) for further details of the format of this + file. + + ~/.ssh/rc + Commands in this file are executed by ssh when the user logs in, + just before the user's shell (or command) is started. See the + sshd(8) manual page for more information. + + /etc/hosts.equiv + This file is for host-based authentication (see above). It + should only be writable by root. + + /etc/shosts.equiv + This file is used in exactly the same way as hosts.equiv, but + allows host-based authentication without permitting login with + rlogin/rsh. + + /etc/ssh/ssh_config + Systemwide configuration file. The file format and configuration + options are described in ssh_config(5). + + /etc/ssh/ssh_host_key + /etc/ssh/ssh_host_dsa_key + /etc/ssh/ssh_host_ecdsa_key + /etc/ssh/ssh_host_ed25519_key + /etc/ssh/ssh_host_rsa_key + These files contain the private parts of the host keys and are + used for host-based authentication. If protocol version 1 is + used, ssh must be setuid root, since the host key is readable + only by root. For protocol version 2, ssh uses ssh-keysign(8) to + access the host keys, eliminating the requirement that ssh be + setuid root when host-based authentication is used. By default + ssh is not setuid root. + + /etc/ssh/ssh_known_hosts + Systemwide list of known host keys. This file should be prepared + by the system administrator to contain the public host keys of + all machines in the organization. It should be world-readable. + See sshd(8) for further details of the format of this file. + + /etc/ssh/sshrc + Commands in this file are executed by ssh when the user logs in, + just before the user's shell (or command) is started. See the + sshd(8) manual page for more information. + +EXIT STATUS + ssh exits with the exit status of the remote command or with 255 if an + error occurred. + +SEE ALSO + scp(1), sftp(1), ssh-add(1), ssh-agent(1), ssh-keygen(1), ssh-keyscan(1), + tun(4), ssh_config(5), ssh-keysign(8), sshd(8) + +STANDARDS + S. Lehtinen and C. Lonvick, The Secure Shell (SSH) Protocol Assigned + Numbers, RFC 4250, January 2006. + + T. Ylonen and C. Lonvick, The Secure Shell (SSH) Protocol Architecture, + RFC 4251, January 2006. + + T. Ylonen and C. Lonvick, The Secure Shell (SSH) Authentication Protocol, + RFC 4252, January 2006. + + T. Ylonen and C. Lonvick, The Secure Shell (SSH) Transport Layer + Protocol, RFC 4253, January 2006. + + T. Ylonen and C. Lonvick, The Secure Shell (SSH) Connection Protocol, RFC + 4254, January 2006. + + J. Schlyter and W. Griffin, Using DNS to Securely Publish Secure Shell + (SSH) Key Fingerprints, RFC 4255, January 2006. + + F. Cusack and M. Forssen, Generic Message Exchange Authentication for the + Secure Shell Protocol (SSH), RFC 4256, January 2006. + + J. Galbraith and P. Remaker, The Secure Shell (SSH) Session Channel Break + Extension, RFC 4335, January 2006. + + M. Bellare, T. Kohno, and C. Namprempre, The Secure Shell (SSH) Transport + Layer Encryption Modes, RFC 4344, January 2006. + + B. Harris, Improved Arcfour Modes for the Secure Shell (SSH) Transport + Layer Protocol, RFC 4345, January 2006. + + M. Friedl, N. Provos, and W. Simpson, Diffie-Hellman Group Exchange for + the Secure Shell (SSH) Transport Layer Protocol, RFC 4419, March 2006. + + J. Galbraith and R. Thayer, The Secure Shell (SSH) Public Key File + Format, RFC 4716, November 2006. + + D. Stebila and J. Green, Elliptic Curve Algorithm Integration in the + Secure Shell Transport Layer, RFC 5656, December 2009. + + A. Perrig and D. Song, Hash Visualization: a New Technique to improve + Real-World Security, 1999, International Workshop on Cryptographic + Techniques and E-Commerce (CrypTEC '99). + +AUTHORS + OpenSSH is a derivative of the original and free ssh 1.2.12 release by + Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo + de Raadt and Dug Song removed many bugs, re-added newer features and + created OpenSSH. Markus Friedl contributed the support for SSH protocol + versions 1.5 and 2.0. + +OpenBSD 5.8 July 20, 2015 OpenBSD 5.8 diff --git a/crypto/external/bsd/openssh/dist/ssh_config.0 b/crypto/external/bsd/openssh/dist/ssh_config.0 new file mode 100644 index 000000000..67133cd4d --- /dev/null +++ b/crypto/external/bsd/openssh/dist/ssh_config.0 @@ -0,0 +1,1026 @@ +SSH_CONFIG(5) File Formats Manual SSH_CONFIG(5) + +NAME + ssh_config M-bM-^@M-^S OpenSSH SSH client configuration files + +SYNOPSIS + ~/.ssh/config + /etc/ssh/ssh_config + +DESCRIPTION + ssh(1) obtains configuration data from the following sources in the + following order: + + 1. command-line options + 2. user's configuration file (~/.ssh/config) + 3. system-wide configuration file (/etc/ssh/ssh_config) + + For each parameter, the first obtained value will be used. The + configuration files contain sections separated by M-bM-^@M-^\HostM-bM-^@M-^] specifications, + and that section is only applied for hosts that match one of the patterns + given in the specification. The matched host name is usually the one + given on the command line (see the CanonicalizeHostname option for + exceptions.) + + Since the first obtained value for each parameter is used, more host- + specific declarations should be given near the beginning of the file, and + general defaults at the end. + + The configuration file has the following format: + + Empty lines and lines starting with M-bM-^@M-^X#M-bM-^@M-^Y are comments. Otherwise a line + is of the format M-bM-^@M-^\keyword argumentsM-bM-^@M-^]. Configuration options may be + separated by whitespace or optional whitespace and exactly one M-bM-^@M-^X=M-bM-^@M-^Y; the + latter format is useful to avoid the need to quote whitespace when + specifying configuration options using the ssh, scp, and sftp -o option. + Arguments may optionally be enclosed in double quotes (") in order to + represent arguments containing spaces. + + The possible keywords and their meanings are as follows (note that + keywords are case-insensitive and arguments are case-sensitive): + + Host Restricts the following declarations (up to the next Host or + Match keyword) to be only for those hosts that match one of the + patterns given after the keyword. If more than one pattern is + provided, they should be separated by whitespace. A single M-bM-^@M-^X*M-bM-^@M-^Y + as a pattern can be used to provide global defaults for all + hosts. The host is usually the hostname argument given on the + command line (see the CanonicalizeHostname option for + exceptions.) + + A pattern entry may be negated by prefixing it with an + exclamation mark (M-bM-^@M-^X!M-bM-^@M-^Y). If a negated entry is matched, then the + Host entry is ignored, regardless of whether any other patterns + on the line match. Negated matches are therefore useful to + provide exceptions for wildcard matches. + + See PATTERNS for more information on patterns. + + Match Restricts the following declarations (up to the next Host or + Match keyword) to be used only when the conditions following the + Match keyword are satisfied. Match conditions are specified + using one or more critera or the single token all which always + matches. The available criteria keywords are: canonical, exec, + host, originalhost, user, and localuser. The all criteria must + appear alone or immediately after canonical. Other criteria may + be combined arbitrarily. All criteria but all and canonical + require an argument. Criteria may be negated by prepending an + exclamation mark (M-bM-^@M-^X!M-bM-^@M-^Y). + + The canonical keyword matches only when the configuration file is + being re-parsed after hostname canonicalization (see the + CanonicalizeHostname option.) This may be useful to specify + conditions that work with canonical host names only. The exec + keyword executes the specified command under the user's shell. + If the command returns a zero exit status then the condition is + considered true. Commands containing whitespace characters must + be quoted. The following character sequences in the command will + be expanded prior to execution: M-bM-^@M-^X%LM-bM-^@M-^Y will be substituted by the + first component of the local host name, M-bM-^@M-^X%lM-bM-^@M-^Y will be substituted + by the local host name (including any domain name), M-bM-^@M-^X%hM-bM-^@M-^Y will be + substituted by the target host name, M-bM-^@M-^X%nM-bM-^@M-^Y will be substituted by + the original target host name specified on the command-line, M-bM-^@M-^X%pM-bM-^@M-^Y + the destination port, M-bM-^@M-^X%rM-bM-^@M-^Y by the remote login username, and M-bM-^@M-^X%uM-bM-^@M-^Y + by the username of the user running ssh(1). + + The other keywords' criteria must be single entries or comma- + separated lists and may use the wildcard and negation operators + described in the PATTERNS section. The criteria for the host + keyword are matched against the target hostname, after any + substitution by the Hostname or CanonicalizeHostname options. + The originalhost keyword matches against the hostname as it was + specified on the command-line. The user keyword matches against + the target username on the remote host. The localuser keyword + matches against the name of the local user running ssh(1) (this + keyword may be useful in system-wide ssh_config files). + + AddressFamily + Specifies which address family to use when connecting. Valid + arguments are M-bM-^@M-^\anyM-bM-^@M-^], M-bM-^@M-^\inetM-bM-^@M-^] (use IPv4 only), or M-bM-^@M-^\inet6M-bM-^@M-^] (use IPv6 + only). + + BatchMode + If set to M-bM-^@M-^\yesM-bM-^@M-^], passphrase/password querying will be disabled. + This option is useful in scripts and other batch jobs where no + user is present to supply the password. The argument must be + M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. + + BindAddress + Use the specified address on the local machine as the source + address of the connection. Only useful on systems with more than + one address. Note that this option does not work if + UsePrivilegedPort is set to M-bM-^@M-^\yesM-bM-^@M-^]. + + CanonicalDomains + When CanonicalizeHostname is enabled, this option specifies the + list of domain suffixes in which to search for the specified + destination host. + + CanonicalizeFallbackLocal + Specifies whether to fail with an error when hostname + canonicalization fails. The default, M-bM-^@M-^\yesM-bM-^@M-^], will attempt to look + up the unqualified hostname using the system resolver's search + rules. A value of M-bM-^@M-^\noM-bM-^@M-^] will cause ssh(1) to fail instantly if + CanonicalizeHostname is enabled and the target hostname cannot be + found in any of the domains specified by CanonicalDomains. + + CanonicalizeHostname + Controls whether explicit hostname canonicalization is performed. + The default, M-bM-^@M-^\noM-bM-^@M-^], is not to perform any name rewriting and let + the system resolver handle all hostname lookups. If set to M-bM-^@M-^\yesM-bM-^@M-^] + then, for connections that do not use a ProxyCommand, ssh(1) will + attempt to canonicalize the hostname specified on the command + line using the CanonicalDomains suffixes and + CanonicalizePermittedCNAMEs rules. If CanonicalizeHostname is + set to M-bM-^@M-^\alwaysM-bM-^@M-^], then canonicalization is applied to proxied + connections too. + + If this option is enabled, then the configuration files are + processed again using the new target name to pick up any new + configuration in matching Host and Match stanzas. + + CanonicalizeMaxDots + Specifies the maximum number of dot characters in a hostname + before canonicalization is disabled. The default, M-bM-^@M-^\1M-bM-^@M-^], allows a + single dot (i.e. hostname.subdomain). + + CanonicalizePermittedCNAMEs + Specifies rules to determine whether CNAMEs should be followed + when canonicalizing hostnames. The rules consist of one or more + arguments of source_domain_list:target_domain_list, where + source_domain_list is a pattern-list of domains that may follow + CNAMEs in canonicalization, and target_domain_list is a pattern- + list of domains that they may resolve to. + + For example, M-bM-^@M-^\*.a.example.com:*.b.example.com,*.c.example.comM-bM-^@M-^] + will allow hostnames matching M-bM-^@M-^\*.a.example.comM-bM-^@M-^] to be + canonicalized to names in the M-bM-^@M-^\*.b.example.comM-bM-^@M-^] or + M-bM-^@M-^\*.c.example.comM-bM-^@M-^] domains. + + ChallengeResponseAuthentication + Specifies whether to use challenge-response authentication. The + argument to this keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is + M-bM-^@M-^\yesM-bM-^@M-^]. + + CheckHostIP + If this flag is set to M-bM-^@M-^\yesM-bM-^@M-^], ssh(1) will additionally check the + host IP address in the known_hosts file. This allows ssh to + detect if a host key changed due to DNS spoofing and will add + addresses of destination hosts to ~/.ssh/known_hosts in the + process, regardless of the setting of StrictHostKeyChecking. If + the option is set to M-bM-^@M-^\noM-bM-^@M-^], the check will not be executed. The + default is M-bM-^@M-^\yesM-bM-^@M-^]. + + Cipher Specifies the cipher to use for encrypting the session in + protocol version 1. Currently, M-bM-^@M-^\blowfishM-bM-^@M-^], M-bM-^@M-^\3desM-bM-^@M-^], and M-bM-^@M-^\desM-bM-^@M-^] are + supported. des is only supported in the ssh(1) client for + interoperability with legacy protocol 1 implementations that do + not support the 3des cipher. Its use is strongly discouraged due + to cryptographic weaknesses. The default is M-bM-^@M-^\3desM-bM-^@M-^]. + + Ciphers + Specifies the ciphers allowed for protocol version 2 in order of + preference. Multiple ciphers must be comma-separated. If the + specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified + ciphers will be appended to the default set instead of replacing + them. + + The supported ciphers are: + + 3des-cbc + aes128-cbc + aes192-cbc + aes256-cbc + aes128-ctr + aes192-ctr + aes256-ctr + aes128-gcm@openssh.com + aes256-gcm@openssh.com + arcfour + arcfour128 + arcfour256 + blowfish-cbc + cast128-cbc + chacha20-poly1305@openssh.com + + The default is: + + chacha20-poly1305@openssh.com, + aes128-ctr,aes192-ctr,aes256-ctr, + aes128-gcm@openssh.com,aes256-gcm@openssh.com, + arcfour256,arcfour128, + aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc, + aes192-cbc,aes256-cbc,arcfour + + The list of available ciphers may also be obtained using the -Q + option of ssh(1) with an argument of M-bM-^@M-^\cipherM-bM-^@M-^]. + + ClearAllForwardings + Specifies that all local, remote, and dynamic port forwardings + specified in the configuration files or on the command line be + cleared. This option is primarily useful when used from the + ssh(1) command line to clear port forwardings set in + configuration files, and is automatically set by scp(1) and + sftp(1). The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is + M-bM-^@M-^\noM-bM-^@M-^]. + + Compression + Specifies whether to use compression. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] + or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. + + CompressionLevel + Specifies the compression level to use if compression is enabled. + The argument must be an integer from 1 (fast) to 9 (slow, best). + The default level is 6, which is good for most applications. The + meaning of the values is the same as in gzip(1). Note that this + option applies to protocol version 1 only. + + ConnectionAttempts + Specifies the number of tries (one per second) to make before + exiting. The argument must be an integer. This may be useful in + scripts if the connection sometimes fails. The default is 1. + + ConnectTimeout + Specifies the timeout (in seconds) used when connecting to the + SSH server, instead of using the default system TCP timeout. + This value is used only when the target is down or really + unreachable, not when it refuses the connection. + + ControlMaster + Enables the sharing of multiple sessions over a single network + connection. When set to M-bM-^@M-^\yesM-bM-^@M-^], ssh(1) will listen for + connections on a control socket specified using the ControlPath + argument. Additional sessions can connect to this socket using + the same ControlPath with ControlMaster set to M-bM-^@M-^\noM-bM-^@M-^] (the + default). These sessions will try to reuse the master instance's + network connection rather than initiating new ones, but will fall + back to connecting normally if the control socket does not exist, + or is not listening. + + Setting this to M-bM-^@M-^\askM-bM-^@M-^] will cause ssh to listen for control + connections, but require confirmation using ssh-askpass(1). If + the ControlPath cannot be opened, ssh will continue without + connecting to a master instance. + + X11 and ssh-agent(1) forwarding is supported over these + multiplexed connections, however the display and agent forwarded + will be the one belonging to the master connection i.e. it is not + possible to forward multiple displays or agents. + + Two additional options allow for opportunistic multiplexing: try + to use a master connection but fall back to creating a new one if + one does not already exist. These options are: M-bM-^@M-^\autoM-bM-^@M-^] and + M-bM-^@M-^\autoaskM-bM-^@M-^]. The latter requires confirmation like the M-bM-^@M-^\askM-bM-^@M-^] + option. + + ControlPath + Specify the path to the control socket used for connection + sharing as described in the ControlMaster section above or the + string M-bM-^@M-^\noneM-bM-^@M-^] to disable connection sharing. In the path, M-bM-^@M-^X%LM-bM-^@M-^Y + will be substituted by the first component of the local host + name, M-bM-^@M-^X%lM-bM-^@M-^Y will be substituted by the local host name (including + any domain name), M-bM-^@M-^X%hM-bM-^@M-^Y will be substituted by the target host + name, M-bM-^@M-^X%nM-bM-^@M-^Y will be substituted by the original target host name + specified on the command line, M-bM-^@M-^X%pM-bM-^@M-^Y the destination port, M-bM-^@M-^X%rM-bM-^@M-^Y by + the remote login username, M-bM-^@M-^X%uM-bM-^@M-^Y by the username of the user + running ssh(1), and M-bM-^@M-^X%CM-bM-^@M-^Y by a hash of the concatenation: + %l%h%p%r. It is recommended that any ControlPath used for + opportunistic connection sharing include at least %h, %p, and %r + (or alternatively %C) and be placed in a directory that is not + writable by other users. This ensures that shared connections + are uniquely identified. + + ControlPersist + When used in conjunction with ControlMaster, specifies that the + master connection should remain open in the background (waiting + for future client connections) after the initial client + connection has been closed. If set to M-bM-^@M-^\noM-bM-^@M-^], then the master + connection will not be placed into the background, and will close + as soon as the initial client connection is closed. If set to + M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\0M-bM-^@M-^], then the master connection will remain in the + background indefinitely (until killed or closed via a mechanism + such as the ssh(1) M-bM-^@M-^\-O exitM-bM-^@M-^] option). If set to a time in + seconds, or a time in any of the formats documented in + sshd_config(5), then the backgrounded master connection will + automatically terminate after it has remained idle (with no + client connections) for the specified time. + + DynamicForward + Specifies that a TCP port on the local machine be forwarded over + the secure channel, and the application protocol is then used to + determine where to connect to from the remote machine. + + The argument must be [bind_address:]port. IPv6 addresses can be + specified by enclosing addresses in square brackets. By default, + the local port is bound in accordance with the GatewayPorts + setting. However, an explicit bind_address may be used to bind + the connection to a specific address. The bind_address of + M-bM-^@M-^\localhostM-bM-^@M-^] indicates that the listening port be bound for local + use only, while an empty address or M-bM-^@M-^X*M-bM-^@M-^Y indicates that the port + should be available from all interfaces. + + Currently the SOCKS4 and SOCKS5 protocols are supported, and + ssh(1) will act as a SOCKS server. Multiple forwardings may be + specified, and additional forwardings can be given on the command + line. Only the superuser can forward privileged ports. + + EnableSSHKeysign + Setting this option to M-bM-^@M-^\yesM-bM-^@M-^] in the global client configuration + file /etc/ssh/ssh_config enables the use of the helper program + ssh-keysign(8) during HostbasedAuthentication. The argument must + be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. This option should be + placed in the non-hostspecific section. See ssh-keysign(8) for + more information. + + EscapeChar + Sets the escape character (default: M-bM-^@M-^X~M-bM-^@M-^Y). The escape character + can also be set on the command line. The argument should be a + single character, M-bM-^@M-^X^M-bM-^@M-^Y followed by a letter, or M-bM-^@M-^\noneM-bM-^@M-^] to disable + the escape character entirely (making the connection transparent + for binary data). + + ExitOnForwardFailure + Specifies whether ssh(1) should terminate the connection if it + cannot set up all requested dynamic, tunnel, local, and remote + port forwardings. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The + default is M-bM-^@M-^\noM-bM-^@M-^]. + + FingerprintHash + Specifies the hash algorithm used when displaying key + fingerprints. Valid options are: M-bM-^@M-^\md5M-bM-^@M-^] and M-bM-^@M-^\sha256M-bM-^@M-^]. The + default is M-bM-^@M-^\sha256M-bM-^@M-^]. + + ForwardAgent + Specifies whether the connection to the authentication agent (if + any) will be forwarded to the remote machine. The argument must + be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. + + Agent forwarding should be enabled with caution. Users with the + ability to bypass file permissions on the remote host (for the + agent's Unix-domain socket) can access the local agent through + the forwarded connection. An attacker cannot obtain key material + from the agent, however they can perform operations on the keys + that enable them to authenticate using the identities loaded into + the agent. + + ForwardX11 + Specifies whether X11 connections will be automatically + redirected over the secure channel and DISPLAY set. The argument + must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. + + X11 forwarding should be enabled with caution. Users with the + ability to bypass file permissions on the remote host (for the + user's X11 authorization database) can access the local X11 + display through the forwarded connection. An attacker may then + be able to perform activities such as keystroke monitoring if the + ForwardX11Trusted option is also enabled. + + ForwardX11Timeout + Specify a timeout for untrusted X11 forwarding using the format + described in the TIME FORMATS section of sshd_config(5). X11 + connections received by ssh(1) after this time will be refused. + The default is to disable untrusted X11 forwarding after twenty + minutes has elapsed. + + ForwardX11Trusted + If this option is set to M-bM-^@M-^\yesM-bM-^@M-^], remote X11 clients will have full + access to the original X11 display. + + If this option is set to M-bM-^@M-^\noM-bM-^@M-^], remote X11 clients will be + considered untrusted and prevented from stealing or tampering + with data belonging to trusted X11 clients. Furthermore, the + xauth(1) token used for the session will be set to expire after + 20 minutes. Remote clients will be refused access after this + time. + + The default is M-bM-^@M-^\noM-bM-^@M-^]. + + See the X11 SECURITY extension specification for full details on + the restrictions imposed on untrusted clients. + + GatewayPorts + Specifies whether remote hosts are allowed to connect to local + forwarded ports. By default, ssh(1) binds local port forwardings + to the loopback address. This prevents other remote hosts from + connecting to forwarded ports. GatewayPorts can be used to + specify that ssh should bind local port forwardings to the + wildcard address, thus allowing remote hosts to connect to + forwarded ports. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The + default is M-bM-^@M-^\noM-bM-^@M-^]. + + GlobalKnownHostsFile + Specifies one or more files to use for the global host key + database, separated by whitespace. The default is + /etc/ssh/ssh_known_hosts, /etc/ssh/ssh_known_hosts2. + + GSSAPIAuthentication + Specifies whether user authentication based on GSSAPI is allowed. + The default is M-bM-^@M-^\noM-bM-^@M-^]. Note that this option applies to protocol + version 2 only. + + GSSAPIDelegateCredentials + Forward (delegate) credentials to the server. The default is + M-bM-^@M-^\noM-bM-^@M-^]. Note that this option applies to protocol version 2 only. + + HashKnownHosts + Indicates that ssh(1) should hash host names and addresses when + they are added to ~/.ssh/known_hosts. These hashed names may be + used normally by ssh(1) and sshd(8), but they do not reveal + identifying information should the file's contents be disclosed. + The default is M-bM-^@M-^\noM-bM-^@M-^]. Note that existing names and addresses in + known hosts files will not be converted automatically, but may be + manually hashed using ssh-keygen(1). + + HostbasedAuthentication + Specifies whether to try rhosts based authentication with public + key authentication. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The + default is M-bM-^@M-^\noM-bM-^@M-^]. This option applies to protocol version 2 only + and is similar to RhostsRSAAuthentication. + + HostbasedKeyTypes + Specifies the key types that will be used for hostbased + authentication as a comma-separated pattern list. Alternately if + the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the + specified key types will be appended to the default set instead + of replacing them. The default for this option is: + + ecdsa-sha2-nistp256-cert-v01@openssh.com, + ecdsa-sha2-nistp384-cert-v01@openssh.com, + ecdsa-sha2-nistp521-cert-v01@openssh.com, + ssh-ed25519-cert-v01@openssh.com, + ssh-rsa-cert-v01@openssh.com, + ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, + ssh-ed25519,ssh-rsa + + The -Q option of ssh(1) may be used to list supported key types. + + HostKeyAlgorithms + Specifies the protocol version 2 host key algorithms that the + client wants to use in order of preference. Alternately if the + specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified + key types will be appended to the default set instead of + replacing them. The default for this option is: + + ecdsa-sha2-nistp256-cert-v01@openssh.com, + ecdsa-sha2-nistp384-cert-v01@openssh.com, + ecdsa-sha2-nistp521-cert-v01@openssh.com, + ssh-ed25519-cert-v01@openssh.com, + ssh-rsa-cert-v01@openssh.com, + ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, + ssh-ed25519,ssh-rsa + + If hostkeys are known for the destination host then this default + is modified to prefer their algorithms. + + The list of available key types may also be obtained using the -Q + option of ssh(1) with an argument of M-bM-^@M-^\keyM-bM-^@M-^]. + + HostKeyAlias + Specifies an alias that should be used instead of the real host + name when looking up or saving the host key in the host key + database files. This option is useful for tunneling SSH + connections or for multiple servers running on a single host. + + HostName + Specifies the real host name to log into. This can be used to + specify nicknames or abbreviations for hosts. If the hostname + contains the character sequence M-bM-^@M-^X%hM-bM-^@M-^Y, then this will be replaced + with the host name specified on the command line (this is useful + for manipulating unqualified names). The character sequence M-bM-^@M-^X%%M-bM-^@M-^Y + will be replaced by a single M-bM-^@M-^X%M-bM-^@M-^Y character, which may be used + when specifying IPv6 link-local addresses. + + The default is the name given on the command line. Numeric IP + addresses are also permitted (both on the command line and in + HostName specifications). + + IdentitiesOnly + Specifies that ssh(1) should only use the authentication identity + files configured in the ssh_config files, even if ssh-agent(1) or + a PKCS11Provider offers more identities. The argument to this + keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. This option is intended for + situations where ssh-agent offers many different identities. The + default is M-bM-^@M-^\noM-bM-^@M-^]. + + IdentityFile + Specifies a file from which the user's DSA, ECDSA, Ed25519 or RSA + authentication identity is read. The default is ~/.ssh/identity + for protocol version 1, and ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, + ~/.ssh/id_ed25519 and ~/.ssh/id_rsa for protocol version 2. + Additionally, any identities represented by the authentication + agent will be used for authentication unless IdentitiesOnly is + set. ssh(1) will try to load certificate information from the + filename obtained by appending -cert.pub to the path of a + specified IdentityFile. + + The file name may use the tilde syntax to refer to a user's home + directory or one of the following escape characters: M-bM-^@M-^X%dM-bM-^@M-^Y (local + user's home directory), M-bM-^@M-^X%uM-bM-^@M-^Y (local user name), M-bM-^@M-^X%lM-bM-^@M-^Y (local host + name), M-bM-^@M-^X%hM-bM-^@M-^Y (remote host name) or M-bM-^@M-^X%rM-bM-^@M-^Y (remote user name). + + It is possible to have multiple identity files specified in + configuration files; all these identities will be tried in + sequence. Multiple IdentityFile directives will add to the list + of identities tried (this behaviour differs from that of other + configuration directives). + + IdentityFile may be used in conjunction with IdentitiesOnly to + select which identities in an agent are offered during + authentication. + + IgnoreUnknown + Specifies a pattern-list of unknown options to be ignored if they + are encountered in configuration parsing. This may be used to + suppress errors if ssh_config contains options that are + unrecognised by ssh(1). It is recommended that IgnoreUnknown be + listed early in the configuration file as it will not be applied + to unknown options that appear before it. + + IPQoS Specifies the IPv4 type-of-service or DSCP class for connections. + Accepted values are M-bM-^@M-^\af11M-bM-^@M-^], M-bM-^@M-^\af12M-bM-^@M-^], M-bM-^@M-^\af13M-bM-^@M-^], M-bM-^@M-^\af21M-bM-^@M-^], M-bM-^@M-^\af22M-bM-^@M-^], + M-bM-^@M-^\af23M-bM-^@M-^], M-bM-^@M-^\af31M-bM-^@M-^], M-bM-^@M-^\af32M-bM-^@M-^], M-bM-^@M-^\af33M-bM-^@M-^], M-bM-^@M-^\af41M-bM-^@M-^], M-bM-^@M-^\af42M-bM-^@M-^], M-bM-^@M-^\af43M-bM-^@M-^], M-bM-^@M-^\cs0M-bM-^@M-^], + M-bM-^@M-^\cs1M-bM-^@M-^], M-bM-^@M-^\cs2M-bM-^@M-^], M-bM-^@M-^\cs3M-bM-^@M-^], M-bM-^@M-^\cs4M-bM-^@M-^], M-bM-^@M-^\cs5M-bM-^@M-^], M-bM-^@M-^\cs6M-bM-^@M-^], M-bM-^@M-^\cs7M-bM-^@M-^], M-bM-^@M-^\efM-bM-^@M-^], + M-bM-^@M-^\lowdelayM-bM-^@M-^], M-bM-^@M-^\throughputM-bM-^@M-^], M-bM-^@M-^\reliabilityM-bM-^@M-^], or a numeric value. + This option may take one or two arguments, separated by + whitespace. If one argument is specified, it is used as the + packet class unconditionally. If two values are specified, the + first is automatically selected for interactive sessions and the + second for non-interactive sessions. The default is M-bM-^@M-^\lowdelayM-bM-^@M-^] + for interactive sessions and M-bM-^@M-^\throughputM-bM-^@M-^] for non-interactive + sessions. + + KbdInteractiveAuthentication + Specifies whether to use keyboard-interactive authentication. + The argument to this keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default + is M-bM-^@M-^\yesM-bM-^@M-^]. + + KbdInteractiveDevices + Specifies the list of methods to use in keyboard-interactive + authentication. Multiple method names must be comma-separated. + The default is to use the server specified list. The methods + available vary depending on what the server supports. For an + OpenSSH server, it may be zero or more of: M-bM-^@M-^\bsdauthM-bM-^@M-^], M-bM-^@M-^\pamM-bM-^@M-^], and + M-bM-^@M-^\skeyM-bM-^@M-^]. + + KexAlgorithms + Specifies the available KEX (Key Exchange) algorithms. Multiple + algorithms must be comma-separated. Alternately if the specified + value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified methods + will be appended to the default set instead of replacing them. + The default is: + + curve25519-sha256@libssh.org, + ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, + diffie-hellman-group-exchange-sha256, + diffie-hellman-group-exchange-sha1, + diffie-hellman-group14-sha1 + + The list of available key exchange algorithms may also be + obtained using the -Q option of ssh(1) with an argument of M-bM-^@M-^\kexM-bM-^@M-^]. + + LocalCommand + Specifies a command to execute on the local machine after + successfully connecting to the server. The command string + extends to the end of the line, and is executed with the user's + shell. The following escape character substitutions will be + performed: M-bM-^@M-^X%dM-bM-^@M-^Y (local user's home directory), M-bM-^@M-^X%hM-bM-^@M-^Y (remote host + name), M-bM-^@M-^X%lM-bM-^@M-^Y (local host name), M-bM-^@M-^X%nM-bM-^@M-^Y (host name as provided on the + command line), M-bM-^@M-^X%pM-bM-^@M-^Y (remote port), M-bM-^@M-^X%rM-bM-^@M-^Y (remote user name) or + M-bM-^@M-^X%uM-bM-^@M-^Y (local user name) or M-bM-^@M-^X%CM-bM-^@M-^Y by a hash of the concatenation: + %l%h%p%r. + + The command is run synchronously and does not have access to the + session of the ssh(1) that spawned it. It should not be used for + interactive commands. + + This directive is ignored unless PermitLocalCommand has been + enabled. + + LocalForward + Specifies that a TCP port on the local machine be forwarded over + the secure channel to the specified host and port from the remote + machine. The first argument must be [bind_address:]port and the + second argument must be host:hostport. IPv6 addresses can be + specified by enclosing addresses in square brackets. Multiple + forwardings may be specified, and additional forwardings can be + given on the command line. Only the superuser can forward + privileged ports. By default, the local port is bound in + accordance with the GatewayPorts setting. However, an explicit + bind_address may be used to bind the connection to a specific + address. The bind_address of M-bM-^@M-^\localhostM-bM-^@M-^] indicates that the + listening port be bound for local use only, while an empty + address or M-bM-^@M-^X*M-bM-^@M-^Y indicates that the port should be available from + all interfaces. + + LogLevel + Gives the verbosity level that is used when logging messages from + ssh(1). The possible values are: QUIET, FATAL, ERROR, INFO, + VERBOSE, DEBUG, DEBUG1, DEBUG2, and DEBUG3. The default is INFO. + DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify + higher levels of verbose output. + + MACs Specifies the MAC (message authentication code) algorithms in + order of preference. The MAC algorithm is used in protocol + version 2 for data integrity protection. Multiple algorithms + must be comma-separated. If the specified value begins with a + M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified algorithms will be appended to + the default set instead of replacing them. + + The algorithms that contain M-bM-^@M-^\-etmM-bM-^@M-^] calculate the MAC after + encryption (encrypt-then-mac). These are considered safer and + their use recommended. + + The default is: + + umac-64-etm@openssh.com,umac-128-etm@openssh.com, + hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com, + umac-64@openssh.com,umac-128@openssh.com, + hmac-sha2-256,hmac-sha2-512, + hmac-md5-etm@openssh.com,hmac-sha1-etm@openssh.com, + hmac-ripemd160-etm@openssh.com, + hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com, + hmac-md5,hmac-sha1,hmac-ripemd160, + hmac-sha1-96,hmac-md5-96 + + The list of available MAC algorithms may also be obtained using + the -Q option of ssh(1) with an argument of M-bM-^@M-^\macM-bM-^@M-^]. + + NoHostAuthenticationForLocalhost + This option can be used if the home directory is shared across + machines. In this case localhost will refer to a different + machine on each of the machines and the user will get many + warnings about changed host keys. However, this option disables + host authentication for localhost. The argument to this keyword + must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is to check the host key for + localhost. + + NumberOfPasswordPrompts + Specifies the number of password prompts before giving up. The + argument to this keyword must be an integer. The default is 3. + + PasswordAuthentication + Specifies whether to use password authentication. The argument + to this keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\yesM-bM-^@M-^]. + + PermitLocalCommand + Allow local command execution via the LocalCommand option or + using the !command escape sequence in ssh(1). The argument must + be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. + + PKCS11Provider + Specifies which PKCS#11 provider to use. The argument to this + keyword is the PKCS#11 shared library ssh(1) should use to + communicate with a PKCS#11 token providing the user's private RSA + key. + + Port Specifies the port number to connect on the remote host. The + default is 22. + + PreferredAuthentications + Specifies the order in which the client should try protocol 2 + authentication methods. This allows a client to prefer one + method (e.g. keyboard-interactive) over another method (e.g. + password). The default is: + + gssapi-with-mic,hostbased,publickey, + keyboard-interactive,password + + Protocol + Specifies the protocol versions ssh(1) should support in order of + preference. The possible values are M-bM-^@M-^X1M-bM-^@M-^Y and M-bM-^@M-^X2M-bM-^@M-^Y. Multiple + versions must be comma-separated. When this option is set to + M-bM-^@M-^\2,1M-bM-^@M-^] ssh will try version 2 and fall back to version 1 if + version 2 is not available. The default is M-bM-^@M-^X2M-bM-^@M-^Y. + + ProxyCommand + Specifies the command to use to connect to the server. The + command string extends to the end of the line, and is executed + using the user's shell M-bM-^@M-^XexecM-bM-^@M-^Y directive to avoid a lingering + shell process. + + In the command string, any occurrence of M-bM-^@M-^X%hM-bM-^@M-^Y will be substituted + by the host name to connect, M-bM-^@M-^X%pM-bM-^@M-^Y by the port, and M-bM-^@M-^X%rM-bM-^@M-^Y by the + remote user name. The command can be basically anything, and + should read from its standard input and write to its standard + output. It should eventually connect an sshd(8) server running + on some machine, or execute sshd -i somewhere. Host key + management will be done using the HostName of the host being + connected (defaulting to the name typed by the user). Setting + the command to M-bM-^@M-^\noneM-bM-^@M-^] disables this option entirely. Note that + CheckHostIP is not available for connects with a proxy command. + + This directive is useful in conjunction with nc(1) and its proxy + support. For example, the following directive would connect via + an HTTP proxy at 192.0.2.0: + + ProxyCommand /usr/bin/nc -X connect -x 192.0.2.0:8080 %h %p + + ProxyUseFdpass + Specifies that ProxyCommand will pass a connected file descriptor + back to ssh(1) instead of continuing to execute and pass data. + The default is M-bM-^@M-^\noM-bM-^@M-^]. + + PubkeyAcceptedKeyTypes + Specifies the key types that will be used for public key + authentication as a comma-separated pattern list. Alternately if + the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the key + types after it will be appended to the default instead of + replacing it. The default for this option is: + + ecdsa-sha2-nistp256-cert-v01@openssh.com, + ecdsa-sha2-nistp384-cert-v01@openssh.com, + ecdsa-sha2-nistp521-cert-v01@openssh.com, + ssh-ed25519-cert-v01@openssh.com, + ssh-rsa-cert-v01@openssh.com, + ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, + ssh-ed25519,ssh-rsa + + The -Q option of ssh(1) may be used to list supported key types. + + PubkeyAuthentication + Specifies whether to try public key authentication. The argument + to this keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\yesM-bM-^@M-^]. + This option applies to protocol version 2 only. + + RekeyLimit + Specifies the maximum amount of data that may be transmitted + before the session key is renegotiated, optionally followed a + maximum amount of time that may pass before the session key is + renegotiated. The first argument is specified in bytes and may + have a suffix of M-bM-^@M-^XKM-bM-^@M-^Y, M-bM-^@M-^XMM-bM-^@M-^Y, or M-bM-^@M-^XGM-bM-^@M-^Y to indicate Kilobytes, + Megabytes, or Gigabytes, respectively. The default is between + M-bM-^@M-^X1GM-bM-^@M-^Y and M-bM-^@M-^X4GM-bM-^@M-^Y, depending on the cipher. The optional second + value is specified in seconds and may use any of the units + documented in the TIME FORMATS section of sshd_config(5). The + default value for RekeyLimit is M-bM-^@M-^\default noneM-bM-^@M-^], which means that + rekeying is performed after the cipher's default amount of data + has been sent or received and no time based rekeying is done. + This option applies to protocol version 2 only. + + RemoteForward + Specifies that a TCP port on the remote machine be forwarded over + the secure channel to the specified host and port from the local + machine. The first argument must be [bind_address:]port and the + second argument must be host:hostport. IPv6 addresses can be + specified by enclosing addresses in square brackets. Multiple + forwardings may be specified, and additional forwardings can be + given on the command line. Privileged ports can be forwarded + only when logging in as root on the remote machine. + + If the port argument is M-bM-^@M-^X0M-bM-^@M-^Y, the listen port will be dynamically + allocated on the server and reported to the client at run time. + + If the bind_address is not specified, the default is to only bind + to loopback addresses. If the bind_address is M-bM-^@M-^X*M-bM-^@M-^Y or an empty + string, then the forwarding is requested to listen on all + interfaces. Specifying a remote bind_address will only succeed + if the server's GatewayPorts option is enabled (see + sshd_config(5)). + + RequestTTY + Specifies whether to request a pseudo-tty for the session. The + argument may be one of: M-bM-^@M-^\noM-bM-^@M-^] (never request a TTY), M-bM-^@M-^\yesM-bM-^@M-^] (always + request a TTY when standard input is a TTY), M-bM-^@M-^\forceM-bM-^@M-^] (always + request a TTY) or M-bM-^@M-^\autoM-bM-^@M-^] (request a TTY when opening a login + session). This option mirrors the -t and -T flags for ssh(1). + + RevokedHostKeys + Specifies revoked host public keys. Keys listed in this file + will be refused for host authentication. Note that if this file + does not exist or is not readable, then host authentication will + be refused for all hosts. Keys may be specified as a text file, + listing one public key per line, or as an OpenSSH Key Revocation + List (KRL) as generated by ssh-keygen(1). For more information + on KRLs, see the KEY REVOCATION LISTS section in ssh-keygen(1). + + RhostsRSAAuthentication + Specifies whether to try rhosts based authentication with RSA + host authentication. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The + default is M-bM-^@M-^\noM-bM-^@M-^]. This option applies to protocol version 1 only + and requires ssh(1) to be setuid root. + + RSAAuthentication + Specifies whether to try RSA authentication. The argument to + this keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. RSA authentication will only + be attempted if the identity file exists, or an authentication + agent is running. The default is M-bM-^@M-^\yesM-bM-^@M-^]. Note that this option + applies to protocol version 1 only. + + SendEnv + Specifies what variables from the local environ(7) should be sent + to the server. Note that environment passing is only supported + for protocol 2. The server must also support it, and the server + must be configured to accept these environment variables. Note + that the TERM environment variable is always sent whenever a + pseudo-terminal is requested as it is required by the protocol. + Refer to AcceptEnv in sshd_config(5) for how to configure the + server. Variables are specified by name, which may contain + wildcard characters. Multiple environment variables may be + separated by whitespace or spread across multiple SendEnv + directives. The default is not to send any environment + variables. + + See PATTERNS for more information on patterns. + + ServerAliveCountMax + Sets the number of server alive messages (see below) which may be + sent without ssh(1) receiving any messages back from the server. + If this threshold is reached while server alive messages are + being sent, ssh will disconnect from the server, terminating the + session. It is important to note that the use of server alive + messages is very different from TCPKeepAlive (below). The server + alive messages are sent through the encrypted channel and + therefore will not be spoofable. The TCP keepalive option + enabled by TCPKeepAlive is spoofable. The server alive mechanism + is valuable when the client or server depend on knowing when a + connection has become inactive. + + The default value is 3. If, for example, ServerAliveInterval + (see below) is set to 15 and ServerAliveCountMax is left at the + default, if the server becomes unresponsive, ssh will disconnect + after approximately 45 seconds. This option applies to protocol + version 2 only. + + ServerAliveInterval + Sets a timeout interval in seconds after which if no data has + been received from the server, ssh(1) will send a message through + the encrypted channel to request a response from the server. The + default is 0, indicating that these messages will not be sent to + the server. This option applies to protocol version 2 only. + + StreamLocalBindMask + Sets the octal file creation mode mask (umask) used when creating + a Unix-domain socket file for local or remote port forwarding. + This option is only used for port forwarding to a Unix-domain + socket file. + + The default value is 0177, which creates a Unix-domain socket + file that is readable and writable only by the owner. Note that + not all operating systems honor the file mode on Unix-domain + socket files. + + StreamLocalBindUnlink + Specifies whether to remove an existing Unix-domain socket file + for local or remote port forwarding before creating a new one. + If the socket file already exists and StreamLocalBindUnlink is + not enabled, ssh will be unable to forward the port to the Unix- + domain socket file. This option is only used for port forwarding + to a Unix-domain socket file. + + The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. + + StrictHostKeyChecking + If this flag is set to M-bM-^@M-^\yesM-bM-^@M-^], ssh(1) will never automatically add + host keys to the ~/.ssh/known_hosts file, and refuses to connect + to hosts whose host key has changed. This provides maximum + protection against trojan horse attacks, though it can be + annoying when the /etc/ssh/ssh_known_hosts file is poorly + maintained or when connections to new hosts are frequently made. + This option forces the user to manually add all new hosts. If + this flag is set to M-bM-^@M-^\noM-bM-^@M-^], ssh will automatically add new host + keys to the user known hosts files. If this flag is set to + M-bM-^@M-^\askM-bM-^@M-^], new host keys will be added to the user known host files + only after the user has confirmed that is what they really want + to do, and ssh will refuse to connect to hosts whose host key has + changed. The host keys of known hosts will be verified + automatically in all cases. The argument must be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\noM-bM-^@M-^], or + M-bM-^@M-^\askM-bM-^@M-^]. The default is M-bM-^@M-^\askM-bM-^@M-^]. + + TCPKeepAlive + Specifies whether the system should send TCP keepalive messages + to the other side. If they are sent, death of the connection or + crash of one of the machines will be properly noticed. However, + this means that connections will die if the route is down + temporarily, and some people find it annoying. + + The default is M-bM-^@M-^\yesM-bM-^@M-^] (to send TCP keepalive messages), and the + client will notice if the network goes down or the remote host + dies. This is important in scripts, and many users want it too. + + To disable TCP keepalive messages, the value should be set to + M-bM-^@M-^\noM-bM-^@M-^]. + + Tunnel Request tun(4) device forwarding between the client and the + server. The argument must be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\point-to-pointM-bM-^@M-^] (layer 3), + M-bM-^@M-^\ethernetM-bM-^@M-^] (layer 2), or M-bM-^@M-^\noM-bM-^@M-^]. Specifying M-bM-^@M-^\yesM-bM-^@M-^] requests the + default tunnel mode, which is M-bM-^@M-^\point-to-pointM-bM-^@M-^]. The default is + M-bM-^@M-^\noM-bM-^@M-^]. + + TunnelDevice + Specifies the tun(4) devices to open on the client (local_tun) + and the server (remote_tun). + + The argument must be local_tun[:remote_tun]. The devices may be + specified by numerical ID or the keyword M-bM-^@M-^\anyM-bM-^@M-^], which uses the + next available tunnel device. If remote_tun is not specified, it + defaults to M-bM-^@M-^\anyM-bM-^@M-^]. The default is M-bM-^@M-^\any:anyM-bM-^@M-^]. + + UpdateHostKeys + Specifies whether ssh(1) should accept notifications of + additional hostkeys from the server sent after authentication has + completed and add them to UserKnownHostsFile. The argument must + be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\noM-bM-^@M-^] (the default) or M-bM-^@M-^\askM-bM-^@M-^]. Enabling this option + allows learning alternate hostkeys for a server and supports + graceful key rotation by allowing a server to send replacement + public keys before old ones are removed. Additional hostkeys are + only accepted if the key used to authenticate the host was + already trusted or explicity accepted by the user. If + UpdateHostKeys is set to M-bM-^@M-^\askM-bM-^@M-^], then the user is asked to confirm + the modifications to the known_hosts file. Confirmation is + currently incompatible with ControlPersist, and will be disabled + if it is enabled. + + Presently, only sshd(8) from OpenSSH 6.8 and greater support the + M-bM-^@M-^\hostkeys@openssh.comM-bM-^@M-^] protocol extension used to inform the + client of all the server's hostkeys. + + UsePrivilegedPort + Specifies whether to use a privileged port for outgoing + connections. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is + M-bM-^@M-^\noM-bM-^@M-^]. If set to M-bM-^@M-^\yesM-bM-^@M-^], ssh(1) must be setuid root. Note that + this option must be set to M-bM-^@M-^\yesM-bM-^@M-^] for RhostsRSAAuthentication with + older servers. + + User Specifies the user to log in as. This can be useful when a + different user name is used on different machines. This saves + the trouble of having to remember to give the user name on the + command line. + + UserKnownHostsFile + Specifies one or more files to use for the user host key + database, separated by whitespace. The default is + ~/.ssh/known_hosts, ~/.ssh/known_hosts2. + + VerifyHostKeyDNS + Specifies whether to verify the remote key using DNS and SSHFP + resource records. If this option is set to M-bM-^@M-^\yesM-bM-^@M-^], the client + will implicitly trust keys that match a secure fingerprint from + DNS. Insecure fingerprints will be handled as if this option was + set to M-bM-^@M-^\askM-bM-^@M-^]. If this option is set to M-bM-^@M-^\askM-bM-^@M-^], information on + fingerprint match will be displayed, but the user will still need + to confirm new host keys according to the StrictHostKeyChecking + option. The argument must be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\noM-bM-^@M-^], or M-bM-^@M-^\askM-bM-^@M-^]. The default + is M-bM-^@M-^\noM-bM-^@M-^]. Note that this option applies to protocol version 2 + only. + + See also VERIFYING HOST KEYS in ssh(1). + + VisualHostKey + If this flag is set to M-bM-^@M-^\yesM-bM-^@M-^], an ASCII art representation of the + remote host key fingerprint is printed in addition to the + fingerprint string at login and for unknown host keys. If this + flag is set to M-bM-^@M-^\noM-bM-^@M-^], no fingerprint strings are printed at login + and only the fingerprint string will be printed for unknown host + keys. The default is M-bM-^@M-^\noM-bM-^@M-^]. + + XAuthLocation + Specifies the full pathname of the xauth(1) program. The default + is /usr/X11R6/bin/xauth. + +PATTERNS + A pattern consists of zero or more non-whitespace characters, M-bM-^@M-^X*M-bM-^@M-^Y (a + wildcard that matches zero or more characters), or M-bM-^@M-^X?M-bM-^@M-^Y (a wildcard that + matches exactly one character). For example, to specify a set of + declarations for any host in the M-bM-^@M-^\.co.ukM-bM-^@M-^] set of domains, the following + pattern could be used: + + Host *.co.uk + + The following pattern would match any host in the 192.168.0.[0-9] network + range: + + Host 192.168.0.? + + A pattern-list is a comma-separated list of patterns. Patterns within + pattern-lists may be negated by preceding them with an exclamation mark + (M-bM-^@M-^X!M-bM-^@M-^Y). For example, to allow a key to be used from anywhere within an + organization except from the M-bM-^@M-^\dialupM-bM-^@M-^] pool, the following entry (in + authorized_keys) could be used: + + from="!*.dialup.example.com,*.example.com" + +FILES + ~/.ssh/config + This is the per-user configuration file. The format of this file + is described above. This file is used by the SSH client. + Because of the potential for abuse, this file must have strict + permissions: read/write for the user, and not accessible by + others. + + /etc/ssh/ssh_config + Systemwide configuration file. This file provides defaults for + those values that are not specified in the user's configuration + file, and for those users who do not have a configuration file. + This file must be world-readable. + +SEE ALSO + ssh(1) + +AUTHORS + OpenSSH is a derivative of the original and free ssh 1.2.12 release by + Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo + de Raadt and Dug Song removed many bugs, re-added newer features and + created OpenSSH. Markus Friedl contributed the support for SSH protocol + versions 1.5 and 2.0. + +OpenBSD 5.8 August 14, 2015 OpenBSD 5.8 diff --git a/crypto/external/bsd/openssh/dist/strtonum.c b/crypto/external/bsd/openssh/dist/strtonum.c new file mode 120000 index 000000000..240446e7b --- /dev/null +++ b/crypto/external/bsd/openssh/dist/strtonum.c @@ -0,0 +1 @@ +openbsd-compat/strtonum.c \ No newline at end of file diff --git a/crypto/external/bsd/openssh/dist/timingsafe_bcmp.c b/crypto/external/bsd/openssh/dist/timingsafe_bcmp.c new file mode 120000 index 000000000..166489b19 --- /dev/null +++ b/crypto/external/bsd/openssh/dist/timingsafe_bcmp.c @@ -0,0 +1 @@ +openbsd-compat/timingsafe_bcmp.c \ No newline at end of file diff --git a/crypto/external/bsd/openssh/dist/xcrypt.c b/crypto/external/bsd/openssh/dist/xcrypt.c new file mode 120000 index 000000000..3e329834e --- /dev/null +++ b/crypto/external/bsd/openssh/dist/xcrypt.c @@ -0,0 +1 @@ +openbsd-compat/xcrypt.c \ No newline at end of file diff --git a/crypto/external/bsd/openssh/dist/xmmap.c b/crypto/external/bsd/openssh/dist/xmmap.c new file mode 120000 index 000000000..4fbd1b64e --- /dev/null +++ b/crypto/external/bsd/openssh/dist/xmmap.c @@ -0,0 +1 @@ +openbsd-compat/xmmap.c \ No newline at end of file